Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11656
Последний выпуск: 19.06.2015

Создание динамических форм с помощью JavaScript

Дмитрий Верещака, 23.07.2003
dmitry[@]rsl.ru; http://dmitry.rsl.ru/

Очень часто при создании HTML-форм возникает потребность узнать у пользователя значения однотипных параметров, количество которых заранее неизвестно. Например, если это форма добавления сообщения в форум с возможностью прикрепить один или несколько файлов, например, с фотографиями. Другим примером может служить форма с анкетой, в которой есть сведения о детях. И в том и другом случае невозможно заранее предположить количество полей, которые пожелает заполнить посетитель сайта.

Без использования JavaScript эту задачу можно решить двумя путями:

  1. Ограничить количество полей ввода каким-либо максимально разумным числом. Например, количество людей, у которых число детей больше 5, относительно невелико. Однако этот способ несколько некрасивый - во-первых, мы изначально загромождаем форму большим числом полей ввода, причём, большинству пользователей понадобятся от силы два - три первых, а во-вторых, мы всё-таки ограничиваем пользователя в возможности указать полную информацию о себе - так, если форму пожелает заполнить человек, у которого 10 сыновей, то некоторыми из них ему придётся пожертвовать.
  2. Осуществлять ввод информации поэтапно. Например, на первом этапе предложить пользователю ввести количество фотографий, которые он желает загрузить на сервер, а на втором этапе при помощи скрипта на сервере сформировать форму с нужным количеством полей ввода.
Однако, используя JavaScript, мы можем облегчить пользователю ввод информации о себе. Сделать это можно, например, следующим образом:

Пусть, для определённости, пользователю необходимо ввести информацию о детях, а для упрощения примера - только имя и дату рождения. Со стороны пользователя нам понадобится браузер, понимающий тэг <span> и регулярные выражения, поддерживающий функцию getElementById объекта document, а также понимающий свойство innerHTML, например, Internet Explorer 5.5

Оформим ту часть формы, которая содержит информацию о детях, в виде таблицы. В самой первой строке таблицы мы разместим названия столбцов и добавим ещё одну ячейку, в которой разместим ссылку на добавление ещё одной строки с полями ввода информации. Во второй строке таблицы мы разместим сами поля ввода информации плюс ячейку со ссылкой на удаление строки с информацией. Чтобы можно было отличить строку данных от строки названий, добавим в тэг <tr> параметр id="newline" и номер строки в квадратных скобках (чтобы было легче отличить номер строки от символа 0) nomer="[0]". Затем поместим всю таблицу во внутрь тэга span с каким-либо именем, например, table. И напоследок, добавим еще поле ввода типа hidden для того, чтобы считать строки таблицы.
В итоге у нас должно получиться что-то вроде следующего HTML-кода:

<span id="table">
<table border=0 cellspacing=0 cellpadding=3>
<caption>Сведения о детях</caption>
<tr><td>Имя</td><td>Дата рождения</td><td><a href="#"
onclick="return addline();">добавить</a></td></tr>
<tr id="newline" nomer="[0]">
<td><input type="text" name="name[0]"></td><td><input type="text" name="date[0]"></td>
<td valign="top"><a href="#" onclick="return rmline(0);">удалить</td></tr></table>
</span>
<input type="hidden" name="count" value="0">
Чтобы вся эта конструкция заработала, необходимо еще написать две функции на JavaScript: добавление новой строки и удаление ошибочно добавленной строки. Причём, в данном примере предполагается, что количество строк с данными может быть и нулевым, кроме того, у данной реализации динамической формы есть недостаток: если удалить все строки, то добавить строки уже будет нельзя.
<script>
function addline()
{
	c=++document.getElementById('count').value; // увеличиваем счётчик строк
	s=document.getElementById('table').innerHTML; // получаем HTML-код таблицы
	s=s.replace(/[\r\n]/g,''); // вырезаем все символы перевода строк
	re=/(.*)(<tr id=.*>)(<\/table>)/gi; 
	// это регулярное выражение позволяет выделить последнюю строку таблицы
	s1=s.replace(re,'$2'); // получаем HTML-код последней строки таблицы
	// заменяем все цифры к квадратных скобках
	s2=s1.replace(/\[\d+\]/gi,'['+c+']'); 
	// на номер новой строки
	s2=s2.replace(/(rmline\()(\d+\))/gi,'$1'+c+')');
	// заменяем аргумент функции rmline на номер новой строки
	s=s.replace(re,'$1$2'+s2+'$3');
	// создаём HTML-код с добавленным кодом новой строки
	document.getElementById('table').innerHTML=s;
	// возвращаем результат на место исходной таблицы
	return false; // чтобы не происходил переход по ссылке
}
function rmline(q)
{
	s=document.getElementById('table').innerHTML;
	s=s.replace(/[\r\n]/g,'');
	re=new RegExp('<tr id="?newline"? nomer="?\\['+q+'.*?<\\/tr>','gi');
    // это регулярное выражение позволяет выделить строку таблицы с заданным номером
	s=s.replace(re,'');
    // заменяем её на пустое место
	document.getElementById('table').innerHTML=s;
	return false;
}
</script>

результат выполнения браузером вышеуказанного примера выглядит так:

Сведения о детях
ИмяДата рождениядобавить
удалить

Таким образом, мы обнаружили, что использование регулярных выражений в JavaScript+DHTML открывает нам много новых возможностей для создания удобного пользовательского интерфейса. В частности, данный приём используется автором этих строк в интерфейсе администратора своего сайта для добавления нескольких картинок к странице в одной форме.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
66K
15 мая 2015 года
farrukh
5 / / 15.05.2015
Мне нравитсяМне не нравится
15 мая 2015, 08:43:16
как можно на эту форму создать динамический добавлять столбцов в mysql спасибо за ответ
2.
13K
28 июля 2005 года
Igor_it
2 / / 28.07.2005
Мне нравитсяМне не нравится
13 апреля 2007, 07:21:02
br /> <table id="myTable" border="1">
<tr>
<td>Row 1</td>
<td><input type="button" value="Delete" onclick="deleteRow(this)"></td>
</tr>
<tr>
<td>Row 2</td>
<td><input type="button" value="Delete" onclick="deleteRow(this)"></td>
</tr>
3.
13K
28 июля 2005 года
Igor_it
2 / / 28.07.2005
Мне нравитсяМне не нравится
13 апреля 2007, 07:10:02
во первых -код не работает в мозиле(кнопка добавить), во вторых все намного проще=)
Код:
добавляем:

function insRow()

  {

  var x=document.getElementById('myTable').insertRow(0)

  var y=x.insertCell(0)

  var z=x.insertCell(1)

  y.innerHTML="NEW CELL1"

  z.innerHTML="NEW CELL2"

  }

</script>

удалаем:



function deleteRow(r)

  {

  var i=r.parentNode.parentNode.rowIndex

  document.getElementById('myTable').deleteRow(i)

  }

и все.. без комментариев=)
4.
Аноним
Мне нравитсяМне не нравится
7 апреля 2006, 19:57:28

Цитата:
pav [05.05.2005 10:03 MSD]
Данный код в FireFox к сожелению неработатет :( Нету ли чего подобного, но кроссброузерного?




Глюки в предыдущем коде-- >(В опере не проверял...)
1. После удаления всех строк, новых нет...(IE,Mozilla)
2. если заменить name=-id у count то работает и в Firefox,
но с лагами (при добавлении/удалении строки, обнуляются оба input (value))

Ниже я представил пример своих исправлений, протестил их в mozille и IE, глюков не нашел!
Но все же если кто вдруг найдет глюки, то пишите ISQ: 304-983-214 исправим вместе!


<blockquote><small>Цитата:<hr size=1>
<span id="table">
<table border=0 cellspacing=0 cellpadding=3>
<caption>Сведения о детях</caption>
<tr><td>Имя</td><td>Дата рождения</td><td><a href="#"
&#111;&#110;click="return addline();">добавить</a></td></tr>
<tr id="newline" style="display:none;">
<td><input type="text" id="name[99]" value=" "></td><td><input type="text" id="date[99]" value=" "></td>
<td valign="top"><a href="#" &#111;&#110;click="return rmline(0);">удалить</a></td></tr>
<tr id="newline0">
<td><input type="text" id="name[0]" value=" "></td><td><input type="text" id="date[0]" value=" "></td>
<td valign="top"><a href="#" &#111;&#110;click="return rmline(0);">удалить</a></td></tr>
<tr id="al"></tr>
</table>
</span>
<input type="hidden" id="count" value="0">

<script>
function addline()
{

c=++document.getElementById('count').value; // увеличиваем счётчик строк
mas1(c);
s=document.getElementById('table').innerHTML; // получаем HTML-код таблицы
s=s.replace(/[\r\n]/g,''); // вырезаем все символы перевода строк
re=/(.*)(<tr id=.*>)(<\/tbody><\/table>)/gi;

// это регулярное выражение позволяет выделить последнюю строку таблицы
s1=s.replace(re,'$2'); // получаем HTML-код последней строки таблицы

ss='newline'+(c);
s2='<tr id="'+ss+'">'+document.getElementById('newline').innerHTML+'</tr><tr id="al"></tr>';
// заменяем все цифры в квадратных скобках
s2=s2.replace(/\[\d+\]/gi,'['+c+']');
s2=s2.replace('(0)','('+c+')');
s=s.replace(s1,s2);

// создаём HTML-код с добавленным кодом новой строки
document.getElementById('table').innerHTML=s;
mas2(c);
// возвращаем результат на место исходной таблицы
return false; // чтобы не происходил переход по ссылке
}
function mas1(x)
{
qwe=new Array(99,99);
for (i=0;i<=x;i++) {
x1=document.getElementById('name['+i+']');
if (x1!=null) x1=x1.value;
x2=document.getElementById('date['+i+']');
if (x2!=null) x2=x2.value;
qwe=new Array(x1,x2);
}

}


function mas2(x)
{
for (i=0;i<=x;i++) {
x1_=qwe[0]; if (x1_=='undefined') x1_="";
x2_=qwe[1]; if (x2_=='undefined') x2_="";
x1=document.getElementById('name['+i+']');
if (x1!=null) x1.value=x1_;
x2=document.getElementById('date['+i+']')
if (x2!=null) x2.value=x2_;
}
}


function rmline(q)
{
c=document.getElementById('count').value;
mas1(c);
s=document.getElementById('table').innerHTML;
s=s.replace(/[\r\n]/g,'');
re=new RegExp('<tr id="?newline'+q+'.*?<\\/tr>','gi');
// это регулярное выражение позволяет выделить строку таблицы с заданным номером
s=s.replace(re,'');
// заменяем её на пустое место
document.getElementById('table').innerHTML=s;
mas2(c);
return false;
}
</script>
[/quote]

5.
Аноним
Мне нравитсяМне не нравится
31 марта 2006, 18:17:52
[Для PAVa]

Неправильно:
<input type="hidden" name="count" value="0">

Правильно:!!!
<input type="hidden" id="count" value="0">

----------------
Тогда и в Firefoxe работает!
6.
Аноним
Мне нравитсяМне не нравится
20 февраля 2006, 19:49:46
А как быть если одно из полей является e-mail адресом и я хочу проверить его валидность средствами регулярных выражений? Было бы еще интересно посмотреть на пример вызова написанных выше функций, а не на результат вызова
7.
Аноним
Мне нравитсяМне не нравится
1 декабря 2005, 00:07:34
2 Black Angel
можешь выложить пример пожалуйста ?
8.
Аноним
Мне нравитсяМне не нравится
24 августа 2005, 13:12:34
Использовать innerHTML - плохой тон, ибо появятся проблемы с совместимостью!
Самый правельный вариант использовать DOM!
CreateElement! Код - более громоздкий, но работает везде!
9.
Аноним
Мне нравитсяМне не нравится
23 августа 2005, 13:06:37
по-моему так работает еще лучше:
1)
добавляем еще одно скрытое поле
<input type="hidden" name="id_row" value="0"> <!-- уникальный ID каждой строки таблицы-->
2)
function addline()
{
c=++document.getElementById('count').value; // увеличиваем счётчик строк
id=++document.getElementById('id_row').value; // увеличиваем ID строк
s=document.getElementById('table').innerHTML; // получаем HTML-код таблицы
s=s.replace(/[\r\n]/g,''); // вырезаем все символы перевода строк
re=/(.*)(<\/table>)/gi;
// это регулярное выражение позволяет выделить последнюю строку таблицы
s1="<TR id=newline nomer=\"[0]\"><TD><INPUT name=name[0]></TD><TD><INPUT name=date[0]></TD><TD vAlign=top><A &#111;&#110;click=\"return rmline(0);\" href=\"#\">удалить</A></TD></TR></TBODY>";
// заменяем все цифры к квадратных скобках
s2=s1.replace(/\[\d+\]/gi,'['+id+']');
// на номер новой строки
s2=s2.replace(/(rmline\()(\d+\))/gi,'$1'+id+')');
// заменяем аргумент функции rmline на номер новой строки
s=s.replace(re,'$1'+s2+'$2');
// создаём HTML-код с добавленным кодом новой строки
document.getElementById('table').innerHTML=s;
// возвращаем результат на место исходной таблицы
return false; // чтобы не происходил переход по ссылке
}
3)
function rmline(q)
как написал кот
10.
Аноним
Мне нравитсяМне не нравится
14 мая 2005, 04:01:44
Исправляем указанный глюк:
Код:
1)

