Inteligentne pola formularzy ✅
W jaki sposób uprzyjemnić użytkownikom wypełnianie formularzy za pomocą natywnych API przeglądarki?
Formularze... nikt nie lubi formularzy 😒
Kto lubi wypełniać formularze? Często są za długie, a co gorsza czasami nawet nie wiadomo jak długie są, dopóki się ich nie wypełni. Najgorzej... 😒 Poza tego typu błędami w UXie, w jaki sposób możemy jako frontend developerzy ułatwić użytkownikom proces uzupełniania formularzy? Jest kilka prostych sposobów, a część z nich jest nawet natywnie zaimplementowana w przeglądarki i gotowa do użycia!
Autocomplete 💡
Mechanizm autouzupełniania pól w większości przeglądarek, które mają dostęp do naszych danych (Chrome & konto Google lub Safari & Apple ID) działa out of the box. Jest kilka rzeczy, na które warto zwrócić uwagę przy implementacji formularzy, aby ten mechanizm działał w pełni poprawnie.
Znaczenie mają tutaj oczywiście atrybuty name, type oraz autocomplete.
W standardowym formularzu logowania, gdzie mamy pole z type="email"
oraz type="password"
przeglądarka powinna bez problemu na podstawie adresu dopasować dane odpowiedniego konta.
Zazwyczaj w takim przypadku przeglądarka koloruje wypełnione pola na charakterystyczny jasnożółty kolor. Możemy zmodyfikować te style za pomocą pseudoselektorów: :autofill
/ :-webkit-autofill
.
Hasła 🔐
Warto pamiętać o tym, żeby w formularzu ustawiania nowego hasła dodać do inputów odpowiednio: autocomplete="new-password"
oraz autocomplete="current-password"
jeśli jest to wymagane w tym samym kroku. Pozwala to np. zadziałać mechanizmom generowania silnego hasła.
Kod jednorazowy 📲
Bardzo dużym ułatwieniem jest autouzupełnianie się kodu jednorazowego do dwuetapowej weryfikacji, np. przychodzącego w wiadomości SMS lub z aplikacji 2FA. W bardzo łatwy sposób możemy to zaimplementować za pomocą: autocomplete="one-time-code"
.
Dane adresowe 🏡
Adres (miejsce zamieszkania) jest bardzo częstym elementem wielu formularzy i siłą rzeczy wymaga uzupełnieniu wielu pól, takich jak: ulica, miasto, kod pocztowy itp.
Dlatego warto pamiętać o tym, aby w każdym polu uzupełnić atrybuty name
oraz autocomplete
, dzięki czemu może zadziać się magia✨ tego typu:
Problem z name 👤
Często występujący problem, jaki napotykam to niepoprawna obsługa pola name
, kiedy powinien zawierać on w sobie zarówno imię, jak i nazwisko użytkownika.
Domyślnie przeglądarki dla pola z name="name"
uzupełniają je nazwiskiem, ale czasami w mniej formalnych formularzach (np. formularz kontaktowy na blogu) możemy chcieć autouzupełniania samego imienia lub gdy nie rozdzielamy imienia i nazwiska na dwa osobne pola, to oczekujemy, że przeglądarka uzupełni nam pole imieniem i nazwiskiem. I bez większego problemu możemy to w pełni scustomizować na następujące sposoby:
autocomplete="given-name"
- imięautocomplete="full-name"
- nazwiskoautocomplete="name"
- imię i nazwisko
Karta płatnicze 💳
Przepisywanie danych z karty kredytowej lub debetowej również nie należy do najprzyjemniejszych czynności przy uzupełnianiu formularzy. Dzięki odpowiednim atrybutom można to jednak uprościć do kilku kliknięć, które uzupełnią wszystkie podstawowe dane i ręcznego uzupełnienia wyłącznie ostatniego pola z numerem CSV.
⚠️ Autouzupełnianie danych karty (ze względów bezpieczeństwa) w niektórych przeglądarkach wymaga, aby strona korzystała z certyfikatu SSL, dlatego może to nie działać przy standardowej konfiguracji serwera developerskiego na http://localhost
.
"Brudny i niepoprawny" 🧟♂️
Bardzo fajnym rodzajem podpowiedzi jest pokazywanie użytkownikowi na bieżąco, które pola są wypełnione prawidłowo, a które nieprawidłowo. Często walidacja formularzy odbywa się po stronie serwera i następuje dopiero po uzupełnieniu wszystkich pól wraz z ich wysłaniem. Z punktu widzenia wygody użytkownika nie jest to optymalne rozwiązanie, dlatego w miarę możliwości warto delegować część walidacji na frontend. W niektórych przypadkach może to być utrudnione ze względu na fakt, iż walidacja może wymagać informacji z bazy danych i implikuje to potrzebę wysyłki wielu requestów w tle. Jednak podział na walidację podstawową ("techniczną") po stronie klienta oraz zaawansowaną ("merytoryczną") po stronie serwera wydaje się dobrym kompromisem dla UXu oraz ilości pracy.
Walidacja po stronie klienta może sprawdzać, czy pole z hasłem zostało uzupełnione (required
) oraz czy dane są "technicznie" poprawne, tzn. czy mają odpowiednią długość, czy email jest stringiem w odpowiedniej formie (x...x@y..y.zz
) itp.
Wtedy walidacja na backendzie sprawdza już tylko takie rzeczy jak np. to czy istnieje użytkownik powiązany z danym adresem email, czy hasło jest poprawne itp.
Scenariusz taki pozwala wyeliminować część potencjalnych pomyłek usera już na etapie wprowadzania ich w przeglądarce, co wpływa pozytywnie na doświadczenia użytkownika oraz może ograniczyć obciążenie serwera.
Bardzo przydatny może okazać się pseudoselektor :invalid
, za pomocą którego możemy zmienić stylowanie np. elementu <input>
w przypadku, kiedy treść nie spełnia warunków tzw. constrain validation.
Problem z tym rozwiązaniem jest taki, że w większości przypadków początkowa wartość (pusta) będzie nieprawidłowa, a to powoduje, że po wejściu na formularz pola już będą oznaczone jako błędnie wypełnione, co bardziej może wprowadzać użytkowników w zakłopotanie, niż pomagać im wypełnić formularz.
Najczęściej ten problem rozwiązywało się przy pomocy JavaScriptu, dodając np. klasę .dirty
lub .touched
dopiero w momencie, gdy użytkownik wejdzie w interakcję i opuści pole formularza.
Istnieje też inne, uproszczone rozwiązanie w CSS, które w niektórych przypadkach może być wystarczające i warto je znać. Jest to wykorzystanie pseudoslektora :placeholder-shown
(element <input>
lub <textarea>
który "aktualnie wyświetla placeholder") oraz :not
i :focus
.
W sumie daje nam to selektor dla elementu, który jednocześnie nie jest poprawnie uzupełniony, nie jest pusty i nie jest aktywny.
Aby to rozwiązanie zadziałało we wszystkich współczesnych przeglądarkach element musi mieć ustawiony atrybut placeholder
z jakąkolwiek wartością, może być też pusty string " "
.
Edit 2023: Od listopada 2023 roku pseudoselektor :user-invalid
jest wspierany przez wszystkie wspólczesne przeglądarki. 🎉
Istnieje również pseudoselektor :user-invalid
, który łączy 3 powyższe w
jednym, niestety obecnie działa on tylko w nowych wersjach Firefox'a.
wsparcie przeglądarek: caniuse.com/mdn-css_selectors_user-invalid
Natywna walidacja kodów 🤖
Podczas wpisywania numerów takich jak PESEL czy NIP istnieje całkiem duże prawdopodobieństwo dokonania pomyłki w postaci literówki, którą bardzo ciężko dostrzec gołym okiem. Brzmi jak idealne zadanie dla komputera? 🖥 Tak, ale tego typu pola warto walidować na już na frontendzie. Dla przykładu weźmy sobie numer dowodu osobistego, np.: ASB123456
.
W pierwszej kolejności warto ustawić atrybut maxlength
na 9, aby uniemożliwić użytkownikowi wpisanie większej ilości znaków.
Numer dowodu osobistego ma zawsze następującą strukturę: 3x wielka litera + 6x cyfra. W bardzo łatwy sposób można dodać walidację takiego wzoru za pomocą atrybutu pattern
. Warto też pamiętać o uzupełnieniu atrybutu placeholder
.
Tego typu walidacja zapewne pozwoli uniknąć większości pomyłek, jednak tego typu numery zazwyczaj posiadają tzn. liczbę i sumę kontrolną. Dzięki temu za pomocą odpowiedniego algorytmu możemy obliczyć czy podany numer jest prawidłowy. Dodatkowo korzystając z języka JavaScript możemy ustawić treść wiadomości dla natywnego mechanizmu walidacji w danym środowisku.
Podsumowanie 📋
Przeglądarki do autouzupełniania mogą wykorzystywać różne atrybuty, takie jak name
, type
oraz autocomplete
, czasami może to być też id
lub tekst w przyporządkowanym elemencie <label>
, ale jeśli chcemy mieć nad tym kontrolę to najlepiej odpowiednio uzupełnić name
i autocomplete
. Kiedy formularz nie wykorzystuje dodatkowych, bardziej zaawansowanych narzędzi do walidacji, wciąż możemy w bardzo prosty sposób podnieść jakość wrażeń użytkownika, np. za pomocą pseudoselektora :invalid
czy metody setCustomValidity
.