0

Sử dụng ng-messages để validate Form trong AngularJS 1

Hôm nay, mình xin giới thiệu về ng-messages, một directvie mà angularjs hỗ trợ để validate Form.

1- Chuẩn bị:

Đầu tiên, bạn vào đây, chọn phiên bản ( lưu ý là AngularJS 1). và download để import vào project của mình. Trong bài viết này, mình chọn phiên bản 1.5.8.

Vậy là chúng ta đã có thư viện angularJS. Tiếp theo, để sử dụng được ng-messages: chúng ta cần download thư viện angularJS dành cho ng-messages(Nó nằm ở cùng folder với folder mà bạn đã download thư viện angularJS trước đó). Lưu ý là bạn cần download phiên bản ng-message giống với phiên bản angularJS để tránh những lỗi xảy ra trong quá trình sử dụng.

Vâng, bước download đã xong. Bây giờ bạn chỉ cần import 2 file trên vào project của mình và dùng thôi 😃

2- Sử dụng

Bạn phải nạp module angular message vào Ứng dụng angularJS với cú pháp sau:

angular.module('app',['ngMessages']);

Do khi sử dụng ng-message, chúng ta sẽ phải dùng thêm một số directive khác như ng-maxlength, ng-minlenght, ng-required ... Nên mình sẽ giới thiệu luôn những gì mình biết trong bài viết này:

2.1 ng-maxlengthmaxlength

Directive ng-maxlength sẽ add một key với tên maxlength vào object $error của phần tử html khi mà ngModel.$viewValue dài hơn so với độ dài được ghi trong ng-maxlength. Vâng, ta lại gặp $viewValue, $viewValue là giá trị của input đang được nhập,lưu ý rằng angularjs chỉ set giá trị cho ng-model khi nhập đúng validate đã được set. Nên $viewValue sẽ khác với ng-model khi giá trị nhập đang bị lỗi(lớn hơn, bé hơn, không đúng định dạng ...), trong trường hợp bị nhập lỗi, ng-model sẽ không có giá trị.

<input type="text" ng-model="model" id="input" name="input" ng-maxlength="4" />

Với ví dụ trên, lỗi với key maxlength sẽ xảy ra nếu nhập input > 4 kí tự.

Lưu ý rằng với angularJS, bạn hoàn toàn có thể khai báo ng-maxlength="4", hoặc sử dụng trực tiếp attribute maxlength="4" của html5. AngularJS đều hiểu và thực hiện như nhau. Tuy nhiên, chúng ta cần làm rõ sự khác biệt của ng-maxlengthmaxlength khi sử dụng để phục vụ cho một số trường hợp riêng biệt: ng-maxlength không sử dụng maxlenght của html5 để hạn chế input. Tức là khi bạn khai báo ng-maxlength, bạn hoàn toàn có thể nhập hơn số ký tự, angularjs không chặn việc này, mà chỉ thông báo lỗi. Trong khi đó maxlength cuả html5 thì chặn việc nhập lớn hơn số ký tự đã được khai báo.

2.2 ng-minlength

Với ng-minlenght thì html5 không hề có attribute minlength 😃). (Đầu tiên khi làm angularJS mình đã search minlenght html5 vì nghĩ nó có 😃).

Vâng, rất đơn giản, ngược với ng-maxlength. ng-minlength sẽ add một key với tên minlenght vào object $error của phần tử html khi mà ngModel.$viewValue ngắn hơn so với độ dài được ghi trong ng-minlength.

<input type="text" ng-model="model" id="input" name="input" ng-minlength="4" />

Với ví dụ trên, lỗi với key minlength sẽ xảy ra khi bạn nhập < 4. Đến đây sẽ có bạn đặt câu hỏi Vậy không nhập thì sao? bé hơn 4 mà! Bạn có thể yên tâm là minlength chỉ hoạt động khi input có giá trị. Nếu bạn nhập xong rồi xóa đi thì cũng không sao 😃

2.3 ng-requiredrequired

Tương tự như ng-maxlengthmaxlength. Bạn hoàn toàn có thể sử dụng ng-required or required. AngularJS đều thực hiện được. ng-maxlength sẽ add một key required vào $error nếu phần tử html được khai báo ng-required="required" or required không được nhập hoặc check(tùy theo input là tex hay checkbox, select ...)

<input type="text" ng-model="model" id="input" name="input" ng-required="required" />

Với ví dụ trên, lỗi với key required sẽ xảy ra nếu phần từ html không có giá trị. ng-required có một số điều hay mà mình muốn giới thiệu với các bạn như sau: Nếu bạn viết ng-required="required" thì mặc định phần tử đó sẽ là required. Tuy nhiên khi code, mình đã gặp một số key là: Phần tử html chỉ required trong một số trường hợp, các trường hợp khác không required (thuờng là ẩn phần tử đó đi). Tuy nhiên ẩn xong nhưng nó vẫn là required thì bạn vẫn sẽ không save đựoc form 😃) ng-required sẽ giải quyết vấn đề này:

<input type="text" ng-model="model" id="input" name="input" ng-required="$scope.uid" />

Với ví dụ trên, thẻ input sẽ chỉ required nếu $scope.uid == true. Quá tuyệt phải không 😃.

2.4 ng-pattern

Nhiều khi, bạn phải so sánh và báo lỗi nếu input nhập vào không đúng với chuỗi regex, ví dụ như: email, password(>=8 ký tự, ít nhất một ký tự số ...). ng-pattern sẽ add một error key với name pattern khi chuỗi bạn nhập vào không đúng với regex đã khai báo.

<input type="text" ng-model="model" id="input" name="input" ng-pattern="/^[\w+\-.]+@[a-z\d\-.]+\.[a-z]+$/" />

Chuỗi regex ở trên là chuỗi regex để validate định dạng email(bắt đầu bằng chữ hoặc số, có @, có dấu ., ...). Với ví dụ trên lỗi với key pattern sẽ xảy ra nếu bạn nhập định dạng không phù hợp.

2.5 Custom directive for ng-message.

Đôi khi, sử dụng các directive có sẵn là không đủ với các case phức tạp, mình đã gặp một case mình phải viết một directive mới để validate trường hợp sau password confirmation phải giống password. Vâng, đến đây thì rất buồn, thư viện không support nữa (huhu). May mắn là, nhờ kỹ năng google điêu luyện, lượn lờ stackoverflow, mình đã viết một directive để xử lý trường hợp password confirmation:

angular.module('registerApp').directive('compareTo', compareTo);

function compareTo() {
  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();
      });
    }
  };
};

Mình sẽ nói qua về đoạn code trên: mình khai báo một directive, directive này mình sử dụng ở field password confirmation, truyền vào giá trị là giá trị của field password. Directive này sẽ add một key có name compareTo vào field password confirmation nếu giá trị của password confirmation khác password.

Ở trên mới chỉ là viết directive, sử dụng nó như sau:

<input type="password" ng-model="model" id="input" name="input" compare-to="$scope.password" />

Lỗi sẽ xảy ra nếu bạn nhập password confirmation khác với password.

3. Tổng kết

Mình sẽ sử dụng tất cả mình vừa giới thiệu và cách hiển thị message như dưới đây:

<input type="password" ng-model="model" id="input" name="input" ng-reqired="required" ng-minlength="8"
ng-maxlength="32" ng-pattern="regex.isPassword" compare-to="$scope.password" />
<div ng-messages="myForm.input.$error">
    <div ng-message="required">You did not enter a field</div>
    <div ng-message="minlength">Your field is too short</div>
    <div ng-message="maxlength">Your field is too long</div>
    <div ng-message="pattern">Password not regex</div>
    <div ng-message="compareTo">Password confirmation not like password</div>
</div>

Có một điểm rất tuyệt vời là: ng-message sẽ hiển thị messeage theo thứ tự từ trên xuống như code html, gặp lỗi nào truớc thì hiển thị, và không hiển thị lỗi ở đằng sau. Nên bạn có thể yên tâm rằng một input của bạn sẽ chỉ hiển thị một lỗi trong một thời điểm mà thôi. (tuyetvoi)

4. Kết Luận

Trên đây mình đã giới thiệu một số điều mình biết và đã từng làm với angularJS ng-message cùng một số directive khác hỗ trợ việc validate form. Cám ơn mọi người đã xem hết baì viết. Mình dựa trên tài liệu ở đây(rất tốt cho việc học angularJS):

https://docs.angularjs.org/api/ngMessages

https://docs.angularjs.org/api/ngMessages/directive/ngMessage


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.