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

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

Самое первое, что приходит в голову: заложить новые поля заранее в форме и поставить им 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;

Подписывайтесь на наши группы в социальных сетях

Комментарии (7)

Данияр 2020-07-07 14:07:29
Спасибо автору
Bidbi Sergey 2013-01-07 17:36:59
@Гость:
А можете подсказать, как ето сделать без .js, т.е. по-человечески?
Нельзя по-другому, только с js.
А как бы это все сделать еще с многомерным массивом (не одно поле за раз, а два в строку - код города и телефон) и несколько типов полей в форме на одной странице?
Гость 2012-09-30 23:33:17
А можете подсказать, как ето сделать без .js, т.е. по-человечески?
Андрей 2012-02-08 12:43:37
Скрипт рабочий, автору спсибо!

Не помешало бы передавать скрытое поле со значением счетчика, тогда и ограничивать 5 не нужно, и обрабатывать приятнее.
Александр 2011-11-22 10:32:11
В базу добавляются только то что в первом инпуте, с других инпутов не заносится. Как сделать?
Гость 2011-01-10 18:41:45
Отличный урок. +10! Спасибо
Доктор Пилюлькин > Гость 2019-09-20 17:17:27
Гость
А можете подсказать, как ето сделать без .js, т.е. по-человечески?
заказать у программиста :)))
Меню