I have an asp.net form with a login section and a register section. There are two submit buttons that correspond to the appropriate section, login or register. I am using jquery validation, however I cannot find a way to specify validation groups as I would with normal asp.net validation. When I click the register button, right now it is asking for the login fields to be filled in. Anyone have any thoughts on this? THANKS!
views:
2292answers:
4I'm guessing you are using this validation plugin: JQuery Validation . The plugin uses the form tag as a validation group so to accomplish what you want you will need to remove rules depending on which button the user pushes. Also, you will need to add the rules back for the case where the validation fails then the user decides to click the other button.
Here's an example:
$(document).ready(function()
{
$("#form").validate({
invalidHandler: addRules
});
addRules();
$("#submit1").click(function(){
$(".group2").each(function(){
$(this).rules("remove");
});
});
$("#submit2").click(function(){
$(".group1").each(function(){
$(this).rules("remove");
});
});
});
var addRules = function(){
$("#input1").rules("add", {required:true});
$("#input2").rules("add", {required:true});
}
This approach allows you to add a class attribute (group1 or group2) to each of your inputs which acts as a validation group.
Make the ASP.NET server validation logic available to client-side/jQuery by affixing special CSS class names onto the HTML elements representing server-side validation controls.
The CSS class names generated will represent validation groups. Therefore ,for example, some text boxes will be tagged with the class name for one validation group, and other text boxes for a different validation group.
For example, write and call this C# function in the Page PreRender handler, or before the page is rendered to imbue server controls with special CSS.
/// <summary>
/// Makes the server validation logic knowledge available to the client side
/// by appending css class names to validators and html elements being validated.
/// The generated css classes can be targeted by jQuery in the DOM.
/// </summary>
/// <param name="cssPrefixValidator">prefix string for validator css names</param>
/// <param name="cssPrefixTarget">prefix string for target element css names</param>
/// <remarks>
/// The css prefix arguments to this function help distinguish between what is a
/// validation control and what is an html element being targeted by said validation control.
/// </remarks>
///
void TagValidationWithCss(string cssPrefixValidator, string cssPrefixTarget) {
List<string> valClasses = new List<string>();
List<string> targetClasses = new List<string>();
// iterate over validator server controls
foreach (BaseValidator val in Page.Validators) {
// keep a unique list of generated validator css class names
string classnameVal = cssPrefixValidator + val.ValidationGroup;
if (!valClasses.Contains(classnameVal))
valClasses.Add(classnameVal);
// ..and mark the validator element with the generated css class name
val.CssClass += (string.IsNullOrEmpty(val.CssClass) ? "" : " ") + classnameVal;
// keep a unique list of generated target element css class names
string classnameTarg = cssPrefixTarget + val.ValidationGroup;
if (!targetClasses.Contains(classnameTarg))
targetClasses.Add(classnameTarg);
// ..and mark the target element with the generated css class name
Control target = FindControl(val.ControlToValidate);
if (target is HtmlControl)
((HtmlControl)target).Attributes["class"] += (string.IsNullOrEmpty(val.CssClass) ? "" : " ") + classnameTarg;
else if (target is WebControl)
((WebControl)target).CssClass += (string.IsNullOrEmpty(val.CssClass) ? "" : " ") + classnameTarg;
}
// output client script having array of validator css names representing validation groups
string jscriptVal = string.Format("<script>window['{1}'] = ['{0}'];</script>", string.Join("','", valClasses.ToArray()), cssPrefixValidator);
ClientScript.RegisterStartupScript(this.GetType(), "val", jscriptVal);
//output client script having array of html element class names representing validation groups
string jscriptTarg = string.Format("<script>window['{1}'] = ['{0}'];</script>", string.Join("','", targetClasses.ToArray()), cssPrefixTarget);
ClientScript.RegisterStartupScript(this.GetType(), "targ", jscriptTarg);
}
The function is called in the server-side Page:
protected override void OnPreRender(EventArgs e) {
base.OnPreRender(e);
TagValidationWithCss("validator-", "target-");
}
The declarative syntax of the ASPX page might have your two sections like so:
<div>
Login Section
<asp:TextBox ValidationGroup="vg1" ID="TextBox1" runat="server"></asp:TextBox><asp:TextBox
ValidationGroup="vg1" ID="Textbox2" runat="server"></asp:TextBox><asp:Button ID="Button1"
ValidationGroup="vg1" runat="server" Text="Button" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="TextBox1"
ErrorMessage="RequiredFieldValidator" ValidationGroup="vg1"></asp:RequiredFieldValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="Textbox2"
ErrorMessage="RequiredFieldValidator" ValidationGroup="vg1"></asp:RequiredFieldValidator>
<hr />
Registration Section
<asp:TextBox ValidationGroup="vg2" ID="TextBox4" runat="server"></asp:TextBox><asp:TextBox
ValidationGroup="vg2" ID="Textbox5" runat="server"></asp:TextBox><asp:Button ID="Button3"
ValidationGroup="vg2" runat="server" Text="Button" />
</div>
Now over to the rendered page to see the results .....
The page HTML source contains arrays of generated CSS names representing validation groups, one set for validators (validator-) and another for targets of validation (target-)
<script>window['validator-'] = ['validator-vg1','validator-vg2'];</script>
<script>window['target-'] = ['target-vg1','target-vg2'];</script>
These CSS names are also rendered on the html elements. Notice "target-vg1" CSS classes on text boxes here, representing validation group #1. The text boxes represent the login screen/interface on the page (one of two UI parts):
<input name="TextBox1" type="text" id="TextBox1" class=" target-vg1" /><input name="Textbox2" type="text" id="Textbox2" class=" target-vg1" /><input type="submit" name="Button1" value="Button" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("Button1", "", true, "vg1", "", false, false))" id="Button1" />
This second set of textboxes is on the same ASP.NET page (in the same ASP.NET Form) and represent the user Registration screen/interface (the second UI part). Notice these textboxes are tagged with a different validation group named "target-vg2" through the css class.
<input name="TextBox4" type="text" id="TextBox4" class=" target-vg2" /><input name="Textbox5" type="text" id="Textbox5" class=" target-vg2" /><input type="submit" name="Button3" value="Button" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("Button3", "", true, "vg2", "", false, false))" id="Button3" />
So we injected special Css names into the ASP.NET flow without interrupting or breaking it.
Ultimately this specialized output allows you to write custom scripts against it (i.e. using jQuery) to grab onto those special CSS class names and to distinguish between validation groups on the client side.
This simple example alerts the names of the validation groups on the client side to prove they are seen and known. Whew!
<script>
// Tell the CSS names of the available validation groups assigned to target elements.
var strGroups = 'css validation groups are: ' + window['target-'].join(', ');
alert(strGroups);
</script>
jQuery can be used to target the special css classes too.
This doesn't cover all cases. It might be really out to lunch, but was interesting to make. The server- and client-side code would need to be tweaked to personal or project taste.
(You also want to rely on the fact that newer browsers can apply multiple CSS classes to one element using the 'class' attribute by separating class names with spaces e.g - class="vg1 animated bright myclass your class". This allows the generated css class names to be appended after existing class names without overwriting them.)
Did Jataro's solution actually work? I'm having absolutely no luck with it at all! I've had to make to functions for adding rules to each form and then call those. No luck really - just validates both forms as it did before!