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

—

от автора

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

Один из возможных вариантов решения — получать информацию в сыром виде и обрабатывать ее согласно определенным алгоритмам. Допустим, поместить слова в массив и пройти через него регулярным выражением на сервере.
Можно использовать сложный плагин 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 не будет опубликован. Обязательные поля помечены *