A while ago I've written a custom validation method for .validate(). It is a local validation plugin, with some limited validation.
I was required to write a validation method with the following requirements:
- Must accept a custom string.
- Must allow a maximum value.
- Must allow a minimum value.
- Has to allow to have dynamic values on the string.
- Must validate using a regular expression.
- Must allow numbers in the Portuguese and English formats.
At the time, it was quite a challenge and I was happy with the result, but the code is BAD. It works, but it is so hacky and kludged it hurts my soul.
(function(){
var __c_number_between=new String('');
__c_number_between.valueOf=function(){
return 'The value must be between __MIN__ and __MAX__'
.replace(/__MIN__/g,this.min)
.replace(/__MAX__/g,this.max);
};
__c_number_between.toString=function(){return this.valueOf();};
$.validator.addMethod('c_number_between',
function(d,i,o){
var num=d.replace(/\./g,'').replace(',','.')/1;
__c_number_between.min=o.min;
__c_number_between.max=o.max;
return o.max>=num&&num>=o.min;
},__c_number_between);
})();
Yes, that is the code. It fulfills all my needs, but relies on a really bad behaviour in Javascript, which is that objects are passed as a reference. It also relies on Javascript being executed linearly, instead of having multiple threads, which is REALLY bad!
How can I re-write this in a clean and decent way?
Also, worth noticing is that this is a cross-posting from StackOverflow, on the following question: jQuery .validation plugin: help cleaning aditional method
1 Answer 1
jQuery.validator.format()
jQuery.validator has a format method
This allows you to replace the String you created entirely.
However, this would require you to replace your 'o' parameter object with an array ( [min,max] ).
$.validator.addMethod('c_number_between',
function(d,i,o){
var num=d.replace(/\./g,'').replace(',','.')/1,
// min/max assigns for context readability (optional)
min = o[0],
max = o[1];
return max>=num&&num>=min;
},$.validator.format('The value must be between {0} and {1}'));
Update:
While the docs say:
The default message to display for this method. Can be a function created by ''jQuery.validator.format(value)''. When undefined, an existing message is used (handy for localization), otherwise the field-specific messages have to be defined.
Any function that returns a string can be used so boom:
$.validator.addMethod('c_number_between',
function(d,i,o){
var num=d.replace(/\./g,'').replace(',','.')/1,
return 0.max>=num&&num>=0.min;
},function(params){return 'The value must be between {0} and {1}'.replace('{0}',params.min).replace('{1}',params.max);});
-
\$\begingroup\$ Actually, it is
o.max
ando.min
, instead ofo[0]
ando[1]
. But other than that... WOW! I had no idea about that method. It really is a lifesaver! Thank you a lot! Now, I have a few validations to fix. Once again, thank you \$\endgroup\$Ismael Miguel– Ismael Miguel2015年08月05日 18:01:13 +00:00Commented Aug 5, 2015 at 18:01 -
\$\begingroup\$ To use $.validator.format the o parameter has to be an array (as far as i know) so {min:y,max: x} is now [x,y]... aleast in how i interpreted your code \$\endgroup\$Shaun H– Shaun H2015年08月05日 18:05:14 +00:00Commented Aug 5, 2015 at 18:05
-
\$\begingroup\$ That would be a bad surprise. It isn't feasable to change everything. I have at least 100 instances of that validation. But that is a problem outside the scope of your review, and something I didn't mention. Therefore, you deserved the reputation. I will look into some way to hammer this screw on my steel bar. \$\endgroup\$Ismael Miguel– Ismael Miguel2015年08月05日 18:09:11 +00:00Commented Aug 5, 2015 at 18:09