Allow empty values to pass regex validation
In regex validators (such as number) when the value is undefined (or null) the validator should return success, to comply with the html5 number input.
Since this is a breaking change, it will be enabled only using an opt-in flag called "allowEmptyValues".
I updated existing tests to check when the flag is off (default) and added new tests to check for when its on.
Coverage increased (+0.9%) to 94.562% when pulling 33a43fd4f99241fbf6ba7ad1cb8af2fa17af1c11 on liorch88:allow-empty-values-regex into 531cb127308b41f20f3b0c1f3b4df0027bceca21 on huei90:master.
Sorry for the late review here.
when the value is undefined (or null) the validator should return success,
Why this is not decided by the customize RegExp?
I thought of it, and eventually decided that it is not the RegExp's job to allow empty values: if a user defines a "number" regex, it should really check for number. But if the field is not required (using the "required" validation rule) - it is the validator's job to allow null/undefined values to pass, regardless of the used RegExp
then you can use Function,
function(value){
if ( typeof value undefined ) return true;
if ( /* RegExp */ ) return true/false;
}
Is this fix your case?
One more issue about it, if you set allowEmptyValues to true globally, some RegExp or Function expression which is not allow empty will going to be allowed.
Do you mean I can use a function as a custom rule? If so, then I guess it's possible but then I won't be able to use all the other built it rules, such as "number"...
The basic idea of this PR is to allow undefined values to always pass validation, regardless of which rule is used.
If you want the value to be required - use the required rule. if you don't use this rule - it means the value must be optional.
The way it is now, if you use "number" rule - the value is automatically required, which I think is wrong.
Note that this is also how the default html5 validators work: if you use a "number" input, both 5 and undefined pass the validation, since all fields are optional, unless required is used.
Do you mean I can use a function as a custom rule? If so, then I guess it's possible but then I won't be able to use all the other built it rules, such as "number"...
yes, and you have to update the number rule in your own config, so it is possible to use the rule.
Note that this is also how the default html5 validators work: if you use a "number" input, both 5 and undefined pass the validation, since all fields are optional, unless required is used.
Good to see more insight on the number, after updating the number rule I mentioned above commit, then it will follow this behavior.
😄
just one more thing, the angular-validation-rule.js in this repo is just an example, you should create one which covers your own rules, that will be nice.
If you are using the Function for the number rule, this allow empty to validate success.
function(value){
if ( typeof value undefined ) return true;
return /* RegExp */;
}
If you want to have the number rule which is required, it's easy to add the multiple rule validator="required, number"
I see what you mean, and I guess it is possible to create all those rules and the function you've suggested, but it seems a bit like code duplication:
expression = {
required: function(value) {
return !!value;
},
email: function (value) {
if (typeof value undefined ) return true;
return /* email regex */;
},
number: function (value) {
if (typeof value undefined ) return true;
return /* number regex */;
},
url: function (value) {
if (typeof value undefined ) return true;
return /* url regex */;
},....
As you can see, the "undefined" check repeats itself for all the rules (except required). It also makes the code longer as we can't use the nice short form of regex, the way it is used now in the included rules. This is the reason I thought that the "undefined" check logic should be part of the validator.
What do you think? Is there another way to make all the rules "optional" without code duplication, and without this PR?
@liorch88 Thanks for the insight and it perfectly makes sense.
maybe we can have one more config when defining it as RegExp
number: {
RegExp : /* RegExp */,
isRequired : false
}
what do you see about this option?
I am voting for the below solution. 👇
for now, you can
// in your angular-validation-rule.js
var RegExpNotRequired = function( regexp ) {
return function (value) {
if (typeof value undefined ) return true;
return /* regexp expression */
}
}
expression = {
required: function(value) {
return !!value;
},
email: RegExpNotRequired( /* email regex */ ),
number: RegExpNotRequired( /* number regex */ ),
url: RegExpNotRequired( /* url regex */ ),
....
maybe we can have one more config when defining it as RegExp
I guess that would be a nice option too. what would happen to the shorthand regex form that is used in the default rules? I mean, if a user does:
email: /* regexp */
Is it required in that case? (the way it is now) or optional?
for now, you can
Yes that's a nice idea also. it would prevent the duplication in most cases, unless some user decided to split his rules among multiple files. in that case he will have to place that RegExpNotRequired function on each file. but still useful in most cases.
If you decide to go with this solution, maybe it should be in the be used in the included angular validation rules file, with a note that without this function all the regex rules are normally required.
Is it required in that case? (the way it is now) or optional?
It depends on what regexp you are using.
Ok, then I should add this solution to Documentation.