ASP.NET验证失败 - 显示的元素会更改可见性

时间:2013-09-06 18:47:04

标签: javascript asp.net validation

我在ASP.NET页面中使用了客户端Javascript来设置数据列表中几个项目的可见性。基本上,当项目1可见时,项目2应该被隐藏,反之亦然。此代码还启用/禁用一些ASP.NET必需的字段验证器,具体取决于客户端周围字段的可见性。

除非我有ASP.NET验证错误,否则代码可以正常运行当验证失败时,字段会重置为默认可见性(隐藏)。

我已经排除了这是一个回发,因为我的服务器端断点在问题发生时不会被击中。这似乎与客户端脚本有关。

服务器端修复已经发布,因为页面永远不会回发。我想知道如何从Javascript的角度来做这件事?有没有办法在验证脚本触发时触发自定义代码?

我考虑过使用cookie,但我不认为这会对我有所帮助,除非我能参与验证活动。

代码如下......

function handleDropDown(e, a, b, c, v1, v2, h1, h2) {
    var i = parseInt(c) + 2;
    var x = parseInt(c) + 3;

    if (e.value == "Yes") {
        document.getElementById(i).style.display = "inline";
        document.getElementById(i).style.visibility = "visible";

        document.getElementById(x).style.display = "none";
        document.getElementById(x).style.visibility = "hidden";

        document.getElementById(a).focus();

        //Enable validator if needed
        var oVal1 = document.getElementById(v1);
        var oVal2 = document.getElementById(v2);

        var oVis1 = document.getElementById(h1);
        var oVis2 = document.getElementById(h2);

        ValidatorEnable(oVal1, true);
        if (oVis1 != null) {
            oVis1.value = "true";
        }
        ValidatorEnable(oVal2, false);
        if (oVis2 != null) {
            oVis2.value = "false";
        }
       }
    else if (e.value == "No") {
        document.getElementById(x).style.display = "inline";
        document.getElementById(x).style.visibility = "visible";

        document.getElementById(i).style.display = "none";
        document.getElementById(i).style.visibility = "hidden";

        document.getElementById(b).focus();

        //Enable validator if needed
        var oVal1 = document.getElementById(v1);
        var oVal2 = document.getElementById(v2);

        var oVis1 = document.getElementById(h1);
        var oVis2 = document.getElementById(h2);

        ValidatorEnable(oVal1, false);
        if (oVis1 != null) {
            oVis1.value = "false";

        }
        ValidatorEnable(oVal2, true);
        if (oVis2 != null) {
            oVis2.value = "true";
        }
    }
}

ASPX标记片段: **

             <span id="spTxtAnswer" class="required" visible="false" runat="server">*</span>
                        <asp:TextBox ID="txtAnswer" Text='<%# Bind("Answer") %>' runat="server" 
                                   TextMode="MultiLine" Height="76px" MaxLength="2000" Width="370px" Visible="false"  >
                        </asp:TextBox>
                        <asp:RequiredFieldValidator ID="valTextBox" ErrorMessage="This question is required." Enabled="false"
                        Display="Static" ControlToValidate="txtAnswer" runat="server" ValidationGroup="Request" />
                        <asp:RequiredFieldValidator ID="valAnswer" ControlToValidate="txtAnswer" ErrorMessage="<br />Other description is required."
                        Display="Static" enabled="false" runat="server"  ValidationGroup="Request" />
                        <span id="spDdlAnswer" class="required" visible="false" runat="server">*</span>
                        <asp:DropDownList ID="ddlAnswer" Visible="false" runat="server" />
                        <asp:RequiredFieldValidator ID="valDropDown" ControlToValidate="ddlAnswer" Enabled="false"
                        ErrorMessage="This field is required." Display="Static" runat="server"
                         InitialValue="(Select)"  ValidationGroup="Request" />
                        <asp:HiddenField ID="hfQuestionID" Value='<%# Bind("QuestionID") %>' runat="server" />
                        <asp:HiddenField ID="hfAnswer" Value='<%# Bind("Answer") %>' runat="server" />
                        <asp:HiddenField ID="hfRequired" Value='<%# Bind("Required") %>' runat="server" />
                        <asp:HiddenField ID="hfVisible" Value="false" runat="server" />

CodeBehind片段:

TextBox tb1 = (TextBox)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("txtAnswer");
            TextBox tb2 = (TextBox)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("txtAnswer");
            RequiredFieldValidator rfv1 = (RequiredFieldValidator)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("valTextBox");
            RequiredFieldValidator rfv2 = (RequiredFieldValidator)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("valTextBox");
            HiddenField hf1 = (HiddenField)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("hfVisible");
            HiddenField hf2 = (HiddenField)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("hfVisible");

            ddl.Attributes.Add("onchange", "handleDropDown(this,'" + tb1.ClientID + "','" + tb2.ClientID + "','" + questionID + "','" + rfv1.ClientID + "','" + rfv2.ClientID + "'," + 
                "'" + hf1.ClientID + "','" + hf2.ClientID + "');");

            //When selected and viewing in edit mode, set the visibility during page load
            string script = "<script language='javascript'>";
            script += System.Environment.NewLine + "var el = document.getElementById('" + ddl.ClientID + "');";
            script += System.Environment.NewLine + "handleDropDown(el,'" + tb1.ClientID + "','" + tb2.ClientID + "','" + questionID + "','" + rfv1.ClientID + "','" + rfv2.ClientID + "');</script>";
            ClientScript.RegisterStartupScript(Page.GetType(),"startScript", script);

**

3 个答案:

答案 0 :(得分:0)

来自另一个stackoverflow问题(https://stackoverflow.com/a/11723794/704879):

“这是问题:当在页面上加载验证器时,它会创建一些javascript以支持客户端验证。当您将验证器放置在默认情况下不可见的usercontrol中时,此用户控件位于一个updatepanel,它没有正确地创建javascript。这是解决方案:在updatepanel之外,我在上面做了,使用虚拟验证组创建了一个带有虚拟文本框的虚拟验证器,如下所示:“

积分转到解决方案的原始海报(Anton Belev)。

答案 1 :(得分:0)

我最终需要使用客户端脚本和cookie来设置可见性。我需要在回发后保留值,但是在客户端读取它们,因此在这种情况下,viewstate不是真正的选项。

另一个相关的问题是当我尝试调用脚本在IE10中设置字段可见性时,它总是在主体完成加载之前执行。我在主页面的body标签中设置了调用,现在它正常工作。

答案 2 :(得分:0)

我知道这已经过时了,但是,如果有人像我刚才那样遇到其他人,我想提供一个替代Tim的答案,使用cookie来跟踪客户端和服务器之间的状态 - 侧。

如果你有一些javascript需要能够读取一个值,例如某个特定的控件是否已被设置为可见/隐藏的客户端,而不是使用cookie,我建议你创建自己的视图状态和.NET一样。

多年来,我看到许多同事试图将隐藏的字段控件放入其页面标记中,但这并不总是可靠的,因为.NET可以在重新加载viewstate时覆盖客户端值。我使用的解决方案似乎非常可靠,并且设置起来并不困难。对于Web用户控件甚至服务器控件,这都是完全相同的。这使得服务器端和客户端可以跨回发访问值,并且可以考虑任何客户端对可能发生的值的更改。

下面我的示例显示了一个布尔值,整数和字符串,但是同一个方法可以用于任何可以序列化和反序列化到&#34;字符串的数据类型&#34;值。

public partial class MyPage : System.Web.UI.Page
{
    const string
        hdnFld1Nm = "hdnFld1",
        hdnFld2Nm = "hdnFld2",
        hdnFld3Nm = "hdnFld3";

    protected bool HiddenFieldValue1
    {
        get
        {
            object vsVal = this.ViewState["HiddenFieldValue1"];
            if (vsVal == null)
                return false;   // Whatever you want the 'default' value to be.
            else return (bool)vsVal;
        }
        set { this.ViewState["HiddenFieldValue1"] = value; }
    }
    protected int HiddenFieldValue2
    {
        get
        {
            object vsVal = this.ViewState["HiddenFieldValue2"];
            if (vsVal == null)
                return -1;  // Again, default value.
            else
                return (int)vsVal;
        }
        set { this.ViewState["HiddenFieldValue2"] = value; }
    }
    protected string HiddenFieldValue3
    {
        get { return (string)this.ViewState["HiddenFieldValue3"]; }
        set { this.ViewState["HiddenFieldValue3"] = value; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        // For the boolean state, we'll consider any value other than "0" or NULL to be "true".
        this.HiddenFieldValue1 = (!string.IsNullOrEmpty(this.Request[hdnFld1Nm]) && this.Request.Form[hdnFld1Nm] != "0");

        // For the integer, we have to parse from the string value we get from the Form collection, and deal with the potential for "null" if no value was returned.
        string sHdnVal2 = this.Request.Form[hdnFld2Nm];
        int iHdnVal2;
        if (!string.IsNullOrEmpty(sHdnVal2) && !int.TryParse(sHdnVal2, out iHdnVal2))
            this.HiddenFieldValue2 = iHdnVal2;

        // Getting a string value back is easy.
        this.HiddenFieldValue3 = this.Request[hdnFld3Nm];
    }
    protected void Page_PreRender(object sender, EventArgs e)
    {
        // Before the page actually renders, we want to let the .NET page renderer know that we want these three hidden field values written to the output page.
        this.Page.ClientScript.RegisterHiddenField(hdnFld1Nm, this.HiddenFieldValue1 ? "1" : "0");  // Make sure you keep your boolean logic the same.
        this.Page.ClientScript.RegisterHiddenField(hdnFld2Nm, this.HiddenFieldValue2.ToString());   // Hidden fields can only store "string" values, so we have to "ToString" our int.
        this.Page.ClientScript.RegisterHiddenField(hdnFld3Nm, this.HiddenFieldValue3);
    }
}