Občas se může hodit vytvořit dynamický formulář, jehož elementy jsou doplňovány až po vyvolání nějaké události uživatelem.
Článek se bude zabývat pouze vytvořením INPUTů a SELECTů z formuláře, ale obecně platí pro jakýkoli element.
Občas může nastat situace, kdy je potřeba vypsat formulář, který se bude dynamicky měnit v závislosti na uživatelově rozhodnutí.
Přesně k takovému formuláři nám může pomoci javascript, pomocí něhož jednoduše vytvoříme nový element a umístíme na příslušné místo:
Uvedený příklad si postupně rozebereme a vysvětlíme.
Základem celého příkladu jsou dvě funkce:
Obě funkce jsou volány po kliknutí na příslušný odkaz a je jim předáno jako parametr ID elementu, do kterého budou přidávat nebo mazat.
Nejprve trochu teorie:
CreateElement slouží, jak název napovídá, pro vytvoření elementu. Můžeme jím velice jednoduše vytvořit například TAG P, BR, nebo jakýkoli jiný jiné.
V našem příkladu potřebujeme vytvořit tagy SELECT, s ním související OPTION, a INPUT.
Funkce se volá velice jednoduše:
var input = document.createElement('input');
var option1 = document.createElement('OPTION');
var select = document.createElement('select');
Takto jednoduše vytvoříme elementy, se kterými můžeme dále pracovat.
SetAttribute slouží pro přidávání atributů k vytvořeným elementům nebo tagům. Tato funkce má dva parametry, první je jméno atributu a druhý je jeho hodnota. Můžeme tak snadno přidat k našemu inputu hodnotu name nebo value. Popřípadě tuto funkci můžeme zavolat vícekrát a přidat atributů víc:
input.setAttribute('name', 'input[]' );
input.setAttribute('value', 'text' );
CreateTextNode slouží pro vytvoření textového popisku. Prostě textu.
S textem můžeme potom dále pracovat a umístit jej například jako hodnotu do jiného elementu:
var txt1 = document.createTextNode("Krátký text");
option1.appendChild(txt1);
Funkce pro připojení potomka. U jejího použití je důležité si dávat pozor na správné připojování. Připojovat potomky můžeme pouze do párových tagů, takže například do INPUTU žádného potomka připojit nemůžeme. Na rozdíl od toho do SELECTu ano:
select.appendChild(option1); select.appendChild(option2); select.appendChild(option3); select.appendChild(option4);
Vymazání elementu. Použití je obdobné jako u appendChild.
Nyní vám popíši jak funguje můj příklad, který jsem uvedl výše.
Existují zde dvě funkce. Funkce plus() a funkce minus(). Funkce plus() slouží pro přidání řádku do formuláře a funkce minus() pro jeho vymazání.
Dále zde existuje globální proměnná pojmenovaná num_of_lines, do které si dynamicky ukládám počet vytvořených řádků ve formuláři, abych si podle ní mohl snadno vytvářet unikátní ID elementů pro mazání.
U obou funkcí je vstupní parametr název elementu, ID elemntu, do kterého se bude přidávat, nebo ze kterého se bude mazat.
Na začátku funkce si vytvořím proměnnou, ve které si uložím objekt elementu, předaný jako parametr, abych s ním mohl později pracovat. Přidávat do něj elementy.
var x = document.getElementById( element );
Nyní můžu začít vytvářet nový řádek formuláře. Jako první si vytvořím input a přidám do něj atribut name:
var input = document.createElement('input');
input.setAttribute('name', 'input[]' );
Další element, který budu potřebovat, je SELECT a několik OPTIONů. Do jednotlivých OPTIONů si přidám textové popisky a value hodnoty. Navíc budu potřebovat name hodnotu u SELECTU:
var option1 = document.createElement('OPTION');
option1.setAttribute('value', 'prvni');
var option2 = document.createElement('OPTION');
option2.setAttribute('value', 'druha');
var option3 = document.createElement('OPTION');
option3.setAttribute('value', 'treti');
var option4 = document.createElement('OPTION');
option4.setAttribute('value', 'ctvrta');
var txt1 = document.createTextNode("Krátký text");
option1.appendChild(txt1);
var txt2 = document.createTextNode("Dlouhý text");
option2.appendChild(txt2);
var txt3 = document.createTextNode("Celé číslo");
option3.appendChild(txt3);
var txt4 = document.createTextNode("Desetinné číslo");
option4.appendChild(txt4);
var select = document.createElement('select');
select.setAttribute('name', 'select[]' );
Nyní by jsem mohl tyto dva elementy již přidat pomocí appendChild do elementu předaného jako parametr, ale ještě si oba atributy obalím elementem span, který bude mít jedinečné ID a dle něhož se potom bude mazat. Navíc si můžu vytvořit ještě popisek k řádku formuláře a oddělit celý řádek tagem BR. Takže si všechny tyto elementy vytvořím:
var text = document.createTextNode('Možnost: ');
var p = document.createElement('span');
p.setAttribute('id', 'span_' + num_of_lines );
var br = document.createElement('br');
Nyní stačí pouze ve správném pořadí volat appendChild a všechny elementy do sebe zanořit:
select.appendChild(option1); select.appendChild(option2); select.appendChild(option3); select.appendChild(option4); p.appendChild(text); p.appendChild(input); p.appendChild(select); p.appendChild(br); x.appendChild(p);
Nakonec upravím proměnnou num_of_lines přičtením 1.
Tato funkce je oproti přidávání mnohem jednodušší. Stačí si pouze předat element a z tohoto elementu vymazat příslušný span, jak jsme si jej při přidávání vytvořili:
var d = document.getElementById( element ); var olddiv = document.getElementById( 'span_' + num_of_lines ); d.removeChild(olddiv);
Celý kód si můžete prohlídnout zde:
<script type="text/javascript">
var num_of_lines = 0;
function plus(element){
num_of_lines ++;
var x = document.getElementById( element );
var input = document.createElement('input');
input.setAttribute('name', 'input[]' );
var option1 = document.createElement('OPTION');
option1.setAttribute('value', 'prvni');
var option2 = document.createElement('OPTION');
option2.setAttribute('value', 'druha');
var option3 = document.createElement('OPTION');
option3.setAttribute('value', 'treti');
var option4 = document.createElement('OPTION');
option4.setAttribute('value', 'ctvrta');
var txt1 = document.createTextNode("Krátký text");
option1.appendChild(txt1);
var txt2 = document.createTextNode("Dlouhý text");
option2.appendChild(txt2);
var txt3 = document.createTextNode("Celé číslo");
option3.appendChild(txt3);
var txt4 = document.createTextNode("Desetinné číslo");
option4.appendChild(txt4);
var select = document.createElement('select');
select.setAttribute('name', 'select[]' );
var text = document.createTextNode('Možnost: ');
var p = document.createElement('span');
p.setAttribute('id', 'span_' + num_of_lines );
var br = document.createElement('br');
select.appendChild(option1);
select.appendChild(option2);
select.appendChild(option3);
select.appendChild(option4);
p.appendChild(text);
p.appendChild(input);
p.appendChild(select);
p.appendChild(br);
x.appendChild(p);
}
function minus(element){
if( num_of_lines < 1 )
return;
var d = document.getElementById( element );
var olddiv = document.getElementById( 'span_' + num_of_lines );
num_of_lines--;
d.removeChild(olddiv);
}
</script>
<a href="#" onclick="plus('new_sab'); return false;" >+</a> / <a href="#" onclick="minus('new_sab'); return false;" >-</a><br />
<a href="#" onclick="for( i = 0; i < 3; i++ ) plus('new_sab'); return false;">+ 3</a> / <a href="#" onclick="for( i = 0; i < 3; i++ ) minus('new_sab'); return false;">- 3</a> /
<form method="post" id="new_sab">
<div>
</div>
</form>