2

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 valid
  • firstName lastName city are all valid
  • firstName 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 described above. Is a custom method or validation groups the best way to handle this?

Austyn Mahoney
  • 11,398
  • 8
  • 64
  • 85

3 Answers3

2

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;

}, '');

Community
  • 1
  • 1
Bryan James
  • 316
  • 2
  • 5
  • 18
0
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.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • The reason I need to use the plugin is it's support for error messages and type validation. Rolling my own solution would be simple for required inputs, but it needs to use the plugin so my input sanitation and masking works along with it. – Austyn Mahoney Aug 15 '11 at 20:57
0
 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);
Peter Olson
  • 139,199
  • 49
  • 202
  • 242