【问题标题】:Moving items from one ListBox to another and getting items in ListBox将项目从一个 ListBox 移动到另一个 ListBox 并获取 ListBox 中的项目
【发布时间】:2012-10-11 11:47:26
【问题描述】:

我有一个 ASP.NET 向导控件。第二步,我有两个 ListBox;页面加载时从服务器填充第一个 ListBox 项。

然后用户从 ListBox1 中选择数据并将其移动到 ListBox2。然后,用户单击向导的下一步按钮。不知何故,当用户单击下一步时,ListBox2 为空。

我使用 jQuery 将数据从 ListBox1 移动到 ListBox2。

<td class="style9">
                <asp:ListBox ID="registerCompCats" runat="server" CssClass="ListBox1"
                ClientIDMode="Static" DataTextField="value" DataValueField="key"
                Rows="5" size="5" style="width:135px; size:5px;" SelectionMode="Multiple" ></asp:ListBox>
                    &nbsp;&nbsp;&nbsp;</td>
                <td class="style1">
                    <table>
                        <tr>
                            <td style="padding-left: 20px;">
                                <img id="addCat" onclick="return addCat_onclick()" 
                        src="images/buttons/btn_addCat.jpg" title="Add Category" />
                            </td>
                        </tr>
                        <tr>
                            <td style="padding-left: 20px;">
                                <img id="removeCat" 
                        src="images/buttons/btn_removeCat.jpg" title="Remove Category" />
                            </td>
                        </tr>
                    </table>
                </td>
                <td>
                <asp:ListBox ID="registerCompAcats" runat="server" CssClass="ListBox2"
                ClientIDMode="Static" DataTextField="value" DataValueField="key"
                Rows="5" size="5" style="width:135px; size:5px; margin-top: 0px;" SelectionMode="Multiple" ></asp:ListBox>
                    &nbsp;<asp:RequiredFieldValidator ID="registerCompAcatsValidator" runat="server" 
                        ControlToValidate="registerCompAcats" Display="None" ErrorMessage="categories"></asp:RequiredFieldValidator></td>

【问题讨论】:

    标签: jquery html asp.net viewstate eventvalidation


    【解决方案1】:

    事件验证

    如果您在客户端使用列表框和/或下拉列表的可用选项(即使用 jQuery 或其他方式),内置的 ASP .NET 表单验证(称为“事件验证”)将启动并抛出异常,因为您提交的表单与最初呈现控件时所提供的选项不同。要解决此问题,您必须在 .aspx 页面顶部执行此操作:

    <%@ Page EnableEventValidation="false" %>
    

    请记住,如果您这样做,您需要自己对下拉列表和列表框执行表单验证。

    视图状态

    每次将页面回传到服务器时,这些控件都有 0 个选项。是的,您在 HTML 中看到了选项,但在服务器上,它们开始时只有 0 个选项。如果您在这些控件上启用了视图状态,则在页面生命周期中,ASP .NET 框架将自动添加上一页面呈现中存在的选项。这意味着由于registerCompAcats控件在第一个页面渲染中没有选择,所以当页面回传到服务器时,它仍然没有任何选择。

    这些asp:ListBox 控件在HTML 中呈现为&lt;select&gt; 元素。这些工作的方式是他们将在这些列表框中选择的值发布到服务器。这意味着无论选择什么,您都只会知道用户在表单帖子的这些列表框中选择的项目。

    可能的解决方案

    有几种方法可以解决这个问题。我将概述一对。

    方法一:回发将项目添加到其他列表框

    这可能是最简单但效率最低的。每次用户单击“添加类别”按钮时,您可能会导致页面回发,而不是使用 jQuery 将项目从一个列表框移动到另一个列表框。这允许服务器端代码控制每个框中的选择,并且视图状态对您有利。您还可以在页面上重新启用事件验证,这通常是个好主意。

    <asp:ListBox id="lb1" runat="server" />
    <asp:Button id="btnAdd" runat="server" />
    <asp:ListBox id="lb2" runat="server" />
    

    对于 btnAdd.Click 事件:

    Sub btnAdd_Click(sender As Object, args As EventArgs) Handles btnAdd.Click
    
      lb2.Items.AddRange(lb1.Items.Where(Function(i) i.Selected).ToArray())
    
    End Sub
    

    方法二:使用jQuery添加项目;在提交之前操纵帖子

    您需要像上面解释的那样为此关闭事件验证。使用 jQuery 将项目从一个列表移动到另一个列表 - 这很好。但是,在您实际在页面上进行回发之前,您将使用 jQuery 收集第二个列表框中的所有值并将这些值放入隐藏字段 runat="server"

    <asp:ListBox id="lb1" runat="server" />
    <input type="button" value="Add" onclick="addCategory();" />
    <asp:ListBox id="lb2" runat="server" />
    <input type="hidden" id="hdnSelectedCategories" runat="server" />
    <asp:Button id="btnSubmit" runat="server" onclientclick="preSubmit();" />
    

    jQuery 部分:

    <script type="text/javascript">
    
      var lb1, lb2, hdnSelectedCategories;
    
      $(function() {
        lb1 = $('#<%=lb1.ClientID %>');
        lb2 = $('#<%=lb2.ClientID %>');
        hdnSelectedCategories = $('#<%=hdnSelectedCategories.ClientID %>');
      });
    
      function addCategory() {
        lb2.append(lb1.find('option:selected'));
      }
    
      function preSubmit() {
        // collect all the values from the lb2 listbox into an array
        var values = [];
        lb2.find('option').each(function(index, item) {
          values.push($(item).val());
        });
        // now put the contents of the array in the hidden input, separated by commas
        hdnSelectedCategories.val(values.join(','));
      }
    </script>
    

    现在在您的代码中,用于 btnSubmit.Click 事件:

    Sub btnSubmit_Click(sender As Object, args As EventArgs) Handles btnSubmit.Click
    
      Dim values As String() = hdnSelectedCategories.Value.Split(",")
    
      'TODO: Profit'
    
    End Sub
    

    在这种方法中,您可能还希望关闭列表框上的 Viewstate,因为它会使请求膨胀,并且会在用户单击“提交”按钮后重置您的列表框。

    免责声明

    我对这段代码进行了极少的测试——这只是我的想法。但希望对事件验证、视图状态和回发页面生命周期的解释能够帮助您了解实际发生的情况,并且您可以提出适合您情况的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-07
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2016-06-03
      • 2017-05-06
      相关资源
      最近更新 更多