Jak stworzyć formularz logowania w AngularJS

Ostatnio na blogu pojawiały się głównie wpisy o programowaniu gier. Dziś czas na coś innego. W końcu nie samymi grami człowiek żyje 🙂 Tym razem pokażę jak stworzyć formularz logowania w AngularJS. O stosowaniu angulara pisałem już co nieco, wiedza z tamtych postów wystarczy aby zrozumieć jak działa kod dzisiejszego mini projketu. Skoro już mowa o kodzie, działający formularz wrzuciłem do paczki, którą umieściłem pod tym linkiem. Możecie go ściągnąć i pogrzebać na własną rękę 🙂

Jak stworzyć formularz logowania w AngularJS

Formularz sam w sobie nie wydaje się być sprawą skomplikowaną, wystarczy walnąć parę znaczników HTML i gotowe. Resztą zajmuję się serwer. To prawda, ale trzeba pamiętać, że już po stronie frontendu można zrobić kilka rzeczy, które ułatwią pracę serwerowi i znacznie podniosą jakość interakcji użytkownika z aplikacją. Dziś jest to standard!

To co należy zrobić już po stronie przeglądarki to walidacja wprowadzanych przez użytkownika danych. Jeżeli ma wpisać email, to aplikacja, nie powinna pozwolić wysłać ciągu znaków, który e-mailem nie jest. Po co obciążać serwer zapytaniami, zawierającymi nie nadające się dane. Do tego należy odpowiednio poinformować użytkownika, że wpisuje złe dane. Często, z różnych względów, użytkownicy nie zdają sobie sprawy z tego że coś robią nie tak.

W moim przykładzie formularz zawiera dwa pola, email oraz hasło. Pole email przyjmuje poprawnie wpisany email a pole hasło ciąg 6 znaków zawierający minimum jedną wielką literę, jedną małą oraz cyfrę. Jeżeli te warunki nie zostaną spełnione, nie będzie można wysłać formularza do serwera. Formularz również wyświetli odpowiednie komunikaty, gdy coś nie będzie się zgadzać, a pola input podświetlą się na czerwono. Zachęcam do ściągnięcia paczki z kodem i pobawienia się z aplikacją.

Stworzenie takiego formularza po stronie przeglądarki, nawet przy użyciu jQuery nie byłoby może trudne, ale na pewno było by kłopotilwe. Dzięki specjalnej obsłudze formularzy w AngluarJS, staje się to bardzo proste nawet dla mało doświadczonego developera. Oto kod HTML takiego formularza:

Jak widać, zakres aplikacji to cały dokument. Dyrektywę ng-app przypisuję do znacznika html i nadaję jej wartość angularForm. Jest to nazwa modułu obsługującego formularz. W znaczniku head ustawiam wszystkie niezbędne wartości oraz dodaję zewnętrzne pliki. Na początku oczywiście kod angulara, następnie mój plik controller.js, w którym zapisany jest kod JavaScript. Po JavaScripcie, dołączam także CSSy. Pierwszy to boostrap z zewnętrznego serwera, a drugi to mój własny arkusz. Nie będę opisywał cssów, ale polecam zajrzeć do tego pliku i popatrzeć co tam się dzieję. Szczególnie wykorzystanie specjalnych klas nadawanych elementom przez angular.

Do elementu body dodaję dyrektywę ng-controller. Mój kontroler o nazwie równej wartości tej dyrektywy, będzie miał zakres obejmujący cały kod wewnątrz tego znacznika. Kolejny element który jest ważny to form. Posiada on pokaźną ilość atrybutów.

Na początek powiem o novalidate, który nie ma wpisanej żadnej wartości. HTML5 posiada własną prostą walidację formularzy, niestety w różnych przeglądarkach, różnie działa przez co nie można za bardzo na niej polegać. Atrybut novalidate deaktywuje tę walidację. Ja i tak będę walidować formularz za pomocą angulara. Kolejny ważny atrybut to name. Angular będzie odnosił się do tego formularza właśnie poprzez wartość atrybutu name. Chcę jeszcze zwrócić uwagę na dwie dyrektywy ng-hide oraz ng-submit. Pierwsza spowoduje, że formularz zostanie ukryty gdy zmienna obiektu $scope kontrolera o nazwie correctLogIn będzie równa true. Druga dyrektywa, wywoła funkcję submitData po kliknięciu przycisku submit formularza.

Kolejny element, na który należy zwrócić uwagę to input. Jest to pole tekstowe do którego użytkownik, wpisywać będzie adres email. Pierwsza ważna rzecz to atrybut reqired, oznacza on, że pole to jest wymagane aby formularz mógł być wysłany. Druga ważna rzecz to dyrektywa ng-pattern.. Wartość, którą przyjmuje to wyrażenie regularne. Tekst wpisany do pola, nie zostanie uznany, za poprawny, jeżeli nie będzie zgadzał się z tym wyrażeniem regularnym. Ostatnia dyrektywa to ng-model, jej działanie powinno być już znane. Powoduje ona, że tekst wpisany do pola, staje się wartością zmiennej obiektu scope o nazwie równej wartości dyrektywy. I w drugą stronę, zmiana wartości zmiennej, zmieni tekst wyświetlany w polu.

Pod elementem input odpowiadającym za email, znajduje się div, który z kolei zawiera dwa elementy span. div ten dzięki dyrektywie ng-show widoczny będzie jeżeli zostaną spełnione dwa warunki. Pierwszy warunek to zmienna $invalid musi być true. $invalid to specjalna zmienna w angularze, która oznacza, czy wartość dodana do pola input w formularzu, jest poprawna. Ale skąd wiadomo o jaki input chodzi. Angular znajduje te pola po wartościach ich atrybutów name. Oznacza to, że angularForm.email.$invalid wszkazuje na poprawność pola o nazwie email w formularzu angularForm. Wiadomo już o co chodzi z pierwszym warunkiem ng-show. Drugi wygląda tak angularForm.email.$dirty. Widać, że wskazuje na to same pole. ale co to za zmienna $dirty? W angularze, wszystkie pola formularza, posiadają właściwosći $dirty oraz $pristine. Na początku ta pierwsza równa jest false, a ta druga, true. Sytuacja zmienia się w momencie, kiedy użytkownik wejdzie w interakcje z polem. Wtedy wartości obracają się $dirty wynosi true a $pristine false. Wracając do diva, ukaże on się, jeżeli pole będzie zawierać niepoprawne dane i jeżeli będzie „dotknięte” przez użytkownika.

div ten zawiera dwa elementy span, które ponownie dzięki dyrektywie ng-show, widoczne są tylko pod pewnymi warunkami. Warunki te wyglądają tak angularForm.email.$error.pattern oraz angularForm.email.$error.required. Po raz kolejny chodzi o pole email w formularzu angularForm. Zmienna $error, to jeszcze jedna specjalna wartość przypisana do pól tekstowych przez angular. Wynosi ona true, gdy pole zawiera niepoprawne dane. Co ciekawe, można dokładnie wskazać na to, co wywołało błąd. Zmienna $error posiada własne pola, które ustawione są na true, jeżeli reprezentujące je właściwości są niepoprawne. Ok, może to brzmi dziwnie, ale na przykładzie powinno być widać o co chodzi. Zwrot angularForm.email.$error.pattern oznacza błędne dane, które nie zgadzają się wzorem (zdefiniowanym w dyrektywie pattern przy polu input). Natomiast angularForm.email.$error.required oznacza, że pole jest puste (a nie powinno bo jest wymagane [required]). Mam nadzieję, że ma to sens :). Dla mnie najważniejsze jest to, że mogę wyświetlić użytkownikowi odpowiedni komentarz (zawartość elementu span), dopasowany, do błędu jaki popełnił. Dzięki temu użytkownik będzie wiedział co musi poprawić 🙂

Kolejny input to pole, które przyjmuje hasło od użytkownika. Działają tu dokładnie te same mechanizmy jak w poprzednim polu, więc nie będę ich opisywał. Jedyna nowość to dyrektywa ng-minlength. Oznacza ona, że wartość wpisana do pola, musi mieć przynajmniej tyle znaków ile wynosi wartości dyrektywy. W tym wypadku sześć. Jeżeli warunek ten nie zostanie spełniony, pole będzie oznaczone jako niepoprawne.

Ostatni element input różni się od dwóch poprzednich, ponieważ nie jest to pole do wprowadzania tekstu a przycisk submit. Po naciśnięciu tego przycisku, formularz zostanie wysłany. W tym przypadku jednak, jak zaznaczyłem wcześniej, zostanie również wywołana funkcja przypisana do dyrektywy ng-submit, która pojawia się w głównym elemencie formularza, form. Jedna rzecz na którą warto zwrócić uwagę w przypadku przycisku submit to dyrektywa ng-disabled. Jeżeli wartość tej dyrektywy będzie równa false, przycisk będzie nieaktywny. Wartość ta równa jest angularForm.$invalid. Jak łatwo się domyślić, $invalid to specjalna zmienna, którą angular przypisuje do formularza. Jest ona równa true, dopóki, choć jedno pole w formularzu jest niepoprawne. Idealnie, dokładnie to czego potrzebuję. Użytkownik nie może wysłać treści formularza do serwera, dopóki pola nie będą uzupełnione poprawnie.

Na końcu dokumentu html pojawiają się jeszcze trzy elementy, zawierające informacje, które pojawią się w zależności od tego co zwróci serwer.

Teraz czas spojrzeć na zawartość pliku controller.js, który zawiera kod JavaScript tej aplikacji.

Spora część mechanizmów obsługujących formularz pojawiła się w samym kodzie HTML, tutaj zostały już tylko zmienne pomocnicze i funkcja odpowiedzialna za kontakt z serwerem.

Na początek oczywiście deklaruje moduł, do którego następnie dodaje kontroler. W funkcji kontrolera jako argument pojawia się nie tylko standradowy $scope ale też obiekt $http, jest on potrzebny do wywołań ajax.

Następnie do obiektu &scope dodaję parę pól, które przechowywać będą zmienne, używane w dyrektywach formularza. emailPattern oraz passPattern to wyrażenia regularne, do których porównywane są treści pól. Jeżeli nie znasz wyrażeń regularnych, polecam nauczenie się tego mini języka. Przyda Ci się na pewno, a jeżeli myślisz poważnie o programowaniu, to jest to wręcz niezbędne. Nie będe dokładnie objaśniał każdego wyrażenia, powiem tylko, że emailPattern zawiera jeden znak małpy i jedną kropkę a passPattern jedną wielką literę, jedną małą i liczbę. Czyli dokładnie to co potrzebowałem.

Zmienna user to obiekt, który (dzięki dyrektywom ng-model) przechowywać będzie wartości zapisane w polach formularza.

Zmienne correctLogin, incorrectLogin oraz serverProblem, służą do kontrolowania jaki komunikat pokaże się po wysłaniu formularza do serwera. Początkowo wszystkie ustawione są na false. Co oznacza, że żaden komunikat nie będzie wyświetlany.

W następnej kolejności pojawia się metoda obiektu $scopesubmitData. Ta metoda wywoływana jest w momencie, gdy użytkownik naciśnie przycisk submit. Jako parametr, otrzymuje specjalny obiekt angulara $event, który służy do obsługiwania zdarzeń (w tym wypadku zdarzenia submit). Wykorzystuje go na końcu funkcji, wywołując jego metodę preventDefault. W ten sposób zatrzymuje domyślne zdarzenie submit.

Sama funkcja submitData jest bardzo prosta, zakłada, że serwer zwraca zmienną valid która jest równa true, jeśli dane do logowania są poprawne, i false, jeśli są nieprawidłowe (np taki email nie istnieje w bazie, lub hasło się niezgadza). Najpierw tworzę obiekt dataObj, który posiada dwa pola z zawartością równą temu co użytkownik wpisał w pola formularza (pola są na pewno wypełnione, inaczej użytkownik, nie mógłby nacisnąć submit i wywołać tej funkcji 😉 ). Kolejny obiekt to request. Zawiera on konfiguracje dla wywołania ajaxowego. Posiada trzy pola: method, url oraz data. method to metoda z jaką ma być wykonane połącznie. W tym wypadku POST ponieważ, jest bezpieczniejsza a ja przekazuje wrażliwe dane (hasło użytkownika). Pole url to adres serwera, a pole data to dane, które mu wysyłam. W tym wypadku dane to oczywiście mój obiekt dataObj.

Każdy obiekt wysłany w ten sposób przez angular jest automatycznie zamieniany na format JSON.

Następna część kodu to definicja funkcji obiektu $http. Obiekt ten jako parametr przyjmuje obiekt konfigurujący a funkcje przypisywane są do dwóch jego pól success oraz error. Funkcja przypisana do success wykona się jeżeli połączenie z serwerem uda się a funkcja przypisana do error w przeciwnym wypadku.

Teraz to już tylko kwestia prostego manipulowania polami obiektu $scope, odpowiedzialnymi za wyświetlenie odpowiedniego komunikatu na stronie. Jeżeli serwer zwróci zmienną valid o wartości równej true, pole correctLogin ustawiam na true, w przeciwnym wypadku na true, ustawione zostaje pole incorrectLogin. wywołanie funkcji przypisanej do error obietku $http oznacza, że połączenie się nie udało i na true ustawione zostaje pole serverProblem. Oczywiście ‚czyszczę’ wartości wszystkich pól które mogły wcześniej powodować wyświetlenie innych komunikatów. Wywołuję też funkcję clearForm, która czyści treść pól formularza, przygotowując go na ewentualną kolejną próbę logowania.

I to wszystko! Tak jak pisałem, z Angularem, tworzenie interaktywnych formularzy z porządną walidacją jest bardzo proste. Jeżeli chcesz być na bieżąco z postami dotyczącymi Angulara i tworzenia aplikacji po stronie front endu, zachęcam do polubienia mojej strony na facebooku. Jest ona bardzo często uaktualniana o najświeższe informacje.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *