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?
Solution 1:
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.
Solution 2:
Or you can use the depends property.
http://jqueryvalidation.org/category/plugin/ search for depends
Example: Specifies a contact element as required and as email address, the latter depending on a checkbox being checked for contact via email.
$(".selector").validate({
rules: {
contact: {
required: true,
email: {
depends: function(element) {
return $("#contactform_email:checked")
}
}
}
}
});
Solution 3:
This post is from years ago, but since it has been viewed a lot of times, I think it would be useful to say that the jQuery Validation plugin now allows us to read, add and remove rules.
Some examples:
Print all rules attached to
#myField
:console.log($('#myField').rules());
Remove an unwanted rule:
$('#myField').rules('remove', 'min');
Add a new rule:
$('myField').rules('add', {min: 10});
So say if you want to dynamically update the minimum value required. You can call a remove
and a add
right after:
// Something happened. The minimum value should now be 100
$('#myField').rules('remove', 'min');
$('#myField').rules('add', {min: 100});
More information can be found here: https://jqueryvalidation.org/category/plugin/#-rules()
Solution 4:
If you want to call validate again with new settings (rules,messages ... etc.) call
$('#formid').removeData('validator')
This will remove validation for the form then initialize it again with the new settings