Добавление полей в форму

Задача: реализовать функционал "еще одно поле" для формы с ограничением числа полей и возможностью удаления.

Самое первое, что приходит в голову: заложить новые поля заранее в форме и поставить им style="display:block". Далее с помощью простенького скрипта, меняющего значение display, показывать/скрывать эти поля. Однако, этот способ не очень удобен, т.к. в случае 20 и более полей будет передаваться большое количество HTML-кода, и для исправления придется копаться в скриптах на сервере.

Более удобно и правильно генерировать новые поля формы "на лету" JavaScript-ом и вставлять в DOM-дерево.

К сожалению, скрипты для добавления полей зависимы от верстки формы, поэтому панацеи не будет. Ниже приведен код формы, которую мы попытаемся "размножить", используя JavaScript-функции.

<form method="GET" action="#">
<
div id="parentId">
<
div>
<
input name="name_1" type="text" />
<
a onclick="return deleteField(this)" href="#">[X]</a>
</
div>
</
div>
<
input class="s" type="submit" value="GO!" />
</
form>
<
a onclick="return addField()" href="#">Добавить поле</a>

Суть скрипта в том, чтобы добавлять методом appendChild сгенерированные "на лету" ДИВы к родительскому ДИВу (id="parentId"). Возникает резонный вопрос: "А не проще ли воспользоваться свойством innerHTML того же родительского ДИВа и используя оператор += прибавлять к нему код новых полей?". Ответ - "Нет!". Это связано с тем, что в некоторых браузерах при таком способе наблюдается сбой в работе формы, например:
- форма может терять значения, введенные ранее;
- форма может потерять введенные данные при сабмите;
Поэтому, при добаление полей следует аккуратно перестраивать DOM-ветку формы, оперируя только методами appendChild (или insertBefore) и removeChild.

var countOfFields = 1; // Текущее число полей
var curFieldNameId = 1; // Уникальное значение для атрибута name
var maxFieldLimit = 5; // Максимальное число возможных полей
function deleteField(a) {
// Получаем доступ к ДИВу, содержащему поле
var contDiv = a.parentNode;
// Удаляем этот ДИВ из DOM-дерева
contDiv.parentNode.removeChild(contDiv);
// Уменьшаем значение текущего числа полей
countOfFields--;
// Возвращаем false, чтобы не было перехода по сслыке
return false;
}
function
addField() {
// Проверяем, не достигло ли число полей максимума
if (countOfFields >= maxFieldLimit) {
alert("Число полей достигло своего максимума = " + maxFieldLimit);
return
false;
}
// Увеличиваем текущее значение числа полей
countOfFields++;
// Увеличиваем ID
curFieldNameId++;
// Создаем элемент ДИВ
var div = document.createElement("div");
// Добавляем HTML-контент с пом. свойства innerHTML
div.innerHTML = "<input name=\"name_" + curFieldNameId + "\" type=\"text\" /> <a onclick=\"return deleteField(this)\" href=\"#\">[X]</a>";
// Добавляем новый узел в конец списка полей
document.getElementById("parentId").appendChild(div);
// Возвращаем false, чтобы не было перехода по сслыке
return false;
}

Замечание


Приведенный пример лишь показывает, как следует добавлять поля к форме, сам же код можно (и нужно) дополнять и совершенствовать под свои нужды, избавляясь от глобальных переменных и улучшая функционал.
Проверено в:
- IE 6;
- Opera 9.1;
- FF 1.5;

Автор: Александр Бурцев