betacode

Руководство AngularJS Validation

  1. Tổng quan
  2. ng-required
  3. ng-minlength, ng-maxlength
  4. ng-pattern
  5. ng-submitted
  6. ng-messages
  7. Кастомизированный Validation

1. Tổng quan

AngularJS предоставляет список Directive, который помогает вам валидировать (validate) информацию, введенную пользователем в поля (field) у Form.
ng-required
Настраивает required (требуемые) атрибуты для поля ввода.
ng-minlength
Настраивает minlength атрибута для поля ввода.
ng-maxlength
Настраивает maxlength атрибута для поля ввода. Настройка значение данного атрибута отрицательным числом или нечисловое значение, позволит пользователю вводить содержание любой длины.
ng-pattern
Настройка регулярного выражения (Regular expression), пользователь вводит содержание, которое должно совпасть (match) с данным выражением.
$pristine
(Примитивный статус) Возвращает true если пользователь еще не взаимодействовал control (Не касался или касался, но еще не изменял его ), в обратном случае возвращает false.
$dirty
Является отрицательным состоянием у $pristine. Точнее $dirty == !pristine. Возвращает true если пользователь поменял значение у control минимум один раз.
$touched
Возвращает true если пользователь касался (touched) данного control, и выходил из него минимум один раз. (Терялся focus минимум 1 раз)
$untouched
Является отрицательным состоянием уa $touched. Точнее $untouched == !touched. Возвращает true если пользователь ни разу не касался данного control, или касался но не выходил из него. (Ни разу не терял focus)
$error
Объект $error помещает все валидированные атрибуты (validation attributes) примененные к определенному элементу.
$valid
Возвращает true если содержание не валидировано.
$invalid
Возвращает true если содержание не валидировано.
$pristine
Элемент control имеет статус $pristine = true (Нетронутое состояние) если пользователь ни разу не касался его, или касался но не менял его. В обратном случае $pristine= false.
$dirty
$dirty это отрицательное у $pristine, или точнее $dirty == !$pristine. Элемент control имеет состояние $dirty = true если пользователь менял его хотя бы 1 раз. Если наоборот, то статус $dirty = false.
$touched & $untouched
Control имеет статус $untouched если пользователь ни разу не касался его, или касался но ни разу не выходил из него (Ни разу не терялся focus).
Напротив, control имеет статус $touched если пользователь касался его и выходил из него хотя бы 1 раз (Терялся focus хотя бы один раз).

2. ng-required

ng-required является атрибутом, который применяется к полю (field) ввода у Form чтобы запросить пользователя ввести содержание для данного поля.
<input ng-model="something" ng-required="true" />

<input ng-model="something" ng-required="someLogicExpression" />
Ниже является простой пример использования ng-required, оповещение ошибки отобразится если поле ввода не имеет содержания.
ng-required-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation - ng-required</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="ng-required-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-required</h3>
         <p>Enter Your Name:</p>

         <form name="myForm">
            Full Name <br/>
            <input type="text"
               name="myFullName" ng-model="fullName" ng-required ="true" />
            <span ng-show="myForm.myFullName.$invalid" class="error-msg">
            You must enter your Name.
            </span>
         </form>
      </div>
   </body>
</html>
ng-required-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.fullName = "";

});
Example 2:
Другой пример с ng-required, checkbox решает должен ли пользователь вводить данные в опредленное поле или нет.
ng-required-example2.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation - ng-required</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="ng-required-example2.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-required</h3>
         <p>Enter User Name:</p>
         <form name="myForm">
            <input type="checkbox" ng-model="autoName" /> Auto Name?
            <br/>
            User Name
            <br/>
            <input type="text"
               name="myUserName" ng-model="userName" ng-required ="!autoName" />
            <span ng-show="myForm.myUserName.$invalid" class="error-msg">
            Please Enter User Name.
            </span>
         </form>
      </div>
   </body>
</html>
ng-required-example2.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.autoName = false;
    $scope.userName = "";

});

3. ng-minlength, ng-maxlength

ng-minlength это атрибут применяющийся к полю ввода у Form чтобы определить минимальное количество символол, которое пользователь должен ввести в поле. Например ng-minlength = "3" значит пользователь должен ввести минимум 3 символа в данное поле. При этом ng-maxlength определяет максимальное количество символов, которое разрешается пользователю ввести в поле.
minmax-length-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="minmax-length-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-minlength, ng-maxlength</h3>
         <p>Enter Password:</p>

         <form name="myForm" action="" ng-submit="checkOnSubmit($event)">
            Password <br/>
            <input type="password"
               name="myPassword" ng-model="password"
               ng-minlength= "5" ng-maxlength= "10" ng-required="true"/>
               
            <span ng-show="myForm.myPassword.$invalid" class="error-msg">
                 Password must be minimum 5 and maximum 10 characters
            </span>
            <br/>
            <button type="submit" >Submit</button>
         </form>
      </div>
   </body>
</html>
minmax-length-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.password = "";

    // Show more error infos.
    function printErrorInfo() {
        console.log($scope.myForm.$error);
        if ($scope.myForm.$error.minlength) {
            console.log('$error.minlength? ' + $scope.myForm.$error.minlength[0].$invalid);
        }
        if ($scope.myForm.$error.maxlength) {
            console.log('$error.maxlength? ' + $scope.myForm.$error.maxlength[0].$invalid);
        }
    }

    $scope.checkOnSubmit = function(event) {
        if ($scope.myForm.$invalid) {
            alert("Something invalid!");

            printErrorInfo();

            // Cancel submit
            event.preventDefault();
            return false;
        }
        alert("All valid => Submit now!");
        return true;
    }

});

4. ng-pattern

ng-pattern определяет шаблон (pattern), чтобы гарантировать содержание введенное пользователем в Form должно подходить тому шаблону. Значение ng-pattern это регулярное выражение (Regular expression).
ng-pattern-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation ng-pattern</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="minmax-length-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-pattern</h3>
         <p>Enter Pin Code:</p>
         <form name="myForm" action="" ng-submit="checkOnSubmit($event)">
            Pin Code:<br/>
            <!-- Only Numbers Allowed, Maximum 5 Characters -->
            <input type="text" name="myPinCode" ng-model="pinCode" ng-pattern="/^[0-9]{1,5}$/" ng-required="true" />
            <span class="error-msg" ng-show="myForm.myPinCode.$error.required">Required!</span>
            <span class="error-msg" ng-show="myForm.myPinCode.$dirty && myForm.myPinCode.$error.pattern">
            Only Numbers Allowed, Maximum 5 Characters
            </span>
            <br/>
            <button type="submit" >Submit</button>
         </form>
      </div>
   </body>
</html>
ng-pattern-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) { 
    $scope.pinCode = "";
    // Show more error infos.
    function printErrorInfo() {
        console.log($scope.myForm.$error);
    }
    $scope.checkOnSubmit = function(event) {
        if ($scope.myForm.$invalid) {
            alert("Something invalid!");

            printErrorInfo();

            // Cancel submit
            event.preventDefault();
            return false;
        }
        alert("All valid => Submit now!");
        return true;
    }
});

5. ng-submitted

AngularJS 1.3 так же представляет новый property для Form это $submitted чтобы отобразить был ли когда-то Form был отправлен (submit) или нет.
<div ng-if="myForm.$submitted">
    <!-- show errors -->
</div>
ng-submitted-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation $sumitted</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="$submitted-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>$sumitted</h3>
         <p><a href="?refresh">Reset</a></p>
         <p style="color:blue;">Click Submit button to test $sumitted</p>
         <h3 style= "color:red;">$submitted = {{myForm.$submitted}}</h3>
         <!--
            (IMPOTANT!!) To test with $submitted
            You need to remove the action attribute in the FORM.

            novalidate: Disable browser default validation.
            -->
         <form name="myForm" ng-submit="myForm.$valid && doSubmitForm($event)" novalidate>
            <input type="text" name="myField1" ng-model="field1" ng-required="true"/>
            <span ng-show="myForm.myField1.$invalid" class="error-msg">Required!!</span>
            <br/>
            <button type="submit">Submit</button>
            <h4 ng-show="myForm.$submitted && myForm.$invalid" class="error-msg">
               Something invalid, please check and re-submit
            </h4>
         </form>
      </div>
   </body>
</html>
ng-submitted-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.field1 = "";

    $scope.doSubmitForm = function(event) {
        alert("OK: " + $scope.myForm.$submitted);
        // Code to Submit form!
    }

});

6. ng-messages

