ASP.使用JQuery更新客户端双列表框,以及如何在服务器端检索结果

本文关键字:服务器端 结果 检索 更新 JQuery 使用 客户端 列表 ASP | 更新日期: 2023-09-27 18:09:08

我一直试图得到一个ASP。NET WebForms页面启动并运行,具有双列表框。这是一个标准范例,其中有两个并排的列表框,左边是可用的项,右边是已选择的项,以及将项从一边移动到另一边的按钮。

我希望所有的工作是在客户端完成,通过JQuery(或其他)。并且我希望能够在回发时检索所选项目。

我遇到了各种各样的障碍。以下是一些:

1)当回发发生时,我收到这个错误:

无效的回发或回调参数。事件验证在配置中启用或在页面中使用<%@ Page EnableEventValidation="true" %>。出于安全目的,此功能验证回发或回调事件的参数是否来自最初呈现它们的服务器控件。如果数据是有效且预期的,则使用ClientScriptManager。RegisterForEventValidation方法,以便注册回发或回调数据以进行验证。

关闭"EnableEventValidation"是有风险的。但"ClientScriptManager。" RegisterForEventValidation"很混乱。

2)假设我到达了实际回发发生的点,我的列表框不包含所选的项目。

一个常见的推荐解决方案是在回发之前将选择的值复制到一个隐藏字段中。严重吗?一定有更好的办法。

3)当然,关于客户端脚本应该如何工作的所有细节也令人困惑,尽管不像前两个项目那么糟糕。

那么解决方案是什么呢?我已经把答案贴在下面了

ASP.使用JQuery更新客户端双列表框,以及如何在服务器端检索结果

根据https://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/,不仅可以提问和回答自己的问题,而且还鼓励这样做。这就是我正在做的。

这是我的工作解决方案,之后我会详细说明。请注意,我绝不是web开发或Javascript方面的专家——远非如此。因此,对所有这些都持保留态度,并始终记住,如果您的代码以某种方式设法执行HCF代码,我不负责。

<script>
    function addAllItems() {
        $("#<%= lbAvail.ClientID %> option").appendTo("#<%= lbSelected.ClientID %>");
        enableControls();
    }
    function addSelectedItems() {
        $("#<%= lbAvail.ClientID %> option:selected").appendTo("#<%= lbSelected.ClientID %>");
        enableControls();
    }
    function removeAllItems() {
        $("#<%= lbSelected.ClientID %> option").appendTo("#<%= lbAvail.ClientID %>");
        enableControls();
    }
    function removeSelectedItems() {
        $("#<%= lbSelected.ClientID %> option:selected").appendTo("#<%= lbAvail.ClientID %>");
        enableControls();
    }
    function enableButtons(listBoxControlId, buttonAllControlId, buttonSelectedContolId) {
        var count = $("#" + listBoxControlId + " option").length;
        document.getElementById(buttonAllControlId).disabled = count <= 0;
        count = $("#" + listBoxControlId + " option:selected").length;
        document.getElementById(buttonSelectedContolId).disabled = count <= 0;
    }
    function enableControls() {
        enableButtons("<%= lbAvail.ClientID %>", "<%= btnAddAll.ClientID %>", "<%= btnAddSelected.ClientID %>");
        enableButtons("<%= lbSelected.ClientID %>", "<%= btnRemoveAll.ClientID %>", "<%= btnRemoveSelected.ClientID %>");
    }
    function selectAll() {
        $("#<%= lbSelected.ClientID %> option").prop("selected", true);
    }
</script>
<div style="margin-top: 20px;">
    <table>
        <tr>
            <td>
                <asp:ListBox ID="lbAvail" runat="server" style="min-width: 150px" Height="150" SelectionMode="Multiple" 
                             onchange="enableControls();" ondblclick="addSelectedItems();"/>
            </td>
            <td style="padding-left: 10px; padding-right: 10px;">
                <table>
                    <tr>
                        <td>
                            <asp:Button Width="35" ID="btnAddAll" Text="&raquo;" OnClientClick="addAllItems(); return false;" UseSubmitBehavior="False" runat="server"/>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding-top: 5px">
                            <asp:Button Width="35" ID="btnAddSelected" Text=">" OnClientClick="addSelectedItems(); return false;" UseSubmitBehavior="False" runat="server"/>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding-top: 5px">
                            <asp:Button Width="35" ID="btnRemoveSelected" Text="<" OnClientClick="removeSelectedItems(); return false;" UseSubmitBehavior="False" runat="server"/>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding-top: 5px">
                            <asp:Button Width="35" ID="btnRemoveAll" Text="&laquo;" OnClientClick="removeAllItems(); return false;" UseSubmitBehavior="False" runat="server"/>
                        </td>
                    </tr>
                </table>
            </td>
            <td>
                <asp:ListBox ID="lbSelected" runat="server" style="min-width: 150px" Height="150" SelectionMode="Multiple"
                             onchange="enableControls();" ondblclick="removeSelectedItems();"/>
            </td>
        </tr>
    </table>
    
    <div style="margin-top: 10px;">
        <asp:Button ID="btnSubmit" CssClass="btn btn-primary" Text="Submit" runat="server" OnClientClick="selectAll();"/>
    </div>
</div>

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        lbAvail.Items.Add(new ListItem("Monday", "Mon"));
        lbAvail.Items.Add(new ListItem("Tuesday", "Tues"));
        lbAvail.Items.Add(new ListItem("Wednesday", "Wed"));
        lbAvail.Items.Add(new ListItem("Thursday", "Thur"));
        lbAvail.Items.Add(new ListItem("Friday", "Fri"));
        lbAvail.Items.Add(new ListItem("Saturday", "Sat"));
        lbSelected.Items.Add(new ListItem("Sunday", "Sun"));
        ScriptManager.RegisterStartupScript(this, GetType(), "CallEnableControls", "enableControls()", true);
    }
    else
    {
        string[] selectedValues = Request.Form.GetValues(lbSelected.UniqueID);
        // ...
    }
}
protected override void Render(HtmlTextWriter writer)
{
    // Register all Available items as valid items in the Selected listbox.
    foreach (ListItem item in lbAvail.Items)
    {
        ClientScript.RegisterForEventValidation(lbSelected.UniqueID, item.Value);
    }
    // When a user removes an item from the Selected listbox, we put it into the
    // Available listbox, so we have to register it here, or we'll get an error.
    foreach (ListItem item in lbSelected.Items)
    {
        ClientScript.RegisterForEventValidation(lbAvail.UniqueID, item.Value);
    }
    base.Render(writer);
}

以下是一些解释:

记住"无效的回发或回调参数";错误,我得到的项目从一个列表框移动到另一个,然后张贴页面?这个错误实际上提示了一个事实:ASP。. NET确实在回发数据中包含了修改后的列表框内容。

为了访问修改后的列表框项,我们只需要这一行:

string[] selectedValues = Request.Form.GetValues(lbSelected.UniqueID);

这给了我们一个Selected列表框中值的数组。我们不需要使用隐藏字段或文本框之类的。既然数据被发回给我们,我们不妨使用它。注意,这些是值,而不是显示字符串。

一个重要的注意事项:只有列表框中选中的项目才会被发送回。因此,在上面的标记代码中,您将看到,当Submit按钮被单击时,我调用一些javascript代码来选择Selected列表框中的所有项目(我不关心Available列表框中有什么)。

那么我们如何防止&;Invalid postback或callback参数&;错误,所以我们可以使用这些数据?我们必须告诉ASP。NET哪些值对每个列表框有效。我们使用"ClientScript.RegisterForEventValidation"在"Render()"方法。

ASP。NET已经知道我们最初放置在每个列表框中的值是要返回的有效值。所以我们所要做的就是注册可能返回的其他值。这就是我在register中所做的上面方法。

至于Javascript代码,它应该是相当不言自明的。只要记住它实际上调用了一些JQuery函数,所以显然你必须包含JQuery。

我希望这对你有帮助。我花了一段时间才弄明白,就像我说的,我找不到一个地方能找到所有的答案。当然,一旦我发布了这篇文章,就会有15个人指出我可以在哪里轻松找到这些信息,但这就是生活。