0

我有一个在 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" />

代码隐藏片段:

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

**

4

3 回答 3

0

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

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

学分归于解决方案的原始海报 (Anton Belev)。

于 2013-09-06T19:02:41.410 回答
0

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

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

于 2013-09-10T18:32:31.150 回答
0

我知道这是旧的,但是,以防万一其他人像我一样遇到这种情况,我想提供一个替代 Tim 的答案,即使用 cookie 来跟踪客户端和服务器端之间的状态。

如果您有一些需要能够读取值的 javascript,例如特定控件是否已在客户端显示/隐藏,而不是使用 cookie,我建议您以相同的方式创建自己的视图状态.NET 可以。

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

下面的示例显示了一个布尔值、整数和字符串,但同样的方法可以用于任何可以序列化和反序列化到“字符串”值的数据类型。

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);
    }
}
于 2015-06-12T16:55:40.893 回答