Jak zrobić formularz w HTML
Formularz to element <form> z polami i przyciskiem wysyłania. Każde pole potrzebuje name: to klucz, pod którym wysyłana jest wartość. Wypełnij formularz i naciśnij Send. Podgląd nigdzie niczego nie wysyła; pokazuje dokładnie to, co wysłałaby przeglądarka.
Poszczególne elementy:
actionto adres URL, pod który trafiają dane, amethodokreśla sposób (tutajpost).namena każdym polu. Jego wartość to to, co wpisał użytkownik.<label>nazywa każde pole na ekranie i dla czytników ekranu (patrz etykiety w HTML).requireditype="email"sprawiają, że przeglądarka sprawdza pola przed wysłaniem. Spróbuj wysłać formularz z pustym imieniem albo zabcjako adresem e-mail.- Przycisk wysyłania wysyła formularz. Naciśnięcie Enter w polu tekstowym też.
action i method: dokąd i jak trafiają dane
| Atrybut | Wartości | Domyślnie |
|---|---|---|
action | Dowolny adres URL | Adres URL bieżącej strony |
method | get, post, dialog | get |
enctype | application/x-www-form-urlencoded, multipart/form-data, text/plain | application/x-www-form-urlencoded |
Przy method="get" pola stają się query stringiem adresu URL: formularz wyszukiwania z name="q" przechodzi pod /search?q=blue+shoes. To dobre dla wyszukiwania i filtrów, bo wynik można zapisać w zakładkach i udostępnić. Przy method="post" pola trafiają do treści żądania i nie pojawiają się w pasku adresu ani w historii. Używaj POST do wszystkiego, co loguje, tworzy, zmienia lub usuwa, i do haseł.
Formularz z przesyłaniem plików (<input type="file">) potrzebuje method="post" i enctype="multipart/form-data", inaczej wysyłana jest tylko nazwa pliku. method="dialog" służy do formularza wewnątrz <dialog>: wysłanie zamyka okno dialogowe zamiast wysyłać żądanie.
Co jest wysyłane
Wysyłane są tylko pola z name i tylko wtedy, gdy nie są disabled. Naciśnij Submit i porównaj pola z tym, co wysyła formularz:
Formularz wysyła city, zip, source i action. Pole bez nazwy, wyłączone pole i niezaznaczony checkbox są pomijane. Ukryte pola są wysyłane, ale nigdy się nie wyświetlają, a przycisk wysyłania wysyła własne name i value, bo to on został użyty.
Grupowanie pól przez fieldset i legend
<fieldset> rysuje ramkę wokół powiązanych pól, a <legend> to jej podpis. Czytniki ekranu ogłaszają legend, gdy fokus wchodzi do grupy, dzięki czemu zestaw przycisków radio jak poniżej jest zrozumiały: "Delivery, Standard, przycisk radio".
disabled na fieldset wyłącza naraz każde pole w środku i żadne z nich nie jest wysyłane. Usuń go, a pola z opcjami prezentu staną się dostępne.
Wbudowana walidacja: required, pattern i spółka
Przeglądarki sprawdzają te atrybuty przed wysłaniem i pokazują komunikat przy pierwszym polu, które nie przejdzie:
| Atrybut | Sprawdza |
|---|---|
required | Pole nie jest puste (checkbox jest zaznaczony) |
type="email", type="url" | Wartość wygląda jak adres e-mail lub URL |
minlength, maxlength | Długość tekstu |
min, max, step | Zakres liczb i dat |
pattern | Cała wartość pasuje do wyrażenia regularnego |
:invalid i :valid stylizują pola według ich stanu. Zwykle lepsze jest :user-invalid: działa dopiero wtedy, gdy użytkownik zmieni pole i przejdzie dalej albo spróbuje wysłać formularz, więc pusty formularz nie otwiera się cały na czerwono.
Trzy rzeczy w pattern często zaskakują. Musi pasować do całej wartości (nie trzeba ^ ani $). Działa tylko wtedy, gdy pole nie jest puste, więc łącz go z required. A komunikat błędu przeglądarki jest ogólny, więc opisz format widocznym tekstem obok pola. Chrome i Firefox dodają do komunikatu tekst z title, ale łatwo go przeoczyć.
Aby wyłączyć sprawdzanie, na przykład podczas testowania walidacji na serwerze, dodaj novalidate do <form>. Pojedynczy przycisk wysyłania może je pominąć przez formnovalidate.
Walidacja w przeglądarce jest dla wygody użytkownika. Każdy może edytować stronę albo wysłać żądanie bez niej, więc serwer musi jeszcze raz sprawdzić każdą wartość.
Własne komunikaty z setCustomValidity
Gdy reguły nie da się zapisać jako atrybutu, np. "oba hasła muszą się zgadzać", ustaw komunikat z JavaScriptu. Pole z niepustym własnym komunikatem jest niepoprawne; pusty ciąg znaków znowu czyni je poprawnym:
Pole powtórzenia nie ma name, więc wysyłana jest tylko jedna kopia hasła.
Obsługa wysyłania w JavaScripcie
Aby wysłać formularz bez opuszczania strony, nasłuchuj submit, wywołaj preventDefault() i odczytaj pola przez FormData. Nasłuchiwanie submit zamiast click na przycisku łapie każdy sposób wysłania, łącznie z Enter, i działa dopiero po przejściu wbudowanej walidacji:
Object.fromEntries(new FormData(form)) zamienia pola w zwykły obiekt. Dla pól, które mogą mieć kilka wartości (checkboxy o tej samej nazwie, select z wyborem wielokrotnym), użyj zamiast tego formData.getAll('name'), bo obiekt zachowuje tylko ostatnią wartość.
Częste błędy
- Pola bez
name. Są po cichu pomijane w wysyłanych danych. - Placeholdery zamiast etykiet. Podpowiedź znika, gdy tylko użytkownik zacznie pisać. Użyj
<label>. <button>beztypeużywany do czegoś innego niż wysyłanie. W formularzu to przycisk wysyłający.- Formularz w formularzu. Zagnieżdżanie formularzy jest niepoprawne; przeglądarka ignoruje wewnętrzny znacznik
<form>. - Nasłuchiwanie
clickna przycisku wysyłania zamiastsubmitna formularzu. Wysłania klawiszem Enter zostaną pominięte. - Poleganie na walidacji przeglądarki po stronie serwera. Tam waliduj jeszcze raz.
- GET dla haseł. Trafiają do adresu URL, historii i logów serwera.
Najczęściej zadawane pytania
Jak zrobić formularz w HTML?
Otocz pola znacznikiem <form action="/signup" method="post">, nadaj każdemu polu name i <label>, a na końcu dodaj <button type="submit">. Po wysłaniu formularza przeglądarka wysyła każdą parę name=value pod adres z action.
Czym różni się GET od POST w formularzu?
method="get" (domyślne) umieszcza pola w adresie URL, jak w /search?q=shoes, co pasuje do wyszukiwania i filtrów, które powinno się dać zapisać w zakładkach. method="post" wysyła je w treści żądania, czego potrzebujesz przy logowaniu, rejestracji i wszystkim, co zmienia dane.
Dlaczego pole mojego formularza nie jest wysyłane?
Nie ma atrybutu name albo jest disabled. Wysyłane są tylko nazwane, włączone pola. Niezaznaczony checkbox lub przycisk radio też jest całkowicie pomijany.
Do czego służą fieldset i legend?
<fieldset> grupuje powiązane pola, a <legend> to podpis grupy. Czytniki ekranu ogłaszają legend, gdy fokus wchodzi do grupy, dzięki czemu grupa przycisków radio jest zrozumiała, a disabled na fieldset wyłącza każde pole w środku.
Jak zwalidować formularz w HTML bez JavaScriptu?
Użyj atrybutów: required, type="email", minlength, maxlength, min, max i pattern. Przeglądarka blokuje wysłanie i pokazuje komunikat przy pierwszym niepoprawnym polu. Zawsze waliduj też na serwerze, bo te sprawdzenia działają w przeglądarce użytkownika i da się je obejść.
Jak zapobiec przeładowaniu strony przez formularz?
Nasłuchuj zdarzenia submit formularza i wywołaj event.preventDefault(), a potem sam wyślij dane przez fetch: form.addEventListener('submit', (e) => { e.preventDefault(); fetch(form.action, { method: 'POST', body: new FormData(form) }); }).