Произвольное число полей в веб-форме

от автора

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

Один из возможных вариантов решения — получать информацию в сыром виде и обрабатывать ее согласно определенным алгоритмам. Допустим, поместить слова в массив и пройти через него регулярным выражением на сервере.
Можно использовать сложный плагин jQuery и оперировать объектами JSON.
Или можно построить простой клиентский скрипт для отрисовки массива полей по флагам.


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

Далее следует придумать механизм добавления полей. В простейшем случае мы формируем html-шаблон поля и добавляем его в определенный блок нужное число раз. Обратная сторона этой простоты — невозможность удалить какое-то определенное поле. Потому что как скрипт узнает, в какой именно блок мы ткнули, желая убрать его из списка? Можно передавать идентификатор строки функции разбора DOM, которая пройдет по содержимому целевого блока до нужного узла и отсоединит его. Или инициализировать счетчик и использовать флаги: если значение — 1, то такой блок нам нужен, а если 0 — давайте его удалим.

Кроме того, стоит обрабатывать и добавление и удаление полей одной функцией, для чего достаточно научить ее отличать плюс от идентификатора.

Посмотрим на код:

	<script> 		var i = 0; // Инициализируем счетчик 		var emp_arr = new Array(); 		function emp_list(flag, emp_arr) 		{ 			var emp_div = document.getElementById('employees'); // Находим целевой элемент 				 			emp_div.innerHTML = ''; // Очищаем целевой элемент  			if('+' == flag) 			{ 				i++; 				emp_arr[i] = 1; // Добавляем в массив сотрудников 			} 			else 			{	 				var sum = 0; // Не позволяем удалять последний элемент - если сумма ключей в массиве равна единице, ничего не делаем 				for(var z=0; z<=emp_arr.length; z++) 				{ 						if(1 == emp_arr[z]) {sum++;} 				}					 				if(1 != sum) {emp_arr[flag] = 0;} 			} 			for(var z=0; z<=emp_arr.length; z++) 			{ 				// Для дальнейшей обработки данных на сервере передаем элементы с именами в виде массивов. Затем сможем получить их значения при переборе $_POST 				var emp_field='<p><input type="text" name="family_name[]" value="Фамилия" size="20" /> <input type="text" name="first_name[]" value="Имя" size="20" /> <input type="text" name="fathers_name[]" value="Отчество" size="20" /> | Номер мобильного телефона: <input type="text" name="tel_num[]" value="+7(999) 999-9999" size="20" /> | <span class="link" onclick="emp_list(\''+z+'\', emp_arr);">Удалить</span></p>'; 				if(1 == emp_arr[z]) {emp_div.innerHTML+=emp_field;}  			} 		} 	</script> 

Добавим разметку для вывода, кнопку вызова функции и инициализирующую инструкцию:

	<div id="employees"> 		<!-- Здесь будут поля формы --> 		<script> 			emp_list('+', emp_arr); 		</script> 	</div> 	<p><span class="link" onclick="emp_list('+', emp_arr);">Добавить сотрудника</span></p> 

Стили для кнопок:

	<style> 	.link { color: #0069c4; cursor: pointer;} 	.link:hover {text-decoration: underline;} 	</style> 

Готово

Весь код тестового файла

<!DOCTYPE html> <html>   <head>          <title>Произвольное число полей в веб-форме</title> 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 	 	<style> 	.link { color: #0069c4; cursor:pointer;} 	.link:hover {text-decoration:underline;} 	</style> 	 	<script> 		var i = 0; // Инициализируем счетчик 		var emp_arr = new Array(); 		function emp_list(flag, emp_arr) 		{ 			var emp_div = document.getElementById('employees'); // Находим целевой элемент 				 			emp_div.innerHTML = ''; // Очищаем целевой элемент  			if('+' == flag) 			{ 				i++; 				emp_arr[i] = 1; // Добавляем в массив сотрудников 			} 			else 			{	 				var sum = 0; // Не позволяем удалять последний элемент - если сумма ключей в массиве равна единице, ничего не делаем 				for(var z=0; z<=emp_arr.length; z++) 				{ 						if(1 == emp_arr[z]) {sum++;} 				}					 				if(1 != sum) {emp_arr[flag] = 0;} 			} 			for(var z=0; z<=emp_arr.length; z++) 			{ 				// Для дальнейшей обработки данных на сервере передаем элементы с именами в виде массивов. Затем сможем получить их значения при переборе $_POST 				var emp_field='<p><input type="text" name="family_name[]" value="Фамилия" size="20" /> <input type="text" name="first_name[]" value="Имя" size="20" /> <input type="text" name="fathers_name[]" value="Отчество" size="20" /> | Номер мобильного телефона: <input type="text" name="tel_num[]" value="+7(999) 999-9999" size="20" /> | <span class="link" onclick="emp_list(\''+z+'\', emp_arr);">Удалить</span></p>'; 				if(1 == emp_arr[z]) {emp_div.innerHTML+=emp_field;}  			} 		} 	</script> 	   </head>   <body>    	<h1>Информация о сотрудниках</h1>  	<div id="employees"> 		<!-- Здесь будут поля формы --> 		<script> 			emp_list('+', emp_arr); 		</script> 	</div> 	<p><span class="link" onclick="emp_list('+', emp_arr);">Добавить сотрудника</span></p>      </body> </html> 

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

ссылка на оригинал статьи http://habrahabr.ru/post/164137/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *