Přidání dalšího textového pole
Jak umožnit kopírování/přidávání dalších textových polí do formuláře.
V případě, že ve webové aplikaci potřebujeme umožnit zadat více položek stejného typu, hodí se k tomu možnost JavaScriptem jednotlivá políčka duplikovat.
Alternativou je zobrazit předpokládaný počet políček rovnou a při zpracování formuláře brát v úvahu jen ta vyplněná. Dynamická změna počtu položek vypadá ale jako lepší volba.
Metoda cloneNode
Základem je JS metoda cloneNode
, která naklonuje první položku, a metoda appendChild
, která ji později vloží.
var prvniPolozka = document.getElementById('sablona');
var sablona = prvniPolozka.cloneNode(true);
Pro snadné klonování více <input>
ů či jiných formulářových prvků v rámci jedné položky je ideální všechno obalit nějakým elementem – nejspíš <div>
em.
<div class="polozka" id="sablona">
<input name="policko1[]">
<input name="policko2[]">
</div>
Za pozornost dále stojí, že klonování proběhne nadvakrát:
- Ihned po načtení stránky se naklonuje první položka.
- Při kliknutí na tlačítko Přidat se naklonuje tato kopie.
Proč? Kdyby se klonovala přímo živá první položka, promítl by se do klonu její stav (vyplněné hodnoty a podobně), což většinou není žádoucí. Další výhoda je v tom, že nemusíme řešit stav, kdy uživatel odstraní úplně všechny položky. I po odstranění všeho půjde přidat položku novou.
Pokud bychom chtěli zabránit odebrání i první položky, můžeme odebírací tlačítko skrýt pomocí CSS (display: none
) s využitím CSS selektoru :first-child
(IE 7+).
.polozka:first-child .odebrat {
display: none;
}
Odebrání removeChild
Odebrání bude velmi snadné. Tlačítko Odebrat bude v každém <div>
u s položkami. V případě, že tlačítko bude přímo v tomto obalu, stačí si najít jeho rodiče (parentNode
) a provést removeChild
.
function odebrat(el) {
var polozka = el.parentNode;
polozka.parentNode.removeChild(polozka);
}
Funkci odebrat
se pro zjištění rodiče předá odebírací tlačítko prostřednictvím this
.
<button onclick="odebrat(this)">
× Odebrat
</button>
Udělení focus
u
Po kliknutí na Přidat je vhodné rovnou označit první políčko přidané položky, aby do něj šlo rovnou psát:
kopie.getElementsByTagName("input")[0].focus();
Možná vylepšení
V závislosti na konkrétním použití je k úvaze případné vylepšení:
-
Novou položku přidávat místo na konec za položkou naposledy upravenou.
K tomu poslouží metoda
insertBefore
v kombinaci snextSibling
.polozky.insertBefore(kopie, aktualniPolozka.nextSibling);
-
Novou položku přidávat automaticky, když je předchozí (částečně) vyplněná. Tedy mít stále o jednu více položek, než je potřeba.
-
Někdy se může hodit možnost Vytvořit na základě předchozí, kde se naopak bude kopírovat obsah předchozí položky včetně vyplněných hodnot.
-
Pohrát si s
tabindex
em, aby po vyplnění posledního políčka položky klávesa Tab aktivovala tlačítko Přidat namísto Odebrat.Špatné pořadí políček je častou chybou formulářů.
-
Tlačítko Přidat umístit na místo, kde se nebude pohybovat v závislosti na počtu položek. Případně ho přidat ihned za položku před tlačítko Odebrat.
Zpracování na serveru
Pro pohodlné zpracování na serveru je ideální dávat prvkům formuláře názvy s hranatými závorkami []
, aby se s nimi dalo snadno pracovat jako s polem.
Komentáře