Angular dynamic check of ng-templates

I have a form that, if false, forces the text to be checked using the ng-required directive. If the checkbox is set correctly, the field is hidden, and ng-required is set to false.

The problem is that I also have a regex for the validation specified on the input, as well as using the ng-pattern angular directive. The problem I am facing is that if the user fills out an invalid phone number, he checks the checkbox to deactivate this input (and therefore does not need further verification), the form does not allow submission, since it is invalid based on ng -pattern.

I tried to solve this problem by adding the ng-change function to set the input model to null, however the ng-template and, therefore, the field is still set as invalid in the original flag set to false. If, however, I clear the checkbox by setting everything back to the bootstrap form, then check the box again, the form is valid and can file. I'm not sure what I am missing. Here is the ng-change code that I still have:

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; } }; 
+81
angularjs angularjs-directive angularjs-ng-change
Sep 19 '13 at 16:33
source share
7 answers

This is an interesting problem, a complex check of Angular. The following fiddle implements what you want:

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

More details

I created a new rpattern directive, which is a combination of Angular ng-required and ng-pattern code from input[type=text] . What he does is look at the required attribute of this field and take this into account when checking with a regular expression, i.e. If the label field is not required as valid-pattern .

Notes

  • Most of the code is from Angular, tailored to the needs of this.
  • When checked, a field is required.
  • The field is not hidden when the checked box is checked.
  • The regular expression is simplified for demonstration (3 digits allowed).



A dirty (but smaller) solution, if you do not want a new directive, would be something like:

 $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); } }; })(); 

And no changes are required in HTML:

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

These are actually Angular tricks for calling our test() method instead of RegExp.test() , which takes into account the required .

+170
Sep 24 '13 at 14:48
source share

Without removing anything from Nikos's amazing answer, perhaps you can make it simpler:

 <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 entry: we can use ng-if to control the rendering and validation of forms. If the requireTel variable requireTel not set, the second input will not be hidden, but will not be displayed at all, so the form will be tested and the button will turn on, and you will get what you need.

+24
Jul 23 '14 at 8:30
source share

Used pattern:

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

Reference file used:

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

Input Example:

  <input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit"> 
+4
Oct 29 '14 at 17:37
source share

  <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
May 08 '15 at 6:07
source share

I just ran into this the other day.

What I did, which seems easier than the above, is to set the template in a variable in scope and reference it in an ng sample in the view.

When the checkbox is unchecked, I simply set the regex value to /.*/ on the onChanged callback (if it is not set). ng-pattern selects what changes and says "OK, your value is fine." Now the form is valid. I would also delete bad data from the field so that you don't have a clearly bad # phone sitting there.

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

+2
Feb 03 '17 at 18:29
source share

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

It seems that the most voted answer in this question should be updated, because when I try it, it does not use the test function, and the check does not work.

An example from Angular docs works well for me:

Modify 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

0
Dec 26 '15 at 19:20
source share

You can use the site https://regex101.com/ to create your own template for a specific 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}" 
-one
Sep 30 '15 at 8:38
source share



All Articles