Skip to content

Динамическое создание элементов форм

Взял отсюда - http://vvy.me/10-javascript-dinamicheskoe-sozdanie-elementov.html

В начале упрошенный вариант нарытого мной в нете скрипта:

<input type="button" value="Добавить еще один инпут" /></code>

<form>
<div id="inputi"><input name="my_input" type="text" /></div>
</form>

<script language="javascript">// <![CDATA[
function add_input()
{
document.getElementById("inputi").innerHTML=document.getElementById("inputi").innerHTML+'инпут №'+document.getElementById(‘inputi’).getElementsByTagName(‘input’).count+'<input name="my_input">';
}
// ]]></script>

Если насоздавать, скажем, три input-а, забить в них данные, а потом создать еще один, то содержимое первых трех куда-то исчезнет. И не удивительно, ведь при каждом добавлении элемента в div id="inputi" мы перезаписываем его содержимое. Например, если мы выполним, казалось бы, безобидную строку

element.innerHTML= element.innerHTML;

то интерпретатор javascropt:
сотрет весь html-код внутри нашего элемента,
сотрет DOM-овские объекты, связанные с этим элементом,
запишет в элемент новый html-код,
создаcт новые объекты DOM-а, в которых естественно нет значений старых input-ов.

И спасибо новым и умным браузерам, которые услужливо создадут и заполнят нам все новые узлы и их значения в DOM, хотя совершенно не обязаны этого делать. Почему? Да потому, innerHTML предназначен в первую очередь для более удобного получения содержимого элемента, вместе с дочерними, по отношению к нему. А вот создание, удаление и редактирование узлов DOM дерева, в которых и хранится введенная пользователем информация, совсем не его стихия, хотя в современных условиях метод innerHTML часто применим, но не всегда подходит. Для нашего же случая W3C рекомендует следующие методы, которые есть у каждого блочного элемента:

appendChild(child)
Добавляет дочерний узел к объекту,

removeChild(child)
Удаляет дочерний узел child.

На этом теоретическая часть закончена, перейдем к самому скрипту:

<input type="button" value="Добавить еще один инпут" />
<input type="button" value="Убрать лишний" /></code>

<form>
<div id="inputi"><input name="my_input" type="text" /></div>
</form><script language="javascript">// <![CDATA[
function add_input()
{
// Создаем новый div-элемент
var new_input=document.createElement('div');
// Тут мы уже можем воспользоваться innerHTML потому, что изменения не коснуться всего остального докуметна
new_input.innerHTML='
инпут №'+document.getElementById('inputi').getElementsByTagName('div').length+'
<input name="my_input">';
// Добавляем только что созданный div на страницу
document.getElementById('inputi').appendChild(new_input);
}
function del_input()
{
// удаляем последний div в нутри id=inputi
document.getElementById('inputi').removeChild(document.getElementById('inputi').getElementsByTagName('div')[document.getElementById('inputi').getElementsByTagName('div').length-1])
}
// ]]></script>

 

А теперь. для полного феншуя. напишем скрипт, который сможет удалять произвольный импут в нашей форме (а не последний), и дописывать новый в нужное нам место (а не в самый конец).
А заодно посмотрим, как работают еще несколько методов:
nextSibling
возвращает следующий узел в DOM дереве или false/nil/undefined (в зависимости от контекста), если такого узла нет

insertBefore(child,obj)
добавляет в DOM дерево узел child перед узлом obj

Использовать будем именно .insertBefore, т.к. метода .insertAfter в javascript просто нет.

<!--От этих двух кнопок, в принципе, уже можно избавится-->
<input type="button" value="Добавить еще один инпут" />
<input type="button" value="Убрать лишний" /></code>

<form>
<div id="inputi">
<div><input name="my_input" type="text" /><input type="button" value="+" /></div>
</div>
</form><script language="javascript">// <![CDATA[
// Теперь эта функция будет принимать указатель на объект, после которого нужно осуществить вставку
function add_input(obj)
{
var new_input=document.createElement('div');
new_input.innerHTML='
инпут №'+document.getElementById('inputi').getElementsByTagName('div').length+'
<input name="my_input">';
// Дописываем рядом с input-ом кнопку, она будет добовлять элемент именно под input, рядом с которым она находится
new_input.innerHTML=new_input.innerHTML+'<input type="button" value="+" onclick="add_input(this.parentNode)">';
// И еще одна кнопочка для его удаления.
new_input.innerHTML=new_input.innerHTML+'<input type="button" value="-" onclick="del_input(this.parentNode)">';
//Ищем присутствует ли следующий узел в структуре DOM-а
if (obj.nextSibling)
// если да - то создаем после него
document.getElementById('inputi').insertBefore(new_input,obj.nextSibling)
//если такого не нашлось то просто добавляем в конец
else document.getElementById('inputi').appendChild(new_input);
}
// А эта функция будет принимать указатель на объект, который нужно удалить
function del_input(obj)
{
document.getElementById('inputi').removeChild(obj)
}
// ]]></script>

 

И, напоследок, немного функций javascript, которые помогут в создании, удалении и изменении узлов DOM дерева:

createElement(element)
создание нового элемента,

createTextNode(string)
создание нового текстового узла,

appendChild(child)
добавляет дочерний узел к объекту,

insertBefore(child,obj)
добавляет узел child перед узлом obj,

cloneNode()
копирует узел со всеми дочерними узлами,

hasChildNodes()
проверяет, имеет ли объект дочерние узлы и если это так, то возвращает true,

removeChild(child)
удаляет дочерний узел,

replaceChild(child,obj)
перемещает узел child на место узла obj,

setAttribute(attribute,value)
добавляет объекту новый атрибут attribute с значением value

removeAttribute(attribute)
удаляет атрибут объекта.

Leave a Reply

Your email address will not be published. Required fields are marked *

π