jQuery验证 - 一个asp.net表单上的多个提交按钮,不同的验证组?

时间:2009-10-21 19:01:35

标签: asp.net jquery validation

我有一个带有登录部分和注册部分的asp.net表单。有两个提交按钮对应于相应的部分,登录或注册。我正在使用jquery验证,但是我无法像通常的asp.net验证那样​​找到指定验证组的方法。当我点击注册按钮时,它现在要求填写登录字段。任何人对此有何想法?谢谢!

6 个答案:

答案 0 :(得分:5)

我猜你正在使用这个验证插件:JQuery Validation。该插件使用表单标记作为验证组,因此要完成您想要的操作,您需要根据用户推送的按钮删除规则。此外,您需要为验证失败的情况添加规则,然后用户决定单击其他按钮。

以下是一个例子:

$(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});
}

此方法允许您将类属性(group1或group2)添加到充当验证组的每个输入中。

答案 1 :(得分:1)

您不必编写特定于页面的代码来解决此问题,而是可以使用以下库:

https://github.com/bbraithwaite/JQueryValidationForWebForms

NB源代码如下,但Github链接始终具有最新源。

它位于jQuery Validation Framework之上,并通过将类名作为约定来抽象出这个问题。

您以与jQuery验证相同的方式注册验证事件(仅使用不同的名称):

$(function() {
    $("#aspForm").validateWebForm();
});

示例.ASPX

具有两个验证组的基本.aspx示例可能如下所示。你只需要包装每个逻辑部分并给它一个类名“form”,并在应该触发验证事件的动作上添加“submit”类:

 <fieldset class="form">
 <div class="something">
 <ul></ul>
 </div>
 <legend>Sign Up</legend>
 <p>
 <asp:Label ID="uiFirstName" runat="server" AssociatedControlID="uxFirstName" Text="First name:"></asp:Label>
 <asp:TextBox ID="uxFirstName" runat="server" CssClass="required"></asp:TextBox>
 </p>
 <p>
 <asp:Button ID="uxRegister" runat="server" Text="Sign Up" CssClass="submit signup" />
 <asp:Button ID="uxCancelRegister" runat="server" Text="Cancel" />
 </p>
 </fieldset>
 <fieldset class="form">
 <legend>Login</legend>
 <p>
 <asp:Label ID="uiUserName" runat="server" AssociatedControlID="uxUserName" Text="User name:"></asp:Label>
 <asp:TextBox ID="uxUserName" runat="server" CssClass="required email"></asp:TextBox>
 </p>
 <p>
 <asp:Button ID="uxLogin" runat="server" Text="Login" CssClass="submit login" />
 <asp:Button ID="uxCancelSignUp" runat="server" Text="Cancel" />
 </p>
 </fieldset>

源代码

(function ($) {

    $.extend($.fn, {
        validateWebForm: function (options) {

            var form = $(this[0]),
                formExists = (form.length) && form.is('form');

            if (formExists) {
                if (!options) {
                    options = {};
                }

                // stop the validation from firing on the form submit
                options.onsubmit = false;

                // wire up the default jquery validation event to the form
                this.validate(options);

                // Select any input[type=text] elements within a validation group
                // and attach keydown handlers to all of them.
                $('.form :text').keydown(function (event) {
                    // Only execute validation if the key pressed was enter.
                    if (event.keyCode == 13) {
                        $(event.currentTarget).closest(".form").find(".submit").click();
                    }
                });

                // find the submit buttons and override the click event
                form.getSumbitControls().click(this.validateAndSubmit);

                return this;
            }

            return undefined;
        },
        getSumbitControls: function () {
            return $(this).find('.form .submit');
        },
        getValidationContainer: function (submitControl) {
            return $(submitControl).closest('.form');
        },
        validateAndSubmit: function (event) {
            // Ascend from the button that triggered this click event 
            // until we find a container element flagged with 
            // .validationGroup and store a reference to that element.
            var group = $(this).getValidationContainer(event.currentTarget),
                isValid = true;

            // Descending from that .form element, find any input
            // elements within it, iterate over them, and run validation on 
            // each of them.
            group.find(':input').each(function (i, item) {
                if (!$(item).valid()) {
                    isValid = false;
                }
            });

            // If any fields failed validation, prevent the button's click 
            // event from triggering form submission.
            if (!isValid) {
                event.preventDefault();
            }
        }
    });

})(jQuery);

Nuget Users

PM&GT; Install-Package JQuery.Validation.WebForms

这是从Dave Ward的以下帖子发展而来的:

http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/

答案 2 :(得分:1)

您总是可以使用一些简单的jquery / javascript来删除asp按钮OnClientClick上的“validate [required]”类,然后将其添加回其他按钮OnClientClick,这比更改validationengine文件或替换它们更容易。这方面的一个例子是:

<div id="Login">
    <asp:TextBox ID="txtUser" runat="server" CssClass="validate[required]"></asp:TextBox>
    <asp:TextBox ID="txtPass" runat="server" CssClass="validate[required]"></asp:TextBox>
    <asp:Button ID="btnLogin" runat="server" OnClientClick="disableReg();" OnClick="btnLogin_Click" />
</div>
<div id="Register">
    <asp:TextBox ID="txtName" runat="server" CssClass="validate[required]"></asp:TextBox>
    <asp:TextBox ID="txtEmail" runat="server" CssClass="validate[required]"></asp:TextBox>
    <asp:Button ID="btnReg" runat="server" OnClientClick="disableLogin();" OnClick="btnReg_Click" />
</div>

javascript将是:

function disableReg() {
    $('#<%=txtName.ClientID%>').removeClass("validate[required]");
    $('#<%=txtEmail.ClientID%>').removeClass("validate[required]");
    $('#<%=txtUser.ClientID%>').addClass("validate[required]");
    $('#<%=txtPass.ClientID%>').addClass("validate[required]");
    return true;
}

function disableLogin() {
    $('#<%=txtUser.ClientID%>').removeClass("validate[required]");
    $('#<%=txtPass.ClientID%>').removeClass("validate[required]");
    $('#<%=txtName.ClientID%>').addClass("validate[required]");
    $('#<%=txtEmail.ClientID%>').addClass("validate[required]");
    return true;
}

答案 3 :(得分:0)

跟踪验证对象并直接删除/替换规则。适用于v1.13.0

var validation = $('#form1').validate(); //Keep track of validation object

//Rule set 1
var validationRulesLogin = {
    headerEmail: {
        required: true,
        email: true
    },
    headerPassword: "required"
};
var validationMessagesLogin = {
    headerEmail: {
        required: "Please enter your email address.",
        email: "Not a valid email address."
    },
    headerPassword: "Please enter your password."
};

//Rule set 2
var validationRulesSignup = {
    signupEmail: {
        required: true,
        email: true
    },
    signupPassword: "required",
    signupPassword2: {
        equalTo: "#phBody_txtNewPassword"
    }
};
var validationMessagesSignup = {
    signupEmail: {
        required: "Please enter your email address.",
        email: "Not a valid email address."
    },
    signupPassword: "Please enter your password.",
    signupPassword2: "Passwords are not the same."
};

//Toggle rule sets on form focus, button click or other event.
function validatingLoginForm(){
    validation.resetForm();
    validation.settings.rules = validationRulesLogin;
    validation.settings.messages = validationMessagesLogin;
}
function validationSignupForm(){
    validation.resetForm();
    validation.settings.rules = validationRulesSignup;
    validation.settings.messages = validationMessagesSignup;
}

答案 4 :(得分:-1)

如果你使用不显眼的jquery验证,或者你可以使用它:

$(document).ready(function () {

    var formValidator = $("form").validate();

    $("#btnLogin").click(function () {
        formValidator.settings.ignore = "#registerSection *";
    });

    $("#btnRegister").click(function () {
        formValidator.settings.ignore = "#loginSection *";
    });
});

答案 5 :(得分:-2)

通过在表示服务器端验证控件的HTML元素上附加特殊的CSS类名,使ASP.NET服务器验证逻辑可用于客户端/ jQuery。

生成的CSS类名称将代表验证组。因此,例如,某些文本框将使用一个验证组的类名称和其他验证组的其他文本框进行标记。

例如,在Page PreRender处理程序中编写和调用此C#函数,或者在呈现页面之前使用特殊的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);
}

在服务器端页面中调用该函数:

protected override void OnPreRender(EventArgs e) {
    base.OnPreRender(e);

    TagValidationWithCss("validator-", "target-");
}

ASPX页面的声明性语法可能包含两个部分:

<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>

现在转到渲染页面以查看结果.....

页面HTML源包含生成的CSS名称数组,表示验证组,一组用于验证器(验证器 - ),另一组用于验证目标(目标 - )

<script>window['validator-'] = ['validator-vg1','validator-vg2'];</script>
<script>window['target-'] = ['target-vg1','target-vg2'];</script> 

这些CSS名称也在html元素上呈现。请注意此处文本框中的“target-vg1”CSS类,表示验证组#1。文本框表示页面上的登录屏幕/界面(两个UI部分之一):

<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(&quot;Button1&quot;, &quot;&quot;, true, &quot;vg1&quot;, &quot;&quot;, false, false))" id="Button1" /> 

第二组文本框位于同一个ASP.NET页面上(在同一个ASP.NET窗体中),代表用户注册屏幕/界面(第二个UI部分)。请注意,这些文本框通过css类标记为名为“target-vg2”的不同验证组。

 <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(&quot;Button3&quot;, &quot;&quot;, true, &quot;vg2&quot;, &quot;&quot;, false, false))" id="Button3" /> 

因此我们在ASP.NET流程中注入了特殊的Css名称而不会中断或破坏它。

最终,这个专门的输出允许你编写自定义脚本(即使用jQuery)来抓取那些特殊的CSS类名,并区分客户端的验证组。

这个简单的示例警告客户端验证组的名称,以证明它们已被查看和知晓。呼!

<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也可用于定位特殊的css类。

这并未涵盖所有情况。午餐可能真的很不错,但很有意思。服务器端和客户端代码需要调整为个人或项目品味。

(您还希望依赖于这样一个事实:较新的浏览器可以使用'class'属性将多个CSS类应用于一个元素,方法是使用空格分隔类名,例如 - class =“vg1 animated bright myclass your class”。这允许生成的css类名称将在现有类名称之后追加,而不会覆盖它们。)