Form Validation trong Angularjs và ng-messages

Trong bài viết lần này mình sẽ đề cập tới Form Validation trong Angularjs. Trong AngularJs cung cấp cho chúng ta các phương thức validate như : require, min, max, minlength, maxlength, pattern... Ngoài ra nó cũng cho chúng ta tạo ra các validate cho chính mình.

Đầu tiên chúng ta tìm hiểu Directive Form trong Angularjs trước đã.

1, Form là để lấy thông tin người dùng, khi người dùng thao tác nhập dữ liệu và submit form lên sever. Directive Form có nghĩa là khi tất cả ràng buộc bên trong form hợp lệ thì mới submit form được. Và nó sẽ có các directive trong các thẻ input:

  • ng-valid nếu Form hợp lệ.
  • ng-invalid nếu Form không hợp lệ.
  • ng-pristine nếu form chưa có thao tác nào (chưa thay đổi nội dung trong FORM).
  • ng-dirty nếu Form đã có thao tác (có thay đổi nội dung trong FORM).
  • ng-submitted nếu Form đã submit.
  • ng-error: lỗi trong form khi người dùng nhập sai.

2, Form Validation

Bỏ qua các bước thêm thư viện css, angularjs. mình bắt đầu luôn tạo 1 file register.html là form đăng ký tài khoản người dùng index.html

<div ng-app="formValidation" ng-controller="registerCtr">
  <form id="register-form" class="form-horizontal" name="form" ng-submit="register()" novalidate >

    <div class="form-group">
      <label for="email" class="col-xs-3 control-label">Email</label>
      <div class="col-xs-9">
        <input name="email" class="form-control"
          placeholder="Email" ng-model="email" autocomplete="off" required>
      </div>
    </div>

    <div class="form-group">
      <label for="password" class="col-xs-3 control-label">Password</label>
      <div class="col-xs-9">
        <input name="password" ng-model="password" type="password"
          placeholder="Password" required>
      </div>
    </div>

     <div class="form-group">
       <label for="username" class="col-xs-3 control-label required">Name</label>
       <div class="col-xs-9">
         <input name="username" type="text" class="form-control"
           placeholder="Name" ng-model="username">
       </div>
    </div>

    <div class="form-group">
      <div class="col-sm-offset-3 col-xs-9">
        <button type="submit" class="btn btn-primary" >Register<i class="fa fa-sign-in"></i></button>
      </div>
    </div>
  </form>
</div>

bước thứ 2 ta thêm thuộc tính novalidate vào form tag. Để chúng ta tắt tính năng check validate của trình duyệt tránh trùng lặp và gây xung đột giữa angularjs và HTML5 thêm ng-submit="register()" để submit form khi thực thi <form novalidate ng-submit="register()">

tiếp theo bước 3 ta sẽ xét validate: require, min, max, minlength, maxlength, pattern...

#required: điều kiện bắt buộc phải nhập
<input name="username" type="text" class="form-control"
  placeholder="Name" ng-model="username" required ng-maxlength="10">

#ng-pattern: check regular expression
<input name="email" class="form-control" placeholder="Email" ng-model="email" autocomplete="off"
  required ng-pattern="/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-][email protected][a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/">

#ng-minlength: nhập lớn hơn 7 ký tự
<input name="password" ng-model="password" type="password"
  placeholder="Password" required ng-minlength="8">
....

Cụ thể chúng ta có các thuộc tính validation của input như sau:

<input
  ng-model="string"
  [name="string"]
  [required="string"]
  [ng-required="boolean"]
  [ng-minlength="number"]
  [ng-maxlength="number"]
  [ng-pattern="string"]
  [ng-change="string"]
  [ng-trim="boolean"]>
...
</input>

Vậy là chúng ta đã validate các trường trong form đăng ký. Giờ chúng ta sẽ show câu thông báo lỗi tương ứng với các trường hợp

Như nói ở trên ta có $dirty: check khi form thay đổi nội dung và $invalid khi người dùng nhập sai. Chúng ta sẽ check khi $dirty && invalid? = true thì sẽ hiển thị thông báo lỗi, và $dirty && $valid sẽ là thoải mãn validate của form. Khi có lỗi sẽ sử dụng $error để kiểm tra lỗi là nhằm show messages chính xác với lỗi.

VD:

  <div class="form-group">
     <label for="username" class="col-xs-3 control-label required">Name</label>
     <div class="col-xs-9">
       <input name="username" type="text" class="form-control"
         placeholder="Name" ng-model="username" required ng-maxlength="10">
       //khi thỏa màn điều kiện
       <i class="fa fa-check text-success" ng-show="form.name.$dirty && form.name.$valid">
       </i>

       <div ng-show="form.password.$dirty && form.password.$invalid" class="text-danger">
         <i class="fa fa-times text-danger"></i>
         <span ng-show="form.name.$error.required">
           Name Required
         </span>
         <span ng-show="form.name.$error.maxlength">
           Name is less than 10
         </span>
       </div>
     </div>
  </div>

..... Tương tự với các trường khác.

angular.module("formValidation")
  .controller("registerCtr", registerCtr);
register.$inject = [$scope]
function registerCtr($scope) {
  $scope.register = function() {
     alert("Register Successfully")
 }
}

3, Custom directive for ng-message

Nhiều khi dùng form directive không đủ để bắt hết các validate phức tạp. Ví dụ như password confirmation kiểm tra khi password có giống nhau không?

Như vậy chúng ta không thể dùng form để validate được nữa. Giải pháp hiện là sẽ dùng ng-messages của angularjs nhằm hiển thị ra error

ng-messages là 1 directive nhằm hỗ trợ cho validate form

để sử dụng ng-messages ta cần import thư viện https://docs.angularjs.org/api/ngMessages vào trong HTML.

Sau đó add vào module angular.module('app',['ngMessages])

Vẫn form đăng ký ở trên. Mình sẽ tạo thêm 1 file : messages_error.html như sau:

<div class="messages">
  <div ng-message="required">Required</div>
  <div ng-message="minlength">Too short</div>
  <div ng-message="maxlength">Too long</div>
  <div ng-message="email">Invalid email address</div>
  <div ng-message="compareTo">Must match the previous entry</div>
</div>

ở index.html mình sẽ thay phần hiển thị lỗi bằng

<div ng-messages="form.name.$error" ng-messages-include="messages_error.html"></div>
<div ng-messages="form.email.$error" ng-messages-include="messages_error.html"></div>
<div ng-messages="form.password.$error" ng-messages-include="messages_error.html"></div>
<div ng-messages="form.passwordConfirmation.$error" ng-messages-include="messages_error.html"></div>

đó là cách thứ 2 sử dụng ng-messages để validate form. Nói cách khác là ng-messages vẫn hiển thị những lỗi cơ bản mà đã có trong form. Nhưng vấn đề là kiểm tra 2 password có match với nhau hay không thì như thế nào?

Đầu tiên chũng ta sẽ tạo 1 directive

var compareTo = function() {
    return {
      require: "ngModel",
      scope: {
        otherModelValue: "=compareTo"
      },
      link: function(scope, element, attributes, ngModel) {

        ngModel.$validators.compareTo = function(modelValue) {
          return modelValue == scope.otherModelValue;
        };

        scope.$watch("otherModelValue", function() {
          ngModel.$validate();
        });
      }
    };
  };

  app.directive("compareTo", compareTo);

<input ng-model="passwordConfirm" compare-to="$scope.password"

Ở directive này nó sẽ add thêm 1 field là : passwordConfirm chính là thuộc tính passwordConfirm. Và già trị so sanh chính là password. Và lỗi xảy ra khi giá trị passwordConfirm khác password.

Như vậy mình đã trình bày xong phần validate form và các dùng ng-messages. Mọi người có thể tham khảo tại:


All Rights Reserved