[angularjs] Angularjs dynamic ng-pattern validation

I have a form that if a checkbox is false enforces validation on a text input using the ng-required directive. If the checkbox is true, the field is hidden and the ng-required is set to false.

The problem is that I also have a regex for validation specified on the input as well utilizing the ng-pattern angular directive. The issue I am running into is that if a user fills in an invalid phone number, checks the box to deactivate that input (and consequently needs no further validation) the form will not allow submission as it is invalid based on the ng-pattern.

I attempted to resolve this issue by adding an ng-change function to set the input model to null, however the ng-pattern and thus the field is still set to invalid on the initial set of the checkbox to false. If I however uncheck the box, setting everything back to initial form load, then check the box again, the form is valid and able to submit. I am not sure what I am missing. Here is the ng-change code I have thus far:

    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;
        }
    };

This question is related to angularjs angularjs-directive angularjs-ng-change

The answer is


I just ran into this the other day.

What I did, which seems easier than the above, is to set the pattern on a variable on the scope and refer to it in ng-pattern in the view.

When "the checkbox is unchecked" I simply set the regex value to /.*/ on the onChanged callback (if going to unchecked). ng-pattern picks that change up and says "OK, your value is fine". Form is now valid. I would also remove the bad data from the field so you don't have an apparent bad phone # sitting there.

I had additional issues around ng-required, and did the same thing. Worked like a charm.


Used pattern :

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

Used reference file:

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

Example for Input:

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

Not taking anything away from Nikos' awesome answer, perhaps you can do this more simply:

<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>

Pay attention to the second input: We can use an ng-if to control rendering and validation in forms. If the requireTel variable is unset, the second input would not only be hidden, but not rendered at all, thus the form will pass validation and the button will become enabled, and you'll get what you need.


You can use site https://regex101.com/ for building your own specific pattern for some country:

For example, Poland:

-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}"

Sets pattern validation error key if the ngModel $viewValue does not match a RegExp found by evaluating the Angular expression given in the attribute value. If the expression evaluates to a RegExp object, then this is used directly. If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it in ^ and $ characters.

It seems that a most voted answer in this question should be updated, because when i try it, it does not apply test function and validation not working.

Example from Angular docs works good for me:

Modifying built-in validators

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


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


Examples related to angularjs

AngularJs directive not updating another directive's scope ERROR in Cannot find module 'node-sass' CORS: credentials mode is 'include' CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 Print Html template in Angular 2 (ng-print in Angular 2) $http.get(...).success is not a function Angular 1.6.0: "Possibly unhandled rejection" error Find object by its property in array of objects with AngularJS way Error: Cannot invoke an expression whose type lacks a call signature

Examples related to angularjs-directive

Angular2 - Input Field To Accept Only Numbers Use of symbols '@', '&', '=' and '>' in custom directive's scope binding: AngularJS ng-change not working on a text input Controller not a function, got undefined, while defining controllers globally Find child element in AngularJS directive Angular directives - when and how to use compile, controller, pre-link and post-link How to validate email id in angularJs using ng-pattern Enable/Disable Anchor Tags using AngularJS get original element from ng-click How to detect browser using angularjs?

Examples related to angularjs-ng-change

ng-change not working on a text input how to call service method from ng-change of select in angularjs? Angularjs dynamic ng-pattern validation