//re=/(.*)(<tr id=.*>)(<\/table>)/gi;

re=/(.*)(<\/table>)/gi;

2)

//s1=s.replace(re,'$2');

s1="<TR id=newline nomer=\"[0]\"><TD><INPUT name=name[0]></TD><TD><INPUT name=date[0]></TD><TD vAlign=top><A &#111;&#110;click=\"return rmline(0);\" href=\"#\">удалить</A></TD></TR></TBODY>";

3)

//s=s.replace(re,'$1$2'+s2+'$3');

s=s.replace(re,'$1'+s2+'$2');


По моему работает. Тупо но тем не мене лучше чем ничего...
11.
Аноним
Мне нравитсяМне не нравится
5 мая 2005, 10:03:57
Данный код в FireFox к сожелению неработатет :( Нету ли чего подобного, но кроссброузерного?
12.
Аноним
Мне нравитсяМне не нравится
25 марта 2005, 00:03:14
запустить это все в цикле
13.
Аноним
Мне нравитсяМне не нравится
10 ноября 2004, 17:13:07
мне кажется так лучше:

function rmline(q)
{
if (document.all.count.value != 0)
{
s=document.getElementById('table').innerHTML;
s=s.replace(/[\r\n]/g,'');
re=new RegExp('<tr id="?newline"? nomer="?\\['+q+'.*?<\\/tr>','gi');
// это регулярное выражение позволяет выделить строку таблицы с заданным номером
s=s.replace(re,'');
// заменяем её на пустое место
document.getElementById('table').innerHTML=s;
document.all.count.value = document.all.count.value-1;
}
return false;
}
14.
Аноним
Мне нравитсяМне не нравится
17 августа 2004, 12:23:45
А как сделать, чтоб не использовать method=post ?:-(
15.
Аноним
Мне нравитсяМне не нравится
28 мая 2004, 01:24:49
Тут есть один глюк: если нажать удалить на всех строках таблицы - их будет уже не вернуть с помощью "добавить". Так что исправляйте... (сами)
16.
Аноним
Мне нравитсяМне не нравится
24 мая 2004, 17:11:25
А как сделать чтобы на одной странице было сколь угодно много таких форм
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог