angularjs - formularze

AngularJS – Formularze

Podziel się ze znajomymi

Ten wpis będzie o tworzeniu formularzy, wykorzystując framework AngularJS.  Prosta aplikacja, zbudowana na bazie dwóch komponentów posłuży nam do zademonstrowania, w jaki sposób powinniśmy tworzyć i walidować formularze, powszechnie wykorzystywane w tworzonych systemach webowych.

Część teoretyczna

Aplikacje internetowe wykorzystują formularze do wprowadzania danych, zatem są ważną częścią aplikacji. Walidacja wprowadzanych danych przez użytkowników powinna się odbywać zarówno po stronie klienta, jak również serwera. Aby ominięcie zabezpieczeń w aplikacji klienckiej nie spowodowało problemów po stronie serwera.

AngularJS umożliwia nam obsługę formularzy na podstawie HTMLowego znacznika <form>, a także za pomocą dyrektywy Angularowej ngForm. Utworzona dyrektywa przez twórców frameworka, daje nam możliwość obsługi zagnieżdżonych formularzy. Zarówno wykorzystanie znacznika, jak i dyrektywy daje nam dostęp do obiektu powiązanego z danym formularzem. Obiekt ten przechowuje informacje wykorzystywane do walidacji. Abyśmy mogli korzystać z tego obiektu, należy do znacznika <form> lub <ng-form> dodać atrybut name.

Pola obiektu

$pristine – wartość typu boolean jeśli formularz nie został zmieniony zwracana wartość true, po zmianie któregokolwiek pola wartość zostaje zmieniona na false.
$dirty – wartość typu boolean to odwrotność pola $pristine, zatem jeśli pole nie zostało zmienione zwraca wartość false, po zmienie minimum jednego pola wartość zostaje zmieniona na true.
$valid – wartość typu boolean zwraca wartość true, jeśli wszystkie pola formularza zostały poprawnie wypełnione, w przeciwnym wypadku zwracana wartość to false.
$invalid – wartość typu boolean zwraca odwrotność pola $valid.
$submitted – wartość typu boolean zwraca true, jeśli użytkownik wysłał formularz, w przeciwnym wypadku wartość tego pola to false.
$error – wartość typu Object odwołuje się do pól, które nie przeszły poprawnie walidacji.

Pola tego obiektu dają nam możliwość zweryfikowania wprowadzonych danych przez użytkownika.

Przykładowa aplikacja

Na potrzeby tego wpisu przygotujemy aplikację, która będzie zbudowana z dwóch komponentów. Pierwszy z nich odpowiada za wprowadzanie danych, drugi zaś za wyświetlanie wcześniej wprowadzonych danych.

index.html

<!DOCTYPE html>
<html lang="pl" ng-app="app">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>AngularJS #10</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
        crossorigin="anonymous">

    <style>
        .panel-default {
            margin-top: 2em;
            padding: 1em;
        }

        .btn {
            width: 100%
        }

        .control-form {
            width: 100%
        }

        .inupt-text {
            margin-bottom: 1em;
            width: 100%;
        }

        .error {
            color: red;
        }
    </style>

</head>

<body ng-controller="appController as appCtrl">

    <div class="row">
        <div class="col-md-4 col-md-offset-4 panel panel-default">
            <form-register register="appCtrl.register" ng-if="!appCtrl.register.formCheck"></form-register>
            <register-profil data="appCtrl.register" ng-if="appCtrl.register.formCheck"></register-profil>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.2.1.slim.js" integrity="sha256-tA8y0XqiwnpwmOIl3SGAcFl2RvxHjA8qp0+1uCGmRmg="
        crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>

    <script>
        var app = angular.module("app", []);

        app.controller('appController', function () {
            var ctrl = this;
            ctrl.register = {};
            ctrl.register.formCheck = false;
        });

        app.component('formRegister', {
            templateUrl: 'formRegister.html',
            bindings: {
                register: '='
            },
            controller: formRegisterController
        });

        app.component('registerProfil', {
            templateUrl: 'registerProfil.html',
            bindings: {
                data: '<'
            }
        });

        function formRegisterController() {
            var ctrl = this;
            ctrl.submit = function () {
                ctrl.register.formCheck = true;
            }
        }
    </script>
</body>
</html>

 

formRegister.html

<div>
    <h1 class="text-center">Register</h1>
    <form name="formReg">
        <div class="form-group">
            <label for="mail">Email address</label>
            <label class="error" ng-show="formReg.registerEmail.$touched && formReg.registerEmail.$invalid">Correct the e-mail address</label>
            <input type="email" class="form-control" id="mail" placeholder="Email" name="registerEmail" ng-model="$ctrl.register.email"
                required>
        </div>
        <div class="form-group">
            <label for="passwd">Password</label>
            <label class="error" ng-show="formReg.registerPasswd.$touched && formReg.registerPasswd.$invalid">Please correct the password</label>
            <input type="password" class="form-control" id="passwd" placeholder="Password" name="registerPasswd" ng-model="$ctrl.register.passwd"
                required>
        </div>
        <div class="form-group">
            <label for="rpasswd">Repeat password</label>
            <label class="error" ng-show="formReg.registerRPasswd.$touched && formReg.registerRPasswd.$invalid">The repeated password doesn't match</label>
            <input type="password" class="form-control" id="rpasswd" placeholder="Repeat password" name="registerRPasswd" ng-model="$ctrl.register.rpasswd"
                required>
        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox" ng-model="$ctrl.register.conditions" name="registerCond" required> I agree to terms and conditions
            </label>
        </div>
        <button type="submit" class="btn btn-default" ng-click="$ctrl.submit()" ng-disabled="formReg.$invalid || $ctrl.register.passwd !== $ctrl.register.rpasswd">Register</button>
    </form>
</div>

 

registerProfil.html

<h1 class="text-center">Zarejestronwano</h1>
<p>
    <strong>Emial: </strong>{{$ctrl.data.email}}
</p>
<p>
    <strong>Password: </strong>{{$ctrl.data.passwd}}
</p>
<p>
    <strong>Accepted Conditions: </strong>{{$ctrl.data.conditions}}
</p>

 Aplikacja składa się z 3 plików: index.html zawiera kod html strony głównej, a także obsługę AngularJSformRegister.html którego zadaniem jest przechowywanie kodu html komponentu <form-register> odpowiedzialnego za wprowadzanie danych oraz registerProfil.html, który odpowiada za przechowywanie kodu html komponentu <register-profil>, którego zadaniem jest wyświetlanie wprowadzonych danych w formularzu przez użytkownika.

Omówienie index.html

Przejdźmy do omówienia tego co dzieje się w naszej aplikacji. Na początku tworzymy w pliku index.html moduł naszej Angularowej aplikacji. Następnym krokiem jest utworzenie kontrolera naszej aplikacji, którego zadaniem będzie przechowywanie danych i przekazywanie ich do utworzonych przez nas komponentów.

ctrl.register = {};
ctrl.register.formCheck = false;

Kontroler ten zawiera obiekt register, do którego będą przekazywane dane z formularza, a także pole w tym obiekcie formCheck, wykorzystywane do sprawdzenia warunków wyświetlania utworzonych przez nas komponentów.

Kolejnym krokiem jest utworzenie komponentów. Pierwszym jaki tworzymy jest formRegister. O tworzeniu komponentów można przeczytać w jednym z wcześniejszych wpisów AngularJS – Component. Za pomocą templateUrl ustawiamy szablon html komponentu, bindings odpowiada za określenie przekazywanych danych, zaś ostatnie pole obiektu konfiguracyjnego przypisuje komponentowi kontroler, odpowiedzialny za wykonywanie operacji na danych.

ctrl.register.formCheck = true;

W przypisanym kontrolerze mamy utworzoną funkcję submit(), odpowiedzialną za zmianę wartości pola formCheck obiektu register.

W podobny sposób tworzymy komponent wykorzystywany do wyświetlania wprowadzonych danych przez użytkownika. Określamy szablon html, a także przekazywane dane do komponentu.

Omówienie formRegister.html

Przejdźmy teraz do pliku formRegister.html, bo tu dzieje się najwięcej.

<form name="formReg">

Do znacznika <form> dodajemy atrybut name, dzięki któremu będziemy mogli się odwoływać do obiektu opisanego powyżej.

Następnie mamy 4 kontrolki oraz przycisk odpowiedzialny za wysłanie danych.

<div class="form-group">
    <label for="mail">Email address</label>
    <label class="error" ng-show="formReg.registerEmail.$touched && formReg.registerEmail.$invalid">Correct the e-mail address</label>
    <input type="email" class="form-control" id="mail" placeholder="Email" name="registerEmail" ng-model="$ctrl.register.email"
        required>
</div>

Zacznijmy omawianie pierwszego elementu formularza od końca, czyli od znacznika <input>. Mamy określony atrybut type, który jest odpowiedzialny za sprawdzanie czy podany ciąg znaków jest adresem email. Przypisanie klasy css za pomocą atrybutu class. Kolejne atrybuty to: id oraz placeholder. Atrybut name w danym polu wykorzystywane jest do walidacji tego pola. ng-model odpowiada za wiązanie dwukierunkowe danych.

Po określeniu inputu możemy przystąpić do wyświetlania komunikatu o błędzie. Do tego wykorzystywany jest znacznik <label> z klasą error. Najważniejsza tutaj jest dyrektywa ng-show, która to określa warunek, kiedy ma zostać wyświetlony komunikat. Pojawia się jeśli pole zostało naciśnięte, ale obecnie jest już opuszczone i pole nie jest poprawnie wypełnione.

Jak możemy zauważyć, mamy tutaj zaprezentowany schemat odwoływania się do pól sprawdzających pole formularza. Schemat ten wygląda następująco:

nazwa_formularza._nazwa_pola.$pole_obiektu

W podobny sposób zrealizowane są kolejne pola formularza. Kolejną walidację mamy przy przycisku. Sprawdzamy tam, czy formularz został wypełniony prawidłowo, jeśli tak umożliwiamy wysłanie go na serwer.

<button type="submit" class="btn btn-default" ng-click="$ctrl.submit()" ng-disabled="formReg.$invalid || $ctrl.register.passwd !== $ctrl.register.rpasswd">Register</button>

Odpowiada za to dyrektywa ng-disabled, która ma możliwość łączenia warunków jedynie za pomocą spójnika lub ||. Sprawdzamy tutaj czy wszystkie pola zostały wypełnione, a także czy hasło oraz powtórzone hasło są różne. Jeśli któryś z warunków jest spełniony, blokowana jest możliwość przesłania formularza.

Szablon dla komponentu registerProfil to proste wyświetlanie danych przekazanych jako atrybut komponentu.

Efekt działania aplikacji

anuglarjs - formularze -form

anuglarjs - formularze -view

 

Podsumowanie

Stworzona przez nas aplikacja prezentuje sposób tworzenia i sprawdzania poprawności wprowadzonych danych przez użytkownika przy pomocy AngularJS. Jak widzimy, walidacja formularzy z wykorzystaniem frameworka jest bardzo prosta i przejrzysta. To kolejny krok postawiony w nauce tej biblioteki. W kolejnych wpisach zajmiemy się dalszymi elementami wykorzystywanymi podczas pisania aplikacji.

Dodaj komentarz

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