-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Input validation with ng-required function not compatible across different browsers. #4945
Comments
I think the problem is in validators methods (email, required, minlength, number, ...) because these methods return Check flow of validations methods (email by example) : var emailValidator = function(value) {
if (ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value)) {
ctrl.$setValidity('email', true);
return value;
} else {
ctrl.$setValidity('email', false);
return undefined;
}
};
ctrl.$formatters.push(emailValidator);
ctrl.$parsers.push(emailValidator); https://github.com/angular/angular.js/blob/g3_v1_2/src/ng/directive/input.js#L1151-L1153 forEach(this.$parsers, function(fn) {
value = fn(value);
}); I think it is a mistake to return an |
If it is a mistake, are you proposing a solution which would enable your use cases without breaking other ones? (Also it should be noted that the ngRequired directive does not work the way it's being used in @jonricaurte's plnkr: https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L1314, perhaps some documentation needs to be updated) |
Thanks for the responses. @caitp Could you clarify how it is not being used correctly? It seems like you should be able to have a function for ng-required to dynamically change whether or not an input is required. An example of a use case for this would be if you were filling out an address form and some countries require a state field and some don't. Here is a similar example: http://plnkr.co/edit/MXROFfHABF0kWjuvGPJ1?p=preview So the function bound to ng-required always returns true. In Firefox, if you type in "a" then delete "a" and then click show text, you will get undefined. This should return an empty string since the validate-characters directive checks to see if the value is undefined and if it is, returns an empty string. In Firefox's case, in validate-characters it is an empty string and is not undefined so an empty string is returned. However, if you click "show text" search.test is undefined. |
@jonricaurte: $scope.$observe() will interpolate a string --- it does not $eval an expression. The result of the interpolation is always a string (and So, with that in mind, having the function is not going to do what you think it will --- It never gets evaluated by the directive or anything (it does get evaluated twice during bootstrapping, for whatever reason) It should work if you have an expression like These comments weren't really regarding the issue itself, more a comment on your code. However, it is likely that the cross-browser weirdness you're seeing with validation is related to http://dev.w3.org/html5/spec-preview/constraints.html, as they've decided that invalid values (such as an empty string with the I've got a patch to try and work around this particular issue for the [input=number] type, which may or may not be merged some day #4293, you're welcome to see if you can get a similar solution to work for your stuff, and offer any criticism or review of that patch in particular if you see anything I've done rather stupidly ;) |
@caitp In this example it looks like it is evaluating the function: http://plnkr.co/edit/3NtsgZPCz55j3QHzWFgt?p=preview The function returns true if there is something written in either textbox and then applies the css box-shadow. If there is nothing, it doesn't apply any css. This is in Chrome. |
It seems like in the latest version of angular something was fixed and now Firefox returns an empty string. It works sometimes in IE, but sometimes doesn't. |
It only evaluates the function during bootstrap, not during every digest. For one thing, it's not even $observing the But again, this is not really the point of the comment, it's a nitpick about misuse of the directive. If the browser decides that an input is invalid with browser constraint validation, the parsers see |
Ok sorry for going back and forth between two different things. The undefined I understand that it could be for browsers which support constraint validation and angular must handle it differently in later versions for it to perform differently in Firefox (haven't been able to look to see where the changes are). I sort of switched to a different problem relating to ng-required. You are right its not observing ngRequired, however the observe does get fired if you put a breakpoint in the plunker. If you put a breakpoint in angular.js at line 16455 and 16468 you will see the observe is getting fired and recalling the function. However, if I take out the validate-characters directive, the observe doesn't get fired: |
http://plnkr.co/edit/YG91eM8dHSvhEBI3NVGZ?p=preview Sorry for the split comment. |
Where the observe is getting fired is in this plunker on those lines: |
Interesting. In the last plunker, the flow is:
|
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
I have a form with input validation that also uses an ng-required function to determine if the input is required.
http://plnkr.co/edit/sBSkkaR6UCPodKxlQBf7?p=preview
Steps to reproduce:
In angular 1.1.5, after you delete "a" from input you can see that in chrome validateCharacters shows undefined and then in the required function shows an empty string. However, in Firefox and IE there is an empty string in validateCharacters and then in the required function it is undefined. If you update to angular 1.2, then Firefox and Chrome are the same but IE is still the old way:
http://plnkr.co/edit/trECTGaXRo5QVWeYTTdV
Is there any workaround for this?
The text was updated successfully, but these errors were encountered: