Bullines Bullines - 7 months ago 38
Javascript Question

jQuery Validation: Changing Rules Dynamically

I have a single form that, depending on which radio button is clicked (Login or Signup), displays either:


  • email address

  • password



or:


  • name

  • age

  • email address

  • password



Clicking on the radio button toggles the visibility of the Login/Signup fields:

<form id="myForm">
<input name="userAction" type="radio" value="login" checked="checked">Login</input>
<br />
<input name="userAction" type="radio" value="signup">Sign Up</input>

<div id="loginFields" style="display:none">
<!-- Login fields (email address and password) -->
</div>

<div id="signupFields" style="display:none">
<!-- Signup fields (name, age, email address, password) -->
</div>
</form>


I'm using the jQuery Validation plug-in, and I'd like to use the following rules:

var signupRules = {
emailAddressTextBox:
{
required: true,
email: true
},
passwordTextBox:
{
required: true,
minlength: 6,
maxlength: 24,
passwordValidationRule: true // custom regex added with $.validator.addMethod()
}
};

var loginRules = {
nameTextBox:
{
required: true,
maxlength: 50
},
loginEmailAddressTextBox:
{
required: true,
email: true
},
loginPasswordTextBox:
{
required: true,
minlength: 6,
maxlength: 24,
passwordValidationRule: true // custom regex added with $.validator.addMethod()
},
loginPasswordAgainTextBox:
{
required: true,
minlength: 6,
maxlength: 24,
equalTo: "#loginPasswordTextBox"
passwordValidationRule: true // custom regex added with $.validator.addMethod()
}
};


How can I add the correct validation rule dynamically based on:

$("input[name='userAction']").change(function() {
if ($("input[name='userAction']:checked" ).val() === "login") {
// use loginRules
} else {
// use signupRules
}
});


I've tried the following:

$("#myForm").validate({
rules: ($("input[name='userAction']:checked" ).val() === "login") ? loginRules : signupRules;
});


But since my Login fields are the default displayed, its validations work, but the Signup scenario doesn't; it wants to validate Login fields for some reason. Am I missing something?

Answer

Ahh validation plugin, always so tricky :(

First, I added id attributes to all the input boxes. Then, I made a change function for you:

$("input[name='userAction']").change(function() {
    $('#signupFields').toggle();
    $('#loginFields').toggle();    
    if ($("input[name='userAction']:checked").val() === "login") {
        removeRules(signupRules);
        addRules(loginRules);
    } else {        
        removeRules(loginRules);
        addRules(signupRules);

    }
});

The add and remove functions look like this:

function addRules(rulesObj){
    for (var item in rulesObj){
       $('#'+item).rules('add',rulesObj[item]);  
    } 
}

function removeRules(rulesObj){
    for (var item in rulesObj){
       $('#'+item).rules('remove');  
    } 
}

That's pretty much it. See here for a working example: http://jsfiddle.net/ryleyb/wHpus/66/

EDIT: To me, the non-intuitive part is that I don't see an easy way to add/remove rules to the whole form after you call validate, instead you have to manipulate the individual form elements.