Валидирование (validate) Form всегда является сложным и трудным для понимания заданием в AngularJS. Поэтому AngularJS 1.3 представляет некоторые развития, в которых представляет еще 2 Directive: ngMessages & ngMessage.
Если control нуждается в валидировании (validate) во многих аспектах, вам нужно настроить много оповещений ошибок для каждого аспекта. В основном ваш code будет выглядеть как ниже и заключением является то, что он довольно длинный и недружелюбный.
<div>
    <div ng-if="myForm.myFieldName.$error.required">Required Message</div>
    <div ng-if="myForm.myFieldName.$error.minlength">Min length Error Message</div>
    <div ng-if="myForm.myFieldName.$error.customValidator">Custom Error Message</div>
    <div ng-if="myForm.myFieldName.$error.asyncValidator">Custom Async Error Message</div>
    <div ng-if="myForm.myFieldName.$pending">Fetching Data...</div>
</div>

<!-- Or -->

<div>
    <div ng-show="myForm.myFieldName.$error.required">Required Message</div>
    <div ng-show="myForm.myFieldName.$error.minlength">Min length Error Message</div>
    <div ng-show="myForm.myFieldName.$error.customValidator">Custom Error Message</div>
    <div ng-show="myForm.myFieldName.$error.asyncValidator">Custom Async Error Message</div>
    <div ng-show="myForm.myFieldName.$pending">Fetching Data...</div>
</div>
Лучшее решение это вам стоит использовать ng-messages & ng-message:
<div ng-messages="myForm.myFieldName.$error">
    <div ng-message="required">Required Message</div>
    <div ng-message="minlength">Min length Error Message</div>
    <div ng-message="customValidator">Custom Error Message</div>
    <div ng-message="asyncValidator">Custom Async Error Message</div>
    <div ng-message-default="asyncValidator">Some thing error</div>
</div>

<div ng-if="myForm.myFieldName.$pending">Fetching Data...</div>
Общий способ использования:
Usage
<!-- Using attribute directives -->
<!-- ng-messages-multiple: Optional attribute -->
<ANY ng-messages="expression" role="alert" [ng-messages-multiple]>
  <ANY ng-message="stringValue">...</ANY>
  <ANY ng-message="stringValue1, stringValue2, ...">...</ANY>
  <ANY ng-message-exp="expressionValue">...</ANY>
  <ANY ng-message-default>...</ANY>
</ANY>

<!-- Or by using element directives -->
<!-- multiple: Optional attribute -->
<ng-messages for="expression" role="alert" [multiple]>
  <ng-message when="stringValue">...</ng-message>
  <ng-message when="stringValue1, stringValue2, ...">...</ng-message>
  <ng-message when-exp="expressionValue">...</ng-message>
  <ng-message-default>...</ng-message-default>
</ng-messages>
Примечание: Чтобы использовать ngMessages вам нужна библиотека angular-messages.js:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-messages.js"></script>

<!-- Example: -->

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular-messages.js"></script>
И импортировать module "ngMessages" в ваш Apps.
// Import ngMessages module to your App.
var app = angular.module("myApp", ["ngMessages"] );
ng-messages-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <!-- angular-messsages.js Library -->
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular-messages.js"></script>
      <script src="ng-messages-example.js"></script>
      <style>
         .error-msg {
          font-size: 90%;
          font-style: italic;
          color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-messages, ng-message</h3>
         <p>Enter Password:</p>
         <form name="myForm" action="" ng-submit="checkOnSubmit($event)">
            Password <br/>
            <input type="password"
               name="myPassword" ng-model="password"
               ng-minlength= "5" ng-maxlength= "10" ng-required="true"/>

            <div ng-messages="myForm.myPassword.$error" ng-messages-multiple class="error-msg">
               <div ng-message="required">Required!</div>
               <div ng-message="minlength">Min length 5 characters</div>
               <div ng-message="maxlength">Max length 10 characters</div>
               <div ng-message="customValidator">Custom Error Message</div>
               <div ng-message="asyncValidator">Custom Async Error Message</div>
            </div>

            <br/>
            <button type="submit" >Submit</button>
         </form>
      </div>
   </body>
</html>
ng-messages-example.js
// Import ngMessages module to your App.
var app = angular.module("myApp", ["ngMessages"] );

app.controller("myCtrl", function($scope) {

    $scope.password = "";

    $scope.checkOnSubmit = function(event) {
        if ($scope.myForm.$invalid) {
            alert("Something invalid!");
            // Cancel submit
            event.preventDefault();
            return false;
        }
        alert("All valid => Submit now!");
        return true;
    }

});

7. Кастомизированный Validation

  • Custom AngularJS Validation