【问题标题】:Setting hidden input value in Javascript, then accessing it in codebehind在 Javascript 中设置隐藏的输入值,然后在代码隐藏中访问它
【发布时间】:2011-02-10 20:02:59
【问题描述】:

我一直在尝试使用 Javascript 设置隐藏输入的值,然后从我的 C# 代码隐藏中访问该值。当我运行下面复制的代码时,分配给assignedIDs 的值是“”,我假设它是隐藏输入的默认值。如果我在 html 标记中手动设置值,那么 assignIDs 会设置为该值。

这种行为向我表明输入的值在 onClientClick 和 onClick 事件触发之间被重置(重新渲染?)。

我将不胜感激有关此事的任何帮助。我花了几个小时试图解决一个看似非常简单的问题。

html/javascript:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Admin Page - Manage Tasks</title>
    <script language="javascript" type="text/javascript">
        function PopulateAssignedIDHiddenInput() {
            var source = document.getElementById('assignedLinguistListBox');
            var s = "";
            var count = source.length;
            for (var i = count - 1; i >= 0; i--) {
                var item = source.options[i];
                if (s == "") { s = source.options[i].value; }
                else { s = s.concat(",",source.options[i].value); }
            }
            document.getElementById('assignedIDHiddenInput').Value = s;
            // I have confirmed that, at this point, the value of
            // the hidden input is set properly
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Panel id="EditMode" runat="server">
            <table style="border: none;">
                <tr>
                    <td>
                        <asp:Label ID="availableLinguistLabel" runat="server" Text="Available"></asp:Label><br />
                        <asp:ListBox ID="availableLinguistListBox" runat="server" Rows="10" SelectionMode="Multiple"></asp:ListBox>
                    </td>
                    <td>
                        <input type="button" name="right" value="&gt;&gt;"
                            onclick="Javascript:MoveItem('availableLinguistListBox', 'assignedLinguistListBox');" /><br /><br />
                        <input type="button" name="left" value="&lt;&lt;"
                            onclick="Javascript:MoveItem('assignedLinguistListBox', 'availableLinguistListBox');" />
                    </td>
                    <td>
                        <asp:Label ID="assignedLinguistLabel" runat="server" Text="Assigned To"></asp:Label><br />
                        <asp:ListBox ID="assignedLinguistListBox" runat="server" Rows="10" SelectionMode="Multiple"></asp:ListBox>
                    </td>
                </tr>
            </table>
            //-snip-
            <asp:Button ID="save_task_changes_button" runat="server" ToolTip="Click to save changes to task"
                Text="Save Changes" OnClick="save_task_changes_button_click" OnClientClick="Javascript:PopulateAssignedIDHiddenInput()" />
        </asp:Panel>

        <!-- Hidden Inputs -->
        <!-- Note that I have also tried setting runat="server" with no change -->
        <input id="assignedIDHiddenInput" name="assignedIDHiddenInput" type="hidden" />
    </div>
    </form>
</body>

c#

protected void save_task_changes_button_click(object sender, EventArgs e)
{
    string assignedIDs = Request.Form["assignedIDHiddenInput"];
    // Here, assignedIDs == ""; also, Request.Params["assignedIDHiddenInput"] == ""
    // -snip-
}

【问题讨论】:

    标签: c# asp.net javascript html


    【解决方案1】:

    在 javascript 中,您需要将 value 属性设为小写,如下所示:

    document.getElementById('assignedIDHiddenInput').value = s;
    

    那么它就会被正确设置:) You can see an example in action here

    虽然如果你提醒.Value 它会显示你的价值,你实际上已经添加了一个 .Value 属性,但是你还没有设置输入的.value 属性,它是发布到服务器的内容。上面的示例链接说明了这两种方式。

    你也可以让它更快一点,特别是如果你有很多选择,使用数组而不是字符串连接,像这样:

    var source = document.getElementById('assignedLinguistListBox');
    var opts = [];
    for (var i = 0; i < source.options.length; i++) {
        opts.push(source.options[i].value);
    }
    var s = opts.join(',');
    

    编辑: 更新了上面的代码,CMS 是正确的,以前的方法是依赖于浏览器的,现在上面的行为应该一致了。此外,如果jQuery 是一个选项,还有更短的方法可以获取此信息,如下所示:

    var s = $('#assignedLinguistListBox option').map(function() { 
              return this.value; 
            }).get().join(',');
    $('#assignedIDHiddenInput').val(s);
    

    You can see a working example of this here

    【讨论】:

    • 哦...哇。我简直不敢相信!如此愚蠢而简单的错误。谢谢你,尼克!
    • for...in 语句迭代options HTMLOptionsCollection 对象会给你带来意想不到的结果,在某些浏览器中,即使是数字选项索引也不会被迭代,我会推荐一个普通的@ 987654338@循环,检查this example
    • @CMS - 关于浏览器依赖性的重要观点,在这里也习惯了each 闭包。我更新了上面的代码,以防其他人以后遇到需要相同的信息。
    • 是的,我认为对于 array-like 对象(如 DOM 集合)应该避免使用 for...in 语句,其真正目的是迭代数字索引而不是枚举对象属性(即使知道这些索引是属性),此外,对于 host objects,您永远无法确定您会找到哪些属性...顺便说一句,这是一篇关于该主题的好文章:Iteration VS Enumeration
    【解决方案2】:

    我假设这里是 ASP.NET。

    如果是这样,您的问题是 ASP.NET 生成的 HTML 中控件的 ID 不会是您在脚本中引用的“assignedIDHiddenInput”。 ASP.NET 在呈现 HTML 之前以声明方式在 HTML 页面中指定的内容更改了这些内容。在页面上查看源代码,您会明白我的意思。

    这是一种解决方法:

    document.getElementById('<%=assignedIDHiddenInput.ClientID %>').value = s;
    

    更新:如 cmets 中所述,这仅在控件设置为 RunAt=Server 时才相关。

    【讨论】:

    • 这不是问题,他的输入不是runat="server"
    • 我一直以为只有“runat=server”才会给你分配一个clientid?
    • 好点。他提到了“ ” 所以我认为他可能希望以这种方式运行它,但他的服务器端代码使用“ Request.Form["assignedIDHiddenInput"] 所以这可能是一个有争议的问题。
    • 约翰,感谢您的意见。我忘了提到我也尝试过以这种方式处理输入。非常感谢!
    【解决方案3】:

    我认为 ASP.NET 正在调用 javascript 以在该控件上执行回发之前您的 javascript 函数被调用以填充该隐藏值。

    我认为可以禁用默认回发并自己处理,但我相信其他人可以提供更好的建议。

    在你的函数中粘贴一个 alert() 以查看它是否真的在触发回发之前被调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 2018-08-23
      • 1970-01-01
      • 2012-02-23
      相关资源
      最近更新 更多