Move items from one Listbox to another using jQuery – Part 2

I have posted earlier on moving items from one ListBox to another. We use jQuery to do that. Listbox posts only the selected values to the server.  In our case, we are not making any selections. But rather moving the Listbox options. We need a way for the server to know that the options have changed. So, I have come up with a solution in this post.

ASP.NET UI

The HTML code is same as before. We move options between Listboxes, list1 and list2. There are four buttons to move the options.

  1. Add: add selected options in list1 to list2
  2. Remove: remove selected options from list2 to list1
  3. Add All: adds all options in list1 to list2
  4. Remove All: removes all options in list2 to list1

In addition, we have two hidden fields. I will explain the use of these hidden fields below.

<asp:ListBox ID="list1" runat="server">
    <asp:ListItem Text="One"></asp:ListItem>
    <asp:ListItem Text="Two"></asp:ListItem>
    <asp:ListItem Text="Three"></asp:ListItem>
</asp:ListBox>
<asp:HiddenField ID="hdn1" runat="server" />
<asp:Button ID="btnAdd" runat="server" Text=">" />
<asp:Button ID="btnAddAll" runat="server" Text=">>" />
<asp:Button ID="btnRemove" runat="server" Text="<"/>
<asp:Button ID="btnRemoveAll" runat="server" Text="<<" />
<asp:ListBox ID="list2" runat="server"></asp:ListBox>
<asp:HiddenField ID="hdn2" runat="server" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click"/>
<asp:Panel ID="pnl" runat="server"></asp:Panel>

jQuery

The jQuery code for moving items is the same as explained in the previous post.

$(document).ready(
function () {
    $('input[name$=btnAdd]').click(
        function (e) {
            $('select[name$=list1] > option:selected').appendTo('select[name$=list2]');
            e.preventDefault();
        });

    $('input[name$=btnAddAll]').click(
        function (e) {
            $('select[name$=list1] > option').appendTo('select[name$=list2]');
            e.preventDefault();
        });

    $('input[name$=btnRemove]').click(
        function (e) {
            $('select[name$=list2] > option:selected').appendTo('select[name$=list1]');
            e.preventDefault();
        });

    $('input[name$=btnRemoveAll]').click(
        function (e) {
            $('select[name$=list2] > option').appendTo('select[name$=list1]');
            e.preventDefault();
        });
});

We have a submit method which does a few extra things. The hidden fields are stored with the Listbox options in a special format.

<selected-value>;<option-1-value>,<option-2-value>,<option-3-value>,

$('input[name$=btnSubmit]').click(
function (e) {
    var hdn1 = $('select[name$=list1] > option:selected').attr('value') + ';';
    $('select[name$=list1] > option').each(
            function () {
                hdn1 += $(this).attr('value') + ',';
            });
    $('input[name$=hdn1]').val(hdn1);
    
    var hdn2 = $('select[name$=list2] > option:selected').attr('value') + ';';
    $('select[name$=list2] > option').each(
            function () {
                hdn2 += $(this).attr('value') + ',';
            });
    $('input[name$=hdn2]').val(hdn2);
});

Server-side syncing

The hidden fields are posted to the server on submit. On the server side, we sync up the state of the ListBox from these hidden fields.

protected void btnSubmit_Click(object sender, EventArgs e)
{
    pnl.Controls.Add(new Literal() { Text = hdn1.Value + "-" + hdn2.Value });

    ListItem [] arr = new ListItem[list1.Items.Count + list2.Items.Count];
    list1.Items.CopyTo(arr, 0);
    list2.Items.CopyTo(arr, list1.Items.Count);
    ListItemCollection coll = new ListItemCollection();
    coll.AddRange(arr);

    PopulateList(list1, hdn1, coll);
    PopulateList(list2, hdn2, coll);
}

private void PopulateList(ListBox list, HiddenField hdn, ListItemCollection coll)
{
    list.Items.Clear();
    string[] str = hdn.Value.Split(new char[] { ';' }, StringSplitOptions.None);
    string sel = str[0];
    string opt = str[1];
    if (!String.IsNullOrEmpty(opt))
    {
        string[] options = opt.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string option in options)
        {
            ListItem li = coll.FindByValue(option);
            if (li != null)
            {
                list.Items.Add(li);
            }
        }
    }

    ListItem li2 = list.Items.FindByValue(sel);
    if (li2 != null)
        li2.Selected = true;
}

There is nothing special about the above code. It is a lot of string parsing. We parse the string within the hidden field. And populate the Listbox options. In addition, we select the list item. The Listbox server control is in sync with the changes on the browser.

Related Posts

Leave a Reply

Your email address will not be published.