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 is an interesting problem, complex Angular validation. The following fiddle implements what you want:
http://jsfiddle.net/2G8gA/1/
I created a new directive, rpattern
, that is a mix of Angular's ng-required
and the ng-pattern
code from input[type=text]
. What it does is watch the required
attribute of the field and take that into account when validating with regexp, i.e. if not required mark field as valid-pattern
.
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 in HTML no changes would be required:
<input type="text" ng-model="..." ng-required="requireTel"
ng-pattern="phoneNumberPattern" />
This actually tricks angular into calling our test()
method, instead of RegExp.test()
, that takes the required
into account.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With