jQuery Validate elegant conditional logic
I am validating a form with the jQuery validation plugin (using the plugin is required, as I have other functionality that needs the plugin). It has the following fields:
phoneNumber
firstName
lastName
city
zip
The form is considered valid when one of the following statements is true:
phoneNumber
is validfirstName
lastName
city
are all validfirstName
lastName
zip
are all valid
I know how to require each field and use the other validation methods (I even have my own for the zip), but I am trying to figure out an elegant solution to implement the logic I 开发者_StackOverflowdescribed above. Is a custom method or validation groups the best way to handle this?
Elegant is in the eye of the beholder...
I would recommend making a custom validator to handle the three cases that you have.
I spent a while to understand what Validate could do... I came up with this to validate my form. I used an async call to a servlet to do my username check... but you can put what ever you want in it.
I found another post on stack overflow that greater illustrates making custom validators...
I particularly like this line jQuery.validator.methods['date'].call(this,value,element)
as it seems you can use the built in validators within your custom code. jQuery Validate Plugin - How to create a simple custom rule?
These are the resources I used in learning about validate:
http://www.ferdychristant.com/blog//articles/DOMM-7LZJN7 //article detailing how to really use validate.
http://www.ferdychristant.com/blog//pages/jQuery%20validation%20code
http://randomactsofcoding.blogspot.com/2008/10/starting-with-jquery-how-to-write.html
http://docs.jquery.com/Plugins/Validation/Methods/required#dependency-expression
There is also an amazing depth of information simply in http://docs.jquery.com/Plugins/Validation ...you just gotta click through it all!
below you will also see that you can put javascript right into the rules section.
$(document).ready(function() {
$("#EmailUserEditFormId").validate({
debug: true, //this lets it hit firebug
onkeyup:false, //keep the traffic down for my async call
rules: {
username: {
required: (jQuery('input#username:disabled').length==1)?false:true, //example of JS in a rule
usernameCheck: (jQuery('input#username:disabled').length==1)?false:true //example of a JS rule with a custom validator
}
},
messages: {
username: {
required: "Please enter a unique username.",
usernameCheck: "Username is already in use. Choose another."
}
}
});
});
...and this was my simple custom validator.
jQuery.validator.addMethod('usernameCheck', function(username) {
var postURL = "CheckUsername";
$.ajax({
cache: false,
async: false,
type: 'POST',
data: 'username=' + username,
datatype: 'xml',
url: postURL,
success: function(xml) {
unique = (jQuery(xml).find('unique').text() == "true") ? true : false;
}
});
return unique;
}, '');
phoneNumberValid, firstNameValid, lastNameValid, cityValid, zipValid;
if ((phoneNumberValid) || (firstNameValid && lastNameValid && (cityValid || zipValid)) {
//Form Is Valid
}
Each variable represents a Boolean which you should set after checking each field.
I don't think such complex checking is doable with the jQuery validation plugin alone.
function formIsValid(){
if(phoneNumberIsValid) { return true; }
if(firstNameIsValid && lastNameIsValid) {
return (cityIsValid || zipIsValid);
}
return false;
}
If you like one-liners and don't care about readability:
return (phoneNumberIsValid || (firstNameIsValid && lastNameIsValid && (cityIsValid || zipIsValid)));
If you have a plug-in for conditional pattern matching, something like this could be more readable if you are used to it
return match([phoneNumberValid, firstNameValid, lastNameValid, cityValid, zipValid],
[true, _], true,
[_, true, true, true, _], true,
[_, true, true, _, true], true,
_, false);
精彩评论