Xác thực ng-pattern động Angularjs


84

Tôi có một biểu mẫu mà nếu một hộp kiểm là sai sẽ thực thi xác thực đối với đầu vào văn bản bằng cách sử dụng lệnh ng-Required. Nếu hộp kiểm là true, trường sẽ bị ẩn và ng-Required được đặt thành false.

Vấn đề là tôi cũng có một regex để xác thực được chỉ định trên đầu vào cũng như sử dụng chỉ thị góc ng-pattern. Vấn đề tôi đang gặp phải là nếu người dùng điền vào một số điện thoại không hợp lệ, hãy chọn hộp để hủy kích hoạt đầu vào đó (và do đó không cần xác thực thêm) thì biểu mẫu sẽ không cho phép gửi vì nó không hợp lệ dựa trên ng-pattern.

Tôi đã cố gắng giải quyết vấn đề này bằng cách thêm một hàm ng-change để đặt mô hình đầu vào thành null, tuy nhiên ng-pattern và do đó trường vẫn được đặt thành không hợp lệ trên tập hợp ban đầu của hộp kiểm thành false. Tuy nhiên, nếu tôi bỏ chọn hộp, đặt mọi thứ trở lại tải biểu mẫu ban đầu, sau đó chọn lại hộp, biểu mẫu hợp lệ và có thể gửi. Tôi không chắc chắn những gì tôi đang thiếu. Đây là mã ng-change mà tôi có cho đến nay:

    var phoneNumberRegex = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    $scope.phoneNumberPattern = phoneNumberRegex;
    $scope.removeValidation = function() {
        if ($scope.cell._newUser === false) {
            $scope.request._number = '';
            $scope.phoneNumberPattern = /[0-9a-zA-Z]?/;
        } else {
            $scope.phoneNumberPattern = phoneNumberRegex;
        }
    };

Câu trả lời:


175

Đây là một vấn đề thú vị, xác thực Angular phức tạp. Fiddle sau đây thực hiện những gì bạn muốn:

http://jsfiddle.net/2G8gA/1/

Chi tiết

Tôi đã tạo một chỉ thị mới rpattern, đó là sự kết hợp giữa Angular's ng-requiredng-patternmã từ input[type=text]. Những gì nó làm là xem requiredthuộc tính của trường và tính đến điều đó khi xác thực với regexp, tức là nếu không bắt buộc trường đánh dấu là valid-pattern.

Ghi chú

  • Hầu hết mã là từ Angular, phù hợp với nhu cầu của việc này.
  • Khi hộp kiểm được chọn, trường này là bắt buộc.
  • Trường không bị ẩn khi hộp kiểm bắt buộc là false.
  • Biểu thức chính quy được đơn giản hóa cho bản demo (hợp lệ là 3 chữ số).

Một giải pháp bẩn (nhưng nhỏ hơn), nếu bạn không muốn có một chỉ thị mới, sẽ giống như:

$scope.phoneNumberPattern = (function() {
    var regexp = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    return {
        test: function(value) {
            if( $scope.requireTel === false ) {
                return true;
            }
            return regexp.test(value);
        }
    };
})();

Và trong HTML không cần thay đổi:

<input type="text" ng-model="..." ng-required="requireTel"
    ng-pattern="phoneNumberPattern" />

Điều này thực sự đánh lừa góc cạnh khi gọi phương thức của chúng tôi test() , thay vì RegExp.test(), có tính requiredđến.


2
Tôi sẽ rất muốn biết các dấu ngoặc tròn xung quanh và sau hàm làm gì. Nó không hoạt động nếu không có chúng
NeedHack

5
Họ gọi hàm trực tiếp, đặt giá trị trả về của nó vào biến một cách hiệu quả. Nó rất phổ biến trong Javascript để không làm ô nhiễm phạm vi bên ngoài với các chi tiết triển khai của một thành phần cụ thể, ví dụ: nhìn vào mô-đun mẫu .
Nikos Paraskevopoulos

6
Giải pháp bẩn, để chơi một mẹo trên AngularJS dựa trên "ducktyping" của JS là đoạn mã tuyệt vời nhất mà tôi thấy ngày hôm nay. Giải pháp thực sự thông minh!
Florian Loch,

Cảm ơn vì mã tuyệt vời nhưng vẫn chưa rõ ràng lắm, 1) theo docs.angularjs.org/api/ng/directive/input , "Nếu biểu thức đánh giá thành một đối tượng RegExp, thì điều này được sử dụng trực tiếp. Nếu biểu thức đánh giá thành một chuỗi, sau đó nó sẽ được chuyển đổi thành một RegExp ", nhưng tôi cho rằng phoneNumberPattern là một đối tượng khi trả về? Đây có phải là một đối tượng Regxp không? 2) Và trong hàm (value) {} lưu trữ trong thử nghiệm, tham số "value" đến từ đâu? Đánh giá cao cho bất kỳ câu trả lời nào!
user2499325

1
1) Mệnh đề "Nếu biểu thức đánh giá thành RegExp" được Angular thực hiện bằng cách kiểm tra xem thứ mà nó nhận được có testphương thức hay không. Đó là lý do tại sao chúng tôi cung cấp cho nó một đối tượng với tùy chỉnh của riêng chúng tôi test(), về cơ bản là mô phỏng một JS gốc RegExp. 2) Tất valuenhiên là được Angular thông qua khi thực hiện kiểm tra tính hợp lệ thực tế.
Nikos Paraskevopoulos

25

Không làm mất bất cứ điều gì từ câu trả lời tuyệt vời của Nikos, có lẽ bạn có thể làm điều này đơn giản hơn:

<form name="telForm">
  <input name="cb" type='checkbox' data-ng-modal='requireTel'>
  <input name="tel" type="text" ng-model="..." ng-if='requireTel' ng-pattern="phoneNumberPattern" required/>
  <button type="submit" ng-disabled="telForm.$invalid || telForm.$pristine">Submit</button>
</form>

Chú ý đến đầu vào thứ hai: Chúng ta có thể sử dụng một ng-ifđể kiểm soát việc kết xuất và xác nhận trong các biểu mẫu. Nếu requireTelbiến không được đặt, đầu vào thứ hai sẽ không chỉ bị ẩn mà còn không được hiển thị, do đó biểu mẫu sẽ vượt qua xác thực và nút sẽ được bật và bạn sẽ nhận được những gì bạn cần.


1
Ngược lại, nó đơn giản. Nhược điểm, bất kỳ đầu vào nào bị xóa khi biểu thức ng-if là false sẽ bị xóa bất kỳ văn bản nào trong chúng nếu ng-if sau đó được đánh giá thành true sau đó. Tuy nhiên, +1 cho đơn giản.
Brad

Tôi muốn nói thêm, nếu bạn đi theo con đường này, hãy đảm bảo rằng bạn hiểu rằng mọi thứ trong ng-if (nếu bạn đặt nó trên div chẳng hạn) bây giờ sẽ có phạm vi riêng của nó.
Brad

5

Mẫu đã sử dụng:

 ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"

Tệp tham chiếu đã sử dụng:

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

Ví dụ cho Đầu vào:

 <input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">

2

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
<input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">


2

Tôi vừa tình cờ gặp điều này một ngày khác.

Những gì tôi đã làm, có vẻ dễ dàng hơn cách trên, là đặt mẫu trên một biến trên phạm vi và tham chiếu nó trong ng-pattern trong khung nhìn.

Khi "hộp kiểm được bỏ chọn", tôi chỉ cần đặt giá trị regex thành /.*/ trên lệnh gọi lại onChanged (nếu được bỏ chọn). ng-pattern chọn thay đổi đó và nói "OK, giá trị của bạn vẫn ổn". Biểu mẫu bây giờ là hợp lệ. Tôi cũng sẽ xóa dữ liệu xấu khỏi trường để bạn không có một chiếc điện thoại xấu rõ ràng # đang ở đó.

Tôi đã có thêm các vấn đề xung quanh ng-Required, và đã làm điều tương tự. Làm việc như người ở.


0

Đặt khóa lỗi xác thực mẫu nếu ngModel $ viewValue không khớp với RegExp được tìm thấy bằng cách đánh giá biểu thức Angular được cung cấp trong giá trị thuộc tính. Nếu biểu thức đánh giá một đối tượng RegExp, thì nó được sử dụng trực tiếp. Nếu biểu thức đánh giá thành một chuỗi thì nó sẽ được chuyển đổi thành một RegExp sau khi gói nó trong các ký tự ^ và $.

Có vẻ như câu trả lời được bình chọn nhiều nhất trong câu hỏi này nên được cập nhật, vì khi tôi thử nó, nó không áp dụng testchức năng và xác nhận không hoạt động.

Ví dụ từ tài liệu Angular hoạt động tốt cho tôi:

Sửa đổi trình xác thực tích hợp

html

<form name="form" class="css-form" novalidate>
  <div>
   Overwritten Email:
   <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
   <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
   Model: {{myEmail}}
  </div>
</form>

js

var app = angular.module('form-example-modify-validators', []);

app.directive('overwriteEmail', function() {
    var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;

    return {
        require: 'ngModel',
        restrict: '',
        link: function(scope, elm, attrs, ctrl) {
            // only apply the validator if ngModel is present and Angular has added the email validator
            if (ctrl && ctrl.$validators.email) {

                // this will overwrite the default Angular email validator
                ctrl.$validators.email = function(modelValue) {
                    return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
                };
             }
         }
     };
 });

Plunker


-1

Bạn có thể sử dụng trang web https://regex101.com/ để xây dựng mẫu cụ thể của riêng mình cho một số quốc gia:

Ví dụ: Ba Lan:

-pattern = xxxxxxxxx OR xxx-xxx-xxx OR xxx xxx xxx 
-regexp ="^\d{9}|^\d{3}-\d{3}-\d{3}|^\d{3}\s\d{3}\s\d{3}"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.