将项目从一个ListBox移动到另一个ListBox并获取ListBox中的项目

时间:2012-10-11 11:47:27

标签: jquery asp.net html viewstate event-validation

我有一个ASP向导控件。在我的第二步,我有两个列表框,当页面加载时,第一个列表框项从服务器填充。

用户然后从ListBox One中选择数据并将其移动到ListBox2。然后单击wizzard的NEXT按钮。不知何故,当用户点击下一步时,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>

1 个答案:

答案 0 :(得分:2)

事件验证

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

<%@ Page EnableEventValidation="false" %>

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

视图状态

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

这些asp:ListBox控件在HTML中呈现为<select>个元素。这些工作的方式是它们只向在服务器上发布在这些列表框中选择的值。这意味着无论选择什么,您只会知道用户在表单帖子的这些列表框中选择的项目。

可能的解决方案

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

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

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

<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

方法2:使用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,因为它会为请求添加膨胀,并在用户单击“提交”按钮后重置列表框。

声明

我对这段代码的测试非常简单 - 它只是我的头脑。但希望事件验证,视图状态和回发页面生命周期的解释将帮助您了解实际情况,并且您可以提出适合您情况的解决方案。