JQuery plugin для форм с динамической структурой

Доброго времени суток, уважаемые читатели. В некоторых ситуациях требуется через форму на сайте добавить несколько идентичных данных, например, заполнить таблицу в базе данных фамилиями сотрудников фирмы, это не суть. Добавлять через одно поле и каждый раз отправлять данные на сервер согласитесь довольно скучное занятие. Поэтому в данном уроке мы будем учиться размножать поля формы и делать их столько, сколько нам нужно, а в этом нам поможет jQuery. Взгляните на пример и сразу поймете, о чем я.

Поскольку делать это мы будем при помощи jQuery, то нужно подключить данную библиотеку.

Теперь создадим саму форму с кнопкой добавления нового поля и кнопкой отправки данных:






Название





Как вы заметили для кнопки Добавить поле мы написали параметр onclick="return add_new_image();". Это означает что при нажатии на нее у нас должна выполняться функция, которая и будет добавлять дополнительные поля. Данная функция на JavaScript будет выглядеть так:


var total = 0 ;
function add_new_image() {
total++;
$ ("")
.attr ("id" ,"tr_image_" +total )
.css ({lineHeight:"20px" })
.append (
$("" )
.attr ("id" ,"td_title_" +total )

.append (
$("" )
.css ({width:"200px" })
.attr ("id" ,"input_title_" +total )
.attr ("name" ,"input_title_" +total )
)

)
.append (
$("" )
.css ({width:"60px" })
.append (
$("" )
)
.appendTo ("#table_container" );
}
$(document).ready (function () {
add_new_image() ;
});

Давайте разберем, что здесь происходит. Поскольку при добавлении нового поля нам нужно чтобы имена у них были разные, чтобы иметь возможность обработать их на сервере. Для этого создана переменная total, которая будет при клике увеличиваться на 1 и добавляться к имени поля input. Затем мы в таблицу, находящуюся в форме мы добавляем новую строку и применяем к нему атрибут id="tr_image_"+total и стиль lineHeight:"20px"

После этого мы добавляем первый столбец , к которому так же применяем атрибут id="td_title_"+total и стиль paddingRight:"5px",width:"200px"

В этот столбец мы добавляем поле input и снова применяем атрибуты id и name, а также стили

Следующим действием мы добавляем второй столбец, в котором у нас будет кнопка для удаления поля. Данный код уже должен работать и добавлять поля.

Теперь нужно разобраться, как обрабатывать все эти данные. В форме у нас прописан обработчик add.php его и будем редактировать. При добавлении нового поля, как мы знаем, у нас возникают новые переменные input_title_1, input_title_2 и т.д. Казалось бы все просто, мы просто сосчитаем сколько элементов в массиве $_POST и используя цикл переберем все значения.

$n = count ($_POST );
for ($i =1 ; $i input_title_1
$key => input_title_2
$key => input_title_4

Теперь, зная все значения ключей, мы можем их перебрать при помощи цикла в исходном массиве, тем самым не «упустив» переменные. В данном примере просто выводятся все значения, но с ними вы можете делать все что угодно. Чтобы сделать два поля то в JavaScript нужно добавить вот такой код сразу после того как мы закончили с добавлением первого столбца:

Append (
$("" )
.attr ("id" ,"td_ name_" +total )
.css ({paddingRight:"5px" ,width:"200px" })
.append (
$("" )
.css ({width:"200px" })
.attr ("id" ,"name_" +total )
.attr ("name" ,"name_" +total )
)

Только не забывайте менять параметры id и name, иначе у вас получится несколько полей с одинаковым именем.

1. Контактная форма, в которой есть поле «телефон». Пользователь может добавить еще несколько дополнительных полей для телефонов, если возникнет желание.

2. Счет на оплату. Есть фиксированный набор полей, таких как «имя плательщика» и «номер счета». Кроме того, есть таблица с позициями. Каждая позиция состоит следующих полей: «наименование», «количество», «цена». Пользователь может добавлять произвольное количество дополнительных позиций.

Давайте рассмотрим работу с jqDynaForm на примере такого счета. Вот пример такой формы:

Давайте посмотрим на HTML код, который необходимо приготовить для плагина:

Simple form demo Invoice

Number: Payer:

Products Price: X

Выкину все лишнее, чтобы стало нагляднее:

… Фиксированные поля формы… … Поля отдельного пункта счета …

Т.е. у нас есть некая базовая форма с фиксированным набором полей. Внутри этой формы мы размещаем холдер, DIV помеченный атрибутом «data-holder-for». Значение атрибута задает имя блока, который сюда можно вставлять. HTML код этого блока задается отдельно от формы и помечается атрибутом data-name.

Кнопки добавление, удаления пунктов, поведение drag-and-drop для сортировки и переноса полностью формируется плагином.

API Чтобы получить значения полей формы надо сделать следующий вызов

Var json = $().jqDynaForm("get");

И он вернет JSON объект следующей структуры:

{ "number": "123", "payer": "Fake Incorporated", "productArray": [ { "title": "HP Pavilion g7-2010nr 17.3-Inch", "price": "499.99", "amount": "3" }, { "title": "Samsung Galaxy Tab 2 (7-Inch, Wi-Fi)", "price": "248.00", "amount": "1" }, { "title": "HP Envy 4-1030us 14-Inch Ultrabook", "price": "779.99", "amount": "1" } ] }

Обратите внимание, что повторяющиеся вложенные блоки автоматически размещаются в массивах. Значения ключей в полях, это атрибут name в тегах INPUT и SELECT.

Если у вас есть уже такой готовый JSON объект (сформированный скриптом, или считанный из базы данных), то вы можете при помощи одного вызова воссоздать форму.

$().jqDynaForm("set", json);

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

Пример посложнее На самом деле, структура формы может быть гораздо сложней, потому что вы можете размещать холдеры не только в базовой форме, но и внутри динамических блоков. Холдер даже может ссылаться на самого себя, формирую древовидную рекурсивную структуру. Вот пример более сложной формы:

Фичи Перечислю наиболее важные фичи:
  • Произвольный HTML код формы без особых ограничений
  • Строгое задание структуры иерархии вложения блоков
  • Создание вложенности в несколько уровней
  • Создание рекурсивных структур
  • Действия над структурой при заполнении формы: Добавление блока, удаление блока, сортировка и перенос (drag-and-drop) блока в другое разрешенное место.
  • Превращение формы любой структуры в JSON объект
  • Воссоздание формы из JSON объекта
  • Создание формы без необходимости программирования. Настройка задается специальными атрибутами

Также планирую добавить следующее возможности:

  • Упрощенный механизм валидации полей по регулярным выражениям
  • Внешние обработчики событий
Работа с JSON Как работать с полученной JSON структурой. Можно обрабатывать на JavaScript-е, можно отправить на сервер и превратить, например в php-array древовидную структуру.

Обычно значения полей хранят в базах данных. С классическими «плоскими» формами все понятно. Такая форма замечательно ложиться в одну запись таблицы реляционной базы данных. А тут форма древовидная, и структура данных соответственно тоже древовидная. Вариантов хранения много, вот некоторые:

  • Использование MongoDB (Самый красивый вариант)
  • Хранения JSON объекта в виде текста в обычной реляционной БД. Но это не всегда приемлемо, если необходимо выполнять запросы к отдельным поля формы. Поэтому рассмотрим следующий, компромиссный вариант
  • Хранения полей верхнего уровня в полях реляционной БД, а всех полей вложенных блоков в виде текстового представления JSON объектов в дополнительных полях той же записи реляционной БД.
  • Самый занудный вариант, это завести для каждого вида блока полей отдельную таблицу в реляционной БД и заполнять эти таблицы «вручную», оббегая JSON объект.
Что меня побудило к созданию этого плагина Я много занимаюсь разработкой разного рода веб-приложений. Многие приложения содержат большое количество форм. Создание обработчиков форм часто отнимают много времени. Есть разного рода решения, которые упрощают создание обычных, плоских форм. Но когда требуются динамические формы, то тут стандартные решения, как правило, уже мало помогают.

Вот типичный ход работы над проекта в стиле «ночной кошмар». От Заказчика с некоторым периодом поступают следующие требования:

  • Сделайте форму для хранения данных о компании. Там надо только поля «название», «город», «улица», «дом».
  • Ой! Оказывается у компании может быть много филиалов. Сделайте, чтобы можно было в форме задать адрес каждого филиала по отдельности.
  • Мы тут подумали, нам бы еще надо, чтобы у каждой компании в форме можно было записать несколько проектов, которые она выполняла.
  • Добавьте, пожалуйста, контактное лицо к каждому филиалу. А… Добавили? А как к каждому телефону указать имя человека? … Нам надо чтобы можно было задать много контактных лиц в каждом филиале и каждому указать отдельный телефон.

Дабы избежать кошмара постоянного программирования всех этих кнопочек – «добавить», «удалить», «перенести», не мучаться с формированием динамических структур, удобно обрабатывать значения полей, я и задумался на созданием этого плагина.

Исходники Заранее предупреждаю, что плагин еще сырой. Но если у общества будет интерес, то я планирую его дорабатывать и выкладывать следующие версии.

Страничка проекта находится на

Существует множество способов и технологий позволяющих реализовать динамическое добавление полей на странице (без перезагрузки). Т.е. пользователь просто жмет кнопку «добавить поле» и новое поле для ввода каких либо данных добавляется к форме.

В некоторых ситуациях требуется через форму на сайте добавить несколько идентичных данных, например, заполнить таблицу в базе данных фамилиями сотрудников фирмы, это не суть. Добавлять через одно поле и каждый раз отправлять данные на сервер согласитесь довольно скучное занятие. Поэтому в данном уроке мы будем учиться размножать поля формы и делать их столько, сколько нам нужно, а в этом нам поможет jQuery.

Поскольку делать это мы будем при помощи jQuery, то нужно подключить данную библиотеку.

Теперь создадим саму форму с кнопкой добавления нового поля и кнопкой отправки данных:

Название

Как вы заметили для кнопки Добавить поле мы написали параметр onclick=»return add_new_image();». Это означает что при нажатии на нее у нас должна выполняться функция, которая и будет добавлять дополнительные поля. Данная функция на JavaScript будет выглядеть так:

var total = 0; function add_new_image(){ total++; $("") .attr("id","tr_image_"+total) .css({lineHeight:"20px"}) .append ($("") .attr("id","td_title_"+total) .css({paddingRight:"5px",width:"200px"}) .append($("") .css({width:"200px"}) .attr("id","input_title_"+total) .attr("name","input_title_"+total))) .append($("") .css({width:"60px"}) .append($(""))) .appendTo("#table_container"); } $(document).ready(function() { add_new_image(); });

Давайте разберем, что здесь происходит. Поскольку при добавлении нового поля нам нужно чтобы имена у них были разные, чтобы иметь возможность обработать их на сервере. Для этого создана переменная total, которая будет при клике увеличиваться на 1 и добавляться к имени поля input. Затем мы в таблицу, находящуюся в форме мы добавляем новую строку и применяем к нему атрибут id=’tr_image_’+total и стиль lineHeight:’20px’

После этого мы добавляем первый столбец , к которому так же применяем атрибут id=’td_title_’+total и стиль paddingRight:’5px’,width:’200px’

В этот столбец мы добавляем поле input и снова применяем атрибуты id и name, а также стили

Следующим действием мы добавляем второй столбец, в котором у нас будет кнопка для удаления поля. Данный код уже должен работать и добавлять поля.

Теперь нужно разобраться, как обрабатывать все эти данные. В форме у нас прописан обработчик add.php его и будем редактировать. При добавлении нового поля, как мы знаем, у нас возникают новые переменные input_title_1, input_title_2 и т.д. Казалось бы все просто, мы просто сосчитаем сколько элементов в массиве $_POST и используя цикл переберем все значения.

$n = count($_POST); for($i=1; $i input_title_1
$key => input_title_2
$key => input_title_4

Теперь, зная все значения ключей, мы можем их перебрать при помощи цикла в исходном массиве, тем самым не «упустив» переменные. В данном примере просто выводятся все значения, но с ними вы можете делать все что угодно. Чтобы сделать два поля то в JavaScript нужно добавить вот такой код сразу после того как мы закончили с добавлением первого столбца:

Append($("") .attr("id","td_ name_"+total) .css({paddingRight:"5px",width:"200px"}) .append($("") .css({width:"200px"}) .attr("id","name_"+total) .attr("name","name_"+total)))

Только не забывайте менять параметры id и name, иначе у вас получится несколько полей с одинаковым именем.

Демо Скачать