Tym razem pokażemy, jak dynamicznie dodawać nowe elementy do formularza. Ze znajomością kilku funkcji okaże się to łatwe i szybkie.
Często zachodzi potrzeba dodania konkretnej liczby pól w formularzu (gdy chcemy wgrać wiele plików naraz). Wówczas przydaje się button/link, po kliknięciu którego w dokumencie pojawia się nowy {html}{/html}. Spróbujemy coś takiego zrealizować. Standardowo zaczniemy od gotowego pliku HTML, który nie zawiera ani jednej linijki kodu JavaScript.
Strona z dynamicznym formularzem
Aby dodać nowe pole do formularza, po kliknięciu linku dodaj nowe pole typu file należy wykonać poniższe kroki:
- przechwycić zdarzenie, gdy ktoś kliknie link o id=\”add_input\” i uruchomić specjalną funkcję, która będzie obsługiwała dodawanie nowego pola (nazwijmy ją DodajElement),
- utworzyć w JavaScripcie nowy tag {html}{/html} (nowość!),
- nadać mu atrybut type (w tym wypadku jest to file),
- nadać unikatową nazwę (name) typu file-x, gdzie x oznacza kolejną liczbę porządkową inputów w dokumencie (aby otrzymać tę liczbę, musimy wcześniej policzyć, ile inputów zostało dodanych do formularza),
- dodać nowo utworzony tag input do formularza (nowość!).
Czas na wypełnienie naszego planu. Musimy nadać właściwość onclick naszemu linkowi po załadowaniu całego dokumentu. Odpowiedzialna za to będzie funkcja Laduj.
window.onload = Laduj;
function Laduj()
{
document.getElementById(\'add_input\').onclick = DodajElement;
}
Oczywiście można też zastosować zapis:
window.onload = Laduj;
function Laduj()
{
var link = document.getElementById(\'add_input\');
link.onclick = DodajElement;
}
Po co jednak tworzyć niepotrzebnie długi kod. Pora teraz zdefiniować nową funkcję, która wykona się po kliknięciu naszego linku i będzie odpowiedzialna za dodanie nowego elementu do formularza.
function DodajElement()
{
}
Trzeba uzupełnić tę funkcję niezbędnym kodem. Najpierw należy utworzyć nowy tag (element input) w JavaScripcie. Pomoże w tym funkcja .createElement() (createElement = stwórz element). Ponieważ każdy tag jest dzieckiem całego dokumentu, używamy jej w połączeniu ze słówkiem document – document.createElement. Stworzymy więc dzięki niej nowy element input, który będzie zapisany w zmiennej o nazwie element:
function DodajElement()
{
var element = document.createElement(\'input\');
}
Następnie trzeba nadać temu elementowi typ (jak name, type czy style), bowiem każdy tag utworzony przez funkcję createElement jest pozbawiony jakichkolwiek atrybutów. Pomoże w tym funkcja setAttribute:
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
}
Pora teraz nadać nowemu elementowi nazwę, która nie będzie się dublować się z innymi inputami tego typu. Ponieważ nowo dodany element będzie którymś z kolei, policzymy dotychczasowe inputy i dodamy do tej sumy 1, na znak, że to następny element.
Najpierw zdefiniujemy zmienną o nazwie liczba, która będzie przechowywać liczbę inputów o type=\”file\”:
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
var liczba = 0;
}
I teraz pojawiają się małe problemy. Otóż nie istnieje żadna funkcja pozwalająca szybko policzyć, ile w danym tagu-rodzicu jest elementów o danym atrybucie – na przykład, ile w divie jest paragrafów z określonym id. Musimy zająć się tym sami i użyć pętli for() {}. Musi ona wykonać się tyle razy, ile formularz zawiera tagów typu {html}{/html}. Jeśli któryś tag będzie miał atrybut type równy file, wtedy zwiększymy wartość zmiennej liczba o jeden, na znak, że odnaleźliśmy kolejny element o typie file.
{stala}document.createElement(nazwa_tagu){/stala}
Konstrukcja ta pozwala utworzyć nowy tag o nazwie podanej jako argument. Przykład:
{stala}var nowy_div = document.createElement(\’div\’);{/stala}
Zanim zaczniemy zabawę z pętlą, warto dowiedzieć się, że do pól formularza możemy odnieść się nie tylko w ten sposób:
document.forms[\'nazwa_forma\'].nazwa_pola.value
Równie dobrze można użyć właściwości każdego formularza, jakim jest tablica .elements. Wtedy powyższy zapis będzie wyglądał tak:
document.forms[\'nazwa_forma\'].elements[\'nazwa_pola\'].value
Analogicznie można otrzymać liczbę wszystkich pól formularza, odwołując się do właściwości tablic .length:
document.forms[\'nazwa_forma\'].elements.length
Właśnie z niej skorzystamy, bowiem nasza pętla for musi wykonywać się tyle razy, ile jest pól w formularzu. Przy każdym wykonaniu pętli sprawdzamy typ danego elementu formularza i dodajemy, bądź nie, jedynkę do zmiennej liczba.
Załóżmy więc, że liczbę wszystkich elementów formularza zapiszemy do zmiennej ilosc:
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
var liczba = 0;
var ilosc = document.forms[\'add_file\'].elements.length;
}
W ten sposób policzyliśmy liczbę pól w formularzu o name=\”add_file\”. Pora na pętlę for.
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
var liczba = 0;
var ilosc = document.forms[\'add_file\'].elements.length;
for (var i = 0; i < ilosc; i++ )
{
if (document.forms[\'add_file\'].elements[i].type == \'file\')
{
liczba += 1;
}
}
}
Powyższy listing możemy przetłumaczyć następująco: Począwszy od zmiennej i równej zero, póki zmienna ta nie jest większa od liczby wszystkich elementów formularza, wykonaj kod w klamrach i dodaj do zmiennej i jeden.
Kod w klamrach jest bardzo prosty. Do konkretnych elementów formularza można się dostać poprzez elements[x], gdzie x to liczba określająca, który z kolei element jest zapisany w formularzu. Jako że zmienna i to liczba z przedziału od zera do liczby elementów input formularza, podstawiamy ją do .elements i sprawdzamy (if(document.forms[\'add_file\'].elements[i].type ==\'file\' ) ), czy znaleźliśmy pole o type=\"file\".
Jeśli tak, dodajemy jeden do zmiennej liczba, która zawiera liczbę wszystkich inputów o type=\"file\".
Możemy sprawdzić, czy nasz skrypt działa odpowiednio, podstawiając wartość zmiennej liczba do alert();.
alert(liczba);
Jeśli nie dodaliśmy żadnego nowego elementu, pętla powinna znaleźć tylko jeden domyślny input o type=\"file\".
Jeśli mamy już liczbę wszystkich interesujących nas elementów, pora na nadanie nazwy nowemu inputowi.
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
var liczba = 0;
var ilosc = document.forms[\'add_file\'].elements.length;
for (var i = 0; i < ilosc; i++ )
{
if (document.forms[\'add_file\'].elements[i].type == \'file\')
{
liczba += 1;
}
}
element.setAttribute(\'name\', \'file-\'+(liczba+1));
}
Dodane element.setAttribute(\'name\', \'file-\'+(liczba+1)); pozwoli nam nazywać nowe elementy formularza w konwencji form-1, form-2 itd. Wszystko po to, by atrybut name nie powtarzał się. Zwróćmy uwagę na zapis +(liczba+1) - pozwala to dopisać do ciągu po lewej sumę w nawiasie. Natomiast zapis bez nawiasów -+liczba+1 - dopisze do \"file-\" wartość zmiennej liczba oraz jedynkę.
Dobrze byłoby też nadać jakiś atrybut style. Jeśli będziemy dodawać nowe inputy, każdy będzie obok siebie, co nie wygląda dobrze. Nadamy więc display: block każdemu nowemu elementowi.
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
var liczba = 0;
var ilosc = document.forms[\'add_ file\'].elements.length;
for (var i = 0; i < ilosc; i++ )
{
if (document.forms[\'add_file\'].elements[i].type == \'file\')
{
liczba += 1;
}
}
element.setAttribute(\'name\', \'file-\'+(liczba+1));
element.style.display = \"block\";
}
element.style.display = \"Block\";
Przyda się również margines:
element.style.margin= \"2px\";
Ostatnim punktem jest dodanie nowo utworzonego elementu (który zawiera się w zmiennej element, posiadającej różne, nadane przez nas właściwości, jak np. element.name itd.) do formularza. Odpowie za to funkcja appendChild().
{stala}rodzic.appendChild(dziecko){/stala}
Konstrukcja ta dodaje do \"rodzica\" nowe \"dziecko\". Rodzicem jest tutaj dany tag HTML w postaci
odnośnika doń, dzieckiem zaś nowy tag, który powinien się znaleźć pomiędzy tagami rodzica.
Wychodzi na to, że to formularz będzie rodzicem dla nowego inputa, bo rzeczywiście do niego chcemy dodać nowy element.
function DodajElement()
{
var element = document.createElement(\'input\');
element.setAttribute(\'type\', \'file\');
var liczba = 0;
var ilosc = document.forms[\'add_ file\'].elements.length;
for (var i = 0; i < ilosc; i++ )
{
if (document.forms[\'add_file\']. elements[i].type == \'file\')
{
liczba += 1;
}
}
element.setAttribute(\'name\', \'file-\' +(liczba+1));
element.style.display = \"block\";
element.style.margin= \"2px\";
document.forms[\'add_file\']. appendChild(element);
}
W ten sposób zapełniliśmy ciało funkcji Dodaj-Element. Ostatnia linijka dodaje utworzone pod zmienną element nowe pole formularza z type=\"file\". W powyższej konstrukcji odwołujemy się do formularza jako rodzica, używając document. forms[\'add_file\']. Nasz dokument wygląda teraz tak:
Strona z dynamicznym formularzem
Tym sposobem można dodawać zupełnie inne elementy formularza - choćby textarea, input o type=\"text\" i inne. Wystarczy tylko poeksperymentować z funkcją createElement.