Существует множество способов и технологий позволяющих реализовать динамическое добавление полей на странице (без перезагрузки). Т.е. пользователь просто жмет кнопку «добавить поле» и новое поле для ввода каких либо данных добавляется к форме.
В некоторых ситуациях требуется через форму на сайте добавить несколько идентичных данных, например, заполнить таблицу в базе данных фамилиями сотрудников фирмы, это не суть. Добавлять через одно поле и каждый раз отправлять данные на сервер согласитесь довольно скучное занятие. Поэтому в данном уроке мы будем учиться размножать поля формы и делать их столько, сколько нам нужно, а в этом нам поможет jQuery.
Поскольку делать это мы будем при помощи jQuery, то нужно подключить данную библиотеку.
Теперь создадим саму форму с кнопкой добавления нового поля и кнопкой отправки данных:
Название |
Как вы заметили для кнопки Добавить поле мы написали параметр onclick=»return add_new_image();». Это означает что при нажатии на нее у нас должна выполняться функция, которая и будет добавлять дополнительные поля. Данная функция на JavaScript будет выглядеть так:
var total = 0; function add_new_image(){ total++; $("
Давайте разберем, что здесь происходит. Поскольку при добавлении нового поля нам нужно чтобы имена у них были разные, чтобы иметь возможность обработать их на сервере. Для этого создана переменная total, которая будет при клике увеличиваться на 1 и добавляться к имени поля input. Затем мы в таблицу, находящуюся в форме мы добавляем новую строку
После этого мы добавляем первый столбец
В этот столбец мы добавляем поле 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($("
Только не забывайте менять параметры 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 объекта
- Создание формы без необходимости программирования. Настройка задается специальными атрибутами
Также планирую добавить следующее возможности:
- Упрощенный механизм валидации полей по регулярным выражениям
- Внешние обработчики событий
Обычно значения полей хранят в базах данных. С классическими «плоскими» формами все понятно. Такая форма замечательно ложиться в одну запись таблицы реляционной базы данных. А тут форма древовидная, и структура данных соответственно тоже древовидная. Вариантов хранения много, вот некоторые:
- Использование MongoDB (Самый красивый вариант)
- Хранения JSON объекта в виде текста в обычной реляционной БД. Но это не всегда приемлемо, если необходимо выполнять запросы к отдельным поля формы. Поэтому рассмотрим следующий, компромиссный вариант
- Хранения полей верхнего уровня в полях реляционной БД, а всех полей вложенных блоков в виде текстового представления JSON объектов в дополнительных полях той же записи реляционной БД.
- Самый занудный вариант, это завести для каждого вида блока полей отдельную таблицу в реляционной БД и заполнять эти таблицы «вручную», оббегая JSON объект.
Вот типичный ход работы над проекта в стиле «ночной кошмар». От Заказчика с некоторым периодом поступают следующие требования:
- Сделайте форму для хранения данных о компании. Там надо только поля «название», «город», «улица», «дом».
- Ой! Оказывается у компании может быть много филиалов. Сделайте, чтобы можно было в форме задать адрес каждого филиала по отдельности.
- Мы тут подумали, нам бы еще надо, чтобы у каждой компании в форме можно было записать несколько проектов, которые она выполняла.
- Добавьте, пожалуйста, контактное лицо к каждому филиалу. А… Добавили? А как к каждому телефону указать имя человека? … Нам надо чтобы можно было задать много контактных лиц в каждом филиале и каждому указать отдельный телефон.
Дабы избежать кошмара постоянного программирования всех этих кнопочек – «добавить», «удалить», «перенести», не мучаться с формированием динамических структур, удобно обрабатывать значения полей, я и задумался на созданием этого плагина.
Исходники Заранее предупреждаю, что плагин еще сырой. Но если у общества будет интерес, то я планирую его дорабатывать и выкладывать следующие версии.Страничка проекта находится на
Сегодня формы - это один из важнейших инструментов взаимодействия пользователей с веб-приложениями. Формы позволяют организовать эффективное управление информацией на сайте, состоянием самого сайта, оказывать услуги клиентам, передавать информацию другим пользователям, предоставлять доступ к закрытому разделу и многое-многое другое... Поэтому существует вполне естественное желание сделать формы более удобными и адаптированными под конкретные нюансы работы.
Одним из направлений такого улучшения может быть реализация возможности интерактивно, без перезагрузки страницы, управлять количеством полей для ввода данных, как в сторону увеличения, так и в сторону уменьшения. Это может быть очень удобно если необходимо добавить в базу данных приложения не одну, а сразу несколько записей; или если заранее не известно количество однотипных данных, каждое из которых требует отдельного поля для ввода (например, несколько телефонов или кредитных карт пользователя). В этой статье разберем одну из простых реализаций такой возможности через использование javascript библиотеки jQuery.
В самом низу, вы можете скачать архив с примерами, которые разбираются в этой статье.
Добавление нового поля в форму.Создавать новое поле формы будем с помощью метода.append():
$("селектор" ) .append ("строка" ) ;который добавляет “строку” во внутрь элемента с указанным “селектором”, при этом добавляемая строка следует за уже существующим содержимым.
Если рассматривать конкретный пример, то это может быть примерно так:
Поле №1 "/> Добавить новое полеСама функция addField() может быть реализована следующим образом:
< script type= "text/javascript" > function addField () { var telnum = parseInt($("#add_field_area" ) .find ("div.add:last" ) .attr ("id" ) .slice (3 ) ) 1 ; $("div#add_field_area" ) .append (" Поле №" telnum "" ) ; }
Сначала, как обычно, подключаем библиотеку jQuery и далее объявляем функцию addField(). Функция сначала вычисляет номер, который необходимо вставить в добавляемый элемент - по этому номеру, мы в последствии будем удалять ненужные поля. Затем addField() добавляет в div#add_field_area код блока div#add№ с полем формы внутри, код которого полностью аналогичен коду “Поле №1”, указанному чуть выше. Теперь при нажатии на кнопку “Добавить”, мы можем видеть как мгновенно появляется новое поле.
Удаление конкретного поля формы.Для удаления элементов DOM-дерева можно пользоваться методом remove():
$("селектор" ) .remove () ;который применяется к элементу с указанным “селектором”. Будем считать, что по умолчанию одно поле всегда должно оставаться, все дополнительные можно удалять. Для этого в функции addField(), в строке параметра метода.append() мы добавим код кнопки удаления поля, при нажатии на которую будет идти обращение к функции deleteField (id), при этом в функцию будет передаваться номер поля, которое нужно удалить.
function addField () { var telnum = parseInt($("#add_field_area" ) .find ("div.add:last" ) .attr ("id" ) .slice (3 ) ) 1 ; $("div#add_field_area" ) .append (" Поле №" telnum " " ) ; }Сама функция deleteField() может быть устроена предельно просто:
function deleteField (id) { $("div#add" id) .remove () ; }Собственно все. Теперь при нажатии на кнопку (красный крестик) напротив выбранного поля - оно исчезнет, а вместе с ним и та информация, которая была записана в нем.
Обработка данных на сервере (php).Когда форма содержит множественные поля, с однотипными данными, то естественно встает вопрос обработки данных, например перед отправкой в базу данных. В примере выше, этот вопрос решается указанием у поля формы атрибута name с параметром val. Это означает, что после отправки данных этой формы методом POST, значения этих полей будут помещены в массив $_POST[‘val’], элементы которого можно перебрать в цикле foreach (...) {...}, например:
foreach ($_POST [ "val" ] as $value ) { // ваш код.... }Или, если необходимо, все данные этих однотипных полей “склеить” в одну строку с помощью функции implode():
$str = implode ("|" , $_POST [ "val" ] ) ;Тогда все значения полей с name=”val” - будут объединены в строку с разделителем “вертикальная черта”.
Но, это обработка на стороне сервера, которая кстати говоря - более предпочтительна по соображениям безопасности. Но, могут возникнуть обстоятельства вынуждающие вас выполнять обработку таких полей на клиентской стороне: например у вас нет доступа к скриптам сервера (используется какой-то удаленный обработчик формы), или вы не можете по каким-то причинам изменить работу обработчика формы на вашем сервере. В таком случае можно так же пользоваться средствами языка javascript, а так как мы уже работаем с библиотекой jQuery - то и продолжим работать в ней.
Обработка данных на клиентской стороне.Допустим наша задача, все данные этого множественного поля, объединить в строку с разделителем вертикальная черта “|”. На самом деле реализуется это достаточно просто.
Для начала, нам необходимо несколько модифицировать саму форму, а именно добавить одно скрытое поле: