Note:
This question refers to a very old version of jQuery.validate() (version 1.5). This plugin now provides a built-in solution for doing this: the .r
While there are other ways to do this ASP.net does allow you to use multiple form tags so long as they are not all rendered - so if you use a multi view to only display the relevant content you can use multiple forms.
It tends to clean up validation and submit handling quite a bit.
Alternatively jquery does allow :visible to be added to your selector, so you could potentially only run the selector on visible elements and sidestep the issue that way depending on how they are hidden.
How :visible is calculated was changed in jQuery 1.3.2. Element assumed as visible if it and its parents consumes space in document. CSS visibility isn't taken into account. The release notes outline the changes in more detail.
Here is a better / simpler solution from another post on stack overflow-
Apparently the validation plug-in allows you to specify :visible in your rules. Here is the post-
Advanced JQuery Validation: Avoiding Validations on Certain Conditions
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
$('#form_id').validate();//empty rules
//add rules/message to form element
$('#form_id #inputId').rules("add", {
required : true,
messages : {
required : 'Add your required message'
}
});
Obsolete notice:
This answer refers to an extremely old version of the jQuery.validate() plugin (version 1.5) and is now obsolete as the plugin provides an official API for solving this problem. See the .rules() documentation for the current approach to solving this. I'm leaving this answer as-is to help anyone who must maintain a legacy site that is unable to upgrade to the latest versions of jQuery and jQuery.validate().
This uses a feature of the validator that is not well documented in the API (and by this I mean it isn't documented at all), however since it is a fundamental part of how the validator works, it is not likely to be removed even if it is undocumented.
Once you've initialized the jQuery validator, you can get access to the validator object again by calling the validate()
method on the form object you applied the validator to. This validator object has a settings
property, which stores the default settings, combined with the settings you applied to it in initialization.
Assuming I initialize the validator like this:
$('form').validate({
rules: {
leftform_input1: { required: true },
leftform_input2: { required: true }
},
messages: {
leftform_input1: "Field is required",
leftform_input2: "Field is required"
}
});
I can then get those exact settings out of the validator by doing the following:
var settings = $('form').validate().settings;
I can then easily work with this settings object to add or remove validators for the form.
This is how you would remove validation rules:
var settings = $('form').validate().settings;
delete settings.rules.rightform_input1;
delete settings.messages.rightform_input1;
And this is how you would add validation rules:
var settings = $('form').validate().settings;
settings.rules.leftform_input1 = {required: true};
settings.messages.leftform_input1 = "Field is required";
Here is a working solution for the scenario in my question. I use jQuery's extend()
method to overwrite the rules
and messages
properties of the validate
object, which is how I toggle between the two panels.
$('#toggleSwitch').click(function() {
var settings = $('form').validate().settings;
var leftForm = $('#leftform');
var rightForm = $('#rightform');
if (leftForm.css("visibility") !== "hidden") {
leftForm.css("visibility", "hidden");
rightForm.css("visibility", "visible");
$.extend(settings, {
rules: {
rightform_input1: { required: true },
rightform_input2: { required: true }
},
messages: {
rightform_input1: "Field is required",
rightform_input2: "Field is required"
}
});
} else {
rightForm.css("visibility", "hidden");
leftForm.css("visibility", "visible");
$.extend(settings, {
rules: {
leftform_input1: { required: true },
leftform_input2: { required: true }
},
messages: {
leftform_input1: "Field is required",
leftform_input2: "Field is required"
}
});
}
});
The "required" declarations inside of the validate.rules hash do not have to be statically declared as "true". You can actually supply an anonymous function instead which can check for the visibility of something and return true or false depending on the answer.
$('form').validate({
rules: {
rightform_input1: {
required: function(){
return $('#leftform').css("visibility") !== "hidden"
} },
rightform_input2: {
required: function(){
return $('#leftform').css("visibility") !== "hidden"
} }
}
});
I wrote small function for editting rules (only required).
$.editRules = function($array, $type) {
var settings = $('#signupForm').validate().settings;
$.each($array, function($k, $v) {
settings.rules[$v] = {required: ($type == 'add' ? true : false)};
});
};