Архив за Июнь 2008

Удаление и выборка нескольких записей

В web-программировании, особенно при создании различных панелей администрирования, часто встает задача множественного выбора или удаления сразу нескольких записей из базы данных. Пусть имеется таблица items, содержащая два поля: первичный ключ таблицы id и текстовое поле title.

Для удаления записей обычно создается HTML-форма с набором флажков:

<input type="checkbox" name="item[]" value="5" /><br/>
<input type="checkbox" name="item[]" value="7" /><br/>
<input type="checkbox" name="item[]" value="12" /><br/>
<input type="checkbox" name="item[]" value="25" /><br/>
<input type="checkbox" name="item[]" value="32" /><br/>

Скрипт, формирующий список элементов input формы, и удаляющий выбранные записи может выглядеть так:

<?php
echo '<h2>Список</h2>';
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
$query = "SELECT id, title FROM items WHERE 1";
$res = mysql_query( $query );
echo '<table border="1">';;
echo '<tr><th>ID</th><th>Наименование</th><th>Удл.</th></tr>';
while ( $item = mysql_fetch_array( $res ) )
{
  echo '<tr>';
  echo '<td>'.$item['id'].'</td>';
  echo '<td>'.$item['title'].'</td>';
  echo '<td><input type="checkbox" name="item[]" value="'.$item['id'].'" /></td>'
  echo '</tr>';
}
echo '</table>';
echo '<input type="submit" name="submitForm" value="Удалить отмеченные" />';
echo '</form>';

if ( isset ( $_POST['item'] ) )
{
  $ids = implode( ',', $_POST['item'] );
  $query = 'DELETE FROM items WHERE id IN ('.$ids.')';
  mysql_query( $query );
  header( 'Location: '.$_SERVER['PHP_SELF'] );
}
?>

Массив $_POST['item'] содержит ID всех отмеченных checkbox-ов (не отмеченные на сервер не передаются). Запрос к БД на удаление выглядит так

DELETE FROM items WHERE id IN (6,9,11,12);

Если стоит задача не удаления записей, а их выборки, то вместо оператора DELETE следует использовать оператор SELECT.

Доступ к элементам формы

Как правило, доступ к элементу HTML осуществляется по его идентификатору с помощью метода document.getElementById(). Но для доступа к HTML-формам чаще всего используется свойство document.forms. Свойство document.forms представляет собой массив всех форм на текущей странице. Поэтому если на странице находится лишь одна форма, то она доступна с помощью первого элемента массива document.forms[0]. С другой стороны, форме можно присвоить имя:

<form name="mainForm">
...
</form>

Тогда она доступна с помощью элемента массива document.forms["mainForm"].

Обращение ко всем элементам формы также осуществляется по имени, которое служит в качестве индекса массива в свойстве elements формы. Допустим, например, что у первой формы на странице имеется элемент с атрибутом name=”element1″. Тогда доступ к этому элементу осуществляется с помощью следующего кода JavaScript:

document.forms[0].elements["element1"]

Имеется и более краткая форма доступа к информации формы. Например, сокращенная форма доступа к элементу “element1″ формы “mainForm” выглядит так:

document.mainForm.element1

Каждый элемент формы поддерживает свойство form, указывающее на ту форму, в которой находится данный элемент. Поэтому выражение this.form часто используется в коде для упрощения доступа к форме на уровне элементов полей данной формы, не прибегая к массиву document.forms.

Доступ к текстовым полям

window.alert(f.elements["textfield"].value);

В HTML поддерживаются три вида текстовых полей.

  • Однострочные текстовые поля: <input type=”text” />
  • Многострочные текстовые поля: <textarea>…</textarea>
  • Поля ввода паролей: <input type=”password” />

Несмотря на то что эти поля действуют по-разному в браузере, доступ к ним в JavaScript осуществляется практически одинаково. Атрибут value каждого из этих полей содержит текст внутри поля. Его можно использовать как для чтения, так и для записи текста в поле.

В приведенном ниже фрагменте кода демонстрируется два следующих приема: доступ к свойству поля и применение выражения this.form для упрощенного доступа к форме данного поля.

<script type="text/javascript">
function showText(f) {
  window.alert(f.elements["textfield"].value);
}
</script>
<form>
  <input type="text" name="textfield" />
  <input type="button" value="Show text" onclick="showText(this.form);" />
</form>

Доступ к флажкам

f.elements["chkbox"].checked ? "checked." : "not checked."

Флажок в HTML-форме может находиться в двух состояниях: установленном и сброшенном. Поэтому обращение к флажку их кода JavaScript чаще всего осуществляется для определения его состояния.

Свойство checked флажка возвращает логическое значение true, если флажок установлен, а в противном случае — логическое значение false.

<script type="text/javascript">
function showStatus(f) {
  window.alert("The checkbox is " +
    (f.elements["chkbox"].checked ? "checked." : "not checked."));
}
</script>
<form>
  <input type="checkbox" name="chkbox" />
  <input type="button" value="Show status" onclick="showStatus(this.form);" />
</form>

Продолжение следует…

Как работают в IT

Любой русский программист после пары минут чтения кода, обязательно вскочит и произнесет, обращаясь к себе: “переписать это все нафиг”. Потом в нем шевельнется сомнение в том, сколько времени это займет, и остаток дня русский программист потратит на то, что будет доказывать самому себе, что это только кажется, что переписать — это много работы. А если взяться и посидеть немного, то все получится. Зато код будет красивый и правильный. Hа следующее утро русский программист свеж, доволен собой и без единой запинки докладывает начальству, что переписать этот кусок займет один день, не больше. Да, не больше. Hу, в крайнем случае, два, если учесть все риски. В итоге начальство даст ему неделю и через полгода процесс будет успешно завершен. До той поры, пока этот код не увидит другой русский программист.

А в это время, в соседних четырех кубиках, будет ни на секунду не утихать работа китайских программистов, непостижимым образом умудряющихся прийти раньше русского программиста, уйти позже, и при этом сделать примерно втрое меньше. Эта четверка, давно не пишет никакого кода, а только поддерживает код, написанный в свое время индусом, и дважды переписанный двумя разными русскими. В этом коде не просто живут баги. Здесь их гнездо. Это гнездо постоянно воспроизводит себя при помощи любимой китайской технологии реиспользования кода — copy/paste. Отсюда баги расползаются в разные стороны посредством статических переменных и переменных, переданных по ссылке (поскольку, китайский программист не может смириться с неудобствами, вызванными тем, что он не может изменить значение внешней переменной переданной в его функцию модулями, которые переписывает русский программист). Вспоминая об этой функции, русский программист, как правило, на время теряет дар английской речи и переходит к какой-то помеси русского и китайского. Он давно мечтает переписать весь кусок, над которым работают китайцы, но у него нет времени.

Hа китайцах висят серьезные баги, о которых знает начальство и постоянно их торопит. Китайцы торопливо перевешивают баги друг на друга, поскольку знают, что попытки их починить приведут к появлению новых, еще худших. И в этом они правы. Разобраться в том, в каком порядке меняются статические переменные, и как приобретают свои значения, способен только один человек на фирме — индус. Hо он пребывает в медитации.

Поэтому, когда всю четверку уволят во время сокращения… А кого еще увольнять? Русский — еще не переписал свой кусок, а индус — главная ценность фирмы — он редко обращает внимание на проект, но когда обращает, все понимают, что так как он, архитектуру никто не знает. Так вот, когда китайцев увольняют, у их кода возможны две основные судьбы. Первая — он попадет к русским и его перепишут. Вторая — он попадет к местному, канадскому программисту.

О, канадский программист это особый тип. Он, ни на минуту не задумываясь, как рыцарь без страха и упрека, бросится фиксить самый свирепый баг китайского кода. Этот Баг живет там уже три года, и китайцы уже четырежды (каждый по разу) сообщали начальству, что он пофиксен. Hо Баг каждый раз возвращался, как Бетмен в свой Готхем.

Итак, канадский программист сделает то, чего китайцы не рисковали делать в течение трех долгих лет. Он, при помощи дебагера, отследит место, где статическая переменная приняла значение -1 вместо правильного 0, и решительным движением заведет рядом вторую переменную с правильным значением. Баг погибнет в неравной схватке с канадским программистом. Hо победа будет достигнута тяжелой ценой. Работать перестанет все, включая только что переписанный русским программистом код. Это повергнет русского программиста в задумчивость на целых два дня, после чего он сделает, в общем-то, предсказуемый вывод о том, что дизайн с самого начала был неправильным, и все надо переписать. Hа это нам нужна неделя. Да, неделя, не больше.

Канадский программист смело бросится налаживать все, и станет еще хуже, хотя казалось бы… Эта суета выведет из медитации индуса, который придумает и вовсе гениальное решение — отбранчить код. Согласно его плану, мы теперь будем поддерживать две версии одного и того же кода — одну работающую, но с Багом, другую без Бага, но не работающую. Русский программист, услышав об этом плане, сломает линейку об стол и дома обзовет жену дурой, но на совещании возразить не решится.

К счастью, все это не сильно влияет на дела фирмы, поскольку продукт продается и так. Поэтому менеджеры ходят в целом довольные, и не устают напоминать всем, что они отобраны как лучшие среди лучших. И что мы давно доказали свою способность выпускать продукт тем, что выпускаем его иногда.