wtorek, 7 lutego 2017

JavaScript: trochę szerzej o Constraint Validation

Dawno temu napisałem krótki post o Constraint Validation, który miał przedstawić koncepcję i wskazać kierunek dla czytelnika, który chciałby bliżej poznać ten mechanizm. Dziś drobne rozszerzenie do poprzedniego posta: JavaScript: użycie Constraints Validation czyli fajne dymki na polach. Postaram się rozszerzyć nieco myśli rozpoczęte w tamtym poście i opisać parę metod i zdarzeń, które warto znać chcąc stosować Constraint Validation we własnej aplikacji.

Powrót do podstaw

Na początek może mały krok wstecz zanim zaczniemy z tematem wędrować do przodu. Constraint Validation to mechanizm, który zagościł w przeglądarkach wraz z HTML 5. Element, który zdecydowanie był potrzebny zarówno nam - twórcom jak także użytkownikom. Opisałem go głównie w kontekście własnych walidatorów. Podstawowy przypadek użycia jest jednak znacznie prostszy i nie wymaga użycia JavaScript, a samego HTML. Walidacja po stronie klienta jest dostępna dla wielu typów pól i opiera się na wartościach w atrybutach. Jeśli więc masz do czynienia z typowym przypadkiem, nie ma potrzeby pisać logiki samemu, a wystarczy oprzeć się na tej wbudowanej w przeglądarkę.

Mamy więc na polach wejściowych (input) różne formy walidacji dostępne prosto z pudełka. Wystarczy odpowiednio skonfigurować pole. Trzeba tylko pamiętać, że nie każda walidacja jest dostępna na każdym typie pola. Dokładną listę można znaleźć na linkowanej już przeze mnie stronie na Wiki dla Developerów od Mozilli. Poniżej zamieszczą tą samą tabelę z tłumaczeniem:

atrybut typ pola możliwe wartości opis 'ograniczenia' powiązane
naruszenie
pattern text, search, url, tel, email, password Wyrażenie regularne języka JavaScript zgodne z ECMA Script 5 Wartość pola musi spełniać wyrażenie Pattern mismatch
min range, number poprawna liczba wartość musi być większa lub równa wartości atrybutu Underflow
date, month, week poprawna data
datetime, datetime-local, time poprawna data i czas
max range, number poprawna liczba wartość musi być mniejsza lub równa wartości atrybutu Overflow
date, month, week poprawna data
datetime, datetime-local, time poprawna data i czas
required dowolne pole, które może zostać oznaczone jako wymagane. Dodatkowo select i textarea atrybut 'logiczny', nie ma wartości Wartość musi być uzupełniona Missing
step date liczba dni - liczba całkowita Jeśli wartość atrybutu nie jest 'any', to wartość pola musi wynosić min + n * step, gdzie n jest nieujemną liczbą całkowitą Step mismatch
month liczba miesięcy - liczba całkowita
week liczba tygodni - liczba całkowita
datetime, datetime-local, time liczba sekund - liczba całkowita
range, number liczba całkowita
maxlength dowolne pole tekstowe i textarea nieujemna liczba całkowita liczba znaków nie może przekraczać wartości atrybutu Too long

Nie trudno zauważyć, że najbardziej elastycznym sposobem jest skorzystanie z atrybutu pattern. Problemem może być najwyżej złożoność wyrażeń regularnych i niemożliwość wykorzystania tej walidacji na polu textarea.

Co z przypadkiem niestandardowym?

No to teraz czas na krok naprzód. Jak opisywałem w poprzednim poście, walidację należy wykonać przy zmianie wartości na polu, ale jej wynik zostanie zaprezentowany użytkownikowi dopiero przy próbie wysyłki formularza. To nie do końca prawda. Jest to domyślne zachowanie - standardowy przypadek. Programista może jednak wywołać walidację w dowolnym momencie. Może to być szczególnie przydatne, gdy formularz nie jest wysyłany standardowymi metodami.

Pierwsza przydatna metoda to checkValidity(), która może zostać wywołana na dowolnym elemencie strony podlegającemu walidacji, w szczególności na formularzu. Wynikiem metody jest wartość logiczna wskazująca czy walidacja się powiodła czy nie. Metoda ta nie ma żadnych wyników dla użytkownika. Czyli możemy dzięki niej zmienić konfigurację elementów, czy wyświetlić wszystkie komunikaty w jednym miejscu.

Druga praktyczna metoda to reportValidity(), która ma prawie takie same właściwości co poprzednia checkValidity(), ale co ważne powoduje zaprezentowanie komunikatu błędu użytkownikowi. Gdzie można tego użyć? Przykładowo plugin jQuery AjaxForm nie wywołuje zdarzenia submit przy próbie wysyłki. Można do woli ustawiać komunikaty na polach, ale zostaną one zignorowane jeśli wysyłamy formularz korzystając z tej wtyczki. Wystarczy jednak zdefiniować callback beforeSubmit, na formularzy konfigurując AjaxForm, wywołać metodę reportValidity() i zwrócić jej wynik z callbacka, aby użytkownik został powiadomiony o walidacji jak przy zwykłym formularzu.

Pseudoklasy i zdarzenia

Ostatnia rzecz, którą prawie zupełnie pominąłem w poprzednim tekście to możliwość kontrolowania pola w zależności czy jest ono poprawne, czy nie na podstawie pseudoklas css i zdarzeń. O pseudoklasach napisałem ze 2 słowa, ale przyda się to zagadnienie nieco rozszerzyć. Po pierwsze pseudoklasy są ustawiane w momencie ustawienia na polu komunikatu. Gdy tylko wywołana zostaje metoda setCustomValidity(string), na podstawie wartości jej argumentu zostaje ustawiona pseudoklasa i może być zaaplikowany właściwy styl. Oznacza to, że w ten sposób można od razu dać znać użytkownikowi, że coś nie gra z wprowadzanymi danymi, albo nawet korzystając z odpowiednich 'trików', zaprezentować komunikat o błędzie.

Druga kwestia to zdarzenia. Na każdym polu, które zostaje podlega walidacji emitowane są dwa zdarzenia:

  • invalid - gdy walidacja się nie powiedzie
  • valid - gdy walidacja się powiedzie

To co trzeba o nich wiedzieć, to że w przeciwieństwie do pseudoklas te zdarzenia są emitowane tylko wtedy, gdy wynik walidacji jest prezentowany użytkownikowi. Czyli pojawią się albo w przypadku wysyłki formularza, lub w momencie wywołania metody reportValidity(). Można tych zdarzeń użyć, aby na przykład nadać polu lub kontenerowi właściwą klasę zgodną z frameworkiem CSS jakiego używamy.

Mam nadzieję że ten krótki tekst rzeczywiście pomoże komuś w zrozumieniu tego praktycznego mechanizmu jakim jest Custom Validity i pomoże również w rozwiązaniu problemów, przy stosowaniu go w niestandardowym flow.

Brak komentarzy:

Prześlij komentarz