Formularze

Formularze to jedne z najczęściej występujących komponentów na stronach. W poniższym tekście przyjrzymy się niektórym możliwościom jakie daje JavaScript jeżeli chodzi manipulowanie elementami formularza.

Forms

Wszystkie formularze na stronie mamy dostępne w postaci kolekcji document.forms:

console.log(document.forms);

Jak zobaczysz w konsoli, jest to kolekcja kolejnych formularzy, do których możesz odwoływać się przez odpowiedni indeks, ale też przez odpowiedni klucz, jeżeli dany formularz ma swoje ID. Oczywiście wszystkie sposoby pobierania elementów także się tutaj sprawdzą.

Dla każdego formularza najczęściej wykorzystywanymi rzeczami będą:

//właściwości
form.elements - kolekcja wszystkich elementów formularza (osobiście rzadko z tego korzystam na rzecz ręcznego wybierania za pomocą querySelector)
form.action - atrybut action formularza, czyli adres na który formularz zostanie wysłany
form.method - metoda jaką zostanie wysłany formularz (omawiana w dziale Ajax)

//metody
form.submit(); //wysłanie formularza bez zdarzenia submit i z pominięciem htmlowej walidacji
form.requestSubmit(); //wysłanie formularza i wywołanie dla niego zdarzenia submit
form.reset(); //zresetowanie formularza

//zdarzenia
submit - odpalane w momencie wysyłki formularza przez użytkownika

Pola formularza

Każdy formularz składa się z różnego rodzaju pól. W zależności od tego jakiego typu takie pole jest, powinniśmy je nieco inaczej obsługiwać. Jest jednak kilka wspólnych rzeczy, które będą dla nich pomocne.

Jeżeli chodzi o właściwości, które nas interesują są to najczęściej:

input.value
wartość pola, selekta itp.

input.disabled

czy pole jest wyłączone

input.readOnly

czy pole jest w trybie tylko do odczytu

input.checked

czy pole jest zaznaczone (używane tylko dla checkbox, radio)

Jeżeli chodzi o zdarzenia, to głównie będą nas interesować:

change
dla inputów tekstowych (:text, :url, :email, textarea itp) odpalany po zatwierdzeniu nowej wartości. Dla pól tekstowych oznacza to zmianę wartości i opuszczenie pola, dla checkboxów/radio kliknięcie takiego przycisku, a dla innych zmianę wartości

focus / blur

zdarzenia odpalane po wejściu i opuszczeniu danego pola. Stosowane raczej na pól tekstowych, gdy chcemy pokazać walidację gdy użytkownik opuści pole

keypress, keyup, keydown

zdarzenia związane z klawiaturą stosowane dla pól tekstowych

input

event odpalany gdy wartość pola zostanie zmieniona przez użytkownika (np. gdy ją wpisuje, gdy klika na checkbox itp.)

I znowu - wszystko zależy od sytuacji. Może chcemy pokazać w tle duży tekst, który został wpisany do pola? A może za pomocą input:range chcemy sterować jakimś elementem na stronie?

Przyjrzyjmy się najczęściej spotykanym sytuacjom.

Wartość pola

Prawdopodobnie główną właściwością, która będzie nas interesować będzie value, czyli aktualna wartość danego pola. Taka wartość zawsze będzie w formie tekstowej (nawet przy polach typu number, range i podobnych).

I w zasadzie tyle powinno nam w większości sytuacji wystarczyć. Cała reszta to odpowiednia manipulacja takim elementem i w zależności od sytuacji użycie odpowiednich zdarzeń.

Kolejny przykład pokazuje, jak możemy sprawdzić czy wpisywany ciąg ma wymaganą przez nas formę. W przykładzie za pomocą wyrażeń regularnych sprawdzamy, czy użytkownik wpisał prawidłowe imię:

Podaj imię (min. 3 znaki nie będące cyframi):

Sprawdzając rzeczy w formularzach warto mieć gdzieś z tyłu głowy zasadę "im mniej tym lepiej". Spójrz na powyższy kod. Zastosowaliśmy wyrażenie regularne /^[a-zA-Z ]{3,}$/g, co oznacza, że użytkownik może wpisać tylko litery małe/duże oraz spację. Niestety wyrażenie to nie uwzględnia polskich liter, nie mówiąc o innych znakach. Chcąc dobrze sprawiliśmy, że spora liczba użytkowników nie będzie mogła poprawnie wypełnić takiego formularza.

Dla pól typu number i date mamy też dwie mało znane właściwości. Pierwsza z nich - valueAsNumber - dla pól typu number zwraca wartość w postaci liczby, natomiast dla pól typu date zwraca czas Unixowy, czyli w milisekundach od 1 stycznia 1970. Ta druga właściwość dla pól date zwraca wynik w postaci daty. Druga to valueAsDate i zwraca wartość pola typu date w postaci daty, a nie tekstu. Do przetestowania tutaj.

Pola typu RADIO i CHECKBOX

Przyciski radiowe umożliwiają wybór tylko jednej opcji z pośród kilku.

Aby sprawdzić, czy dany radio jest zaznaczony, musimy sprawdzić jego właściwość checked:

Najczęściej jednak radio występują w grupach. Aby je obsłużyć musimy je pobrać i wykonać po nich pętlę sprawdzając wartość checked każdego z nich. Po natrafieniu na pierwszy zaznaczony, pętlę możemy przerwać, ponieważ w grupie o wspólnej nazwie nie może być kilku zaznaczonych radio.

Wybierz płeć mężczyzna kobietaWybrałeś płeć:


Pola checkbox są bardzo podobne w obsłudze do pól radio. Różnica tutaj jest taka, że w jednej grupie może być kilka zaznaczonych przycisków.

Wybierz owoce jagoda jabłko arbuz pomarańczaWybrałeś

Powyższy kod możemy też uprościć za pomocą funkcji filter:

Ciekawostką jest natomiast to, że dzięki Javascript dla checkboxów możemy ustawić trzecią, niedostępną z HTML opcję - czyli indeterminate, która oznacza pół zaznaczenie:

niezaznaczone zaznaczony prawie zaznaczony

Stan taki dość często wykorzystuje się w rozwijanych drzewkach, gdzie za pomocą checkboxów zaznaczamy jakieś elementy. Więcej na ten temat możesz dowiedzieć się tutajarrow-up-right.

Przykładowe zastosowanie może mieć postać:

wszystkie pączki ciastka cukierki obwarzanki

Pola typu SELECT

Żeby pobrać wybraną wartość z selekta, tak samo jak w przypadku innych pól posłużymy się tutaj wartością value.

Każdy selekt dodatkowo udostępnia nam jeszcze kilka dość ciekawych właściwości:

select.value
wartość pola

select.options

kolekcja elementów option

select.selectedOpitons

kolekcja wybranych opcji. Będzie zawierać 1 element, chyba, że selekt ma atrybut multiple

select.selectedIndex

indeks wybranego option

Nowy option dla selekta

Nowe elementy <option> spokojnie możemy robić tak samo jak inne elementy - czyli korzystając z funkcji createElement, ale możemy też skorzystać z konstruktora Option(text*, value*, defaultSelected*, selected*):

Spróbujmy to wykorzystać do stworzenia selekta, który będzie dynamicznie wypełniany opcjami z innego selekta. Gdy dany element option jest zaznaczony (selected), wówczas tworzymy w drugim selekcie nowy option, który ma tekst i value takie same jak dany element w pierwszym selekcie.

Jeżeli byśmy chcieli dodatkowo z lewego selekta usuwać przerzucone wartości, tuż po ich skopiowaniu elementy te powinniśmy usunąć - tak samo jak usuwamy każdy inny element na stronie.

Input type color

Input typu color służy do pobierania koloru. Jest to jeden z prostszych do obsługi inputów, bo wystarczy tutaj obsłużyć tylko zdarzenie change:

Nawet dla takiego prostego inputa mogą pojawić się "smaczki", którymi warto się zająć.

Po wybraniu koloru wrzucamy go do diva leżącego obok. Jeżeli jednak wybierzemy dość ciemny kolor, napis w divie będzie niewidoczny.

Możemy tutaj wykorzystać przepis z niezastąpionego StackOverflowarrow-up-right:

Najważniejszy jednak problem w przypadku tego typu inputów jest to, że elementy te nie zadziałają wszędzie. W przeglądarkach, które nie wspierają takiego pola w ich miejsce pojawi się zwyczajne pole tekstowe, do którego możemy wpisać dowolną wartość. W dzisiejszych czasach nie jest to dla wielu frontendowców problemem, bo tworzą swoje aplikacje tylko dla najnowszych przeglądarek. Ale nawet jeżeli dana przeglądarka wspiera takie pole, wcale nie oznacza to, że będzie to robić identycznie jak inne przeglądarki.

Z tego też powodu, dość często dla inputów stosuje się zewnętrzne pluginy, które nakładają na takie inputy odpowiednią funkcjonalność. W moich zakładkach znalazłem takie cudoarrow-up-right. Na ichniejszej stronie jest dokładnie jak tego użyć a i znajdują się odpowiednie dema.

Input typu RANGE

Ostatni na naszej liście input range to kolejne bardzo proste w obsłudze pole. Pole - jeżeli nie zależy nam na na ładnym wyglądzie i dodatkowych funkcjonalnościach, ponieważ autorzy zrobili to pole bardzo topornym i w sumie mało dopracowanym.

Dla pól range idealnym wydaje się reagować na zdarzenia typu change lub input. To pierwsze będzie odpalane gdy zmienimy wartość pola, a to drugie w czasie jej zmieniania:

change: Wartość pola:input: Wartość pola:

Jeżeli chodzi o zmianę wyglądu to można próbować działać samym CSSarrow-up-right, ale nie zawsze da to oczekiwane rezultaty. Można też posłużyć się odpowiednimi pluginami - np. tymarrow-up-right, tymarrow-up-right lub tymarrow-up-right.

Last updated