Preventing the Transfer of Certain Items, Server-Side

1 posts, 0 answers
  1. Golem
    Golem avatar
    21 posts
    Member since:
    Jun 2008

    Posted 26 Nov 2014 Link to this post

    Hi everyone,

    Recently I had a requirement in which the users needed to be able to select items from one sorted RadListBox control (Source) and move them to another RadListBox control (Destination).  In the Destination box, the users also needed to be able to put the items in any order they wanted.  To make matters a little more complicated, the Destination box was pre-populated with some items marked as "required", and the users were not supposed to be able to move those items out of the Destination, but they still needed to be able to re-order the required items as desired.

    I wanted the Source items to remain sorted after any items were moved into or out of it, and this included drag-n-drop operations.  I also wanted the "Transfer All" buttons to work intelligently, so that all items except for the required items were moved accordingly.

    While I saw a number of options to prevent the transfer of certain items client-side, there was no client-side sorting mechanism.  So I decided to implement everything server-side.

    The only real "gotcha" here was implementing the ListBox's "Reordered" event handler.  This was necessary because when doing drag-n-drop operations, the ListBox control does an automatic re-ordering of the items in order to drop the item in the exact position you want it.  Technically, you're really adding an item to the end of the Items collection, so the re-order happens automatically to place the item where you want it.

    In my case, when moving the items from the unsorted ListBox to the sorted ListBox, I had to make sure that the items were sorted AFTER this "Reordered" event fired.  Otherwise, the last item in the list after the manual Sort in the "Transferred" even would be moved to wherever the mouse dropped the original item.  It was a strange effect, but was solved after asking Telerik about the behavior.

    Since it wasn't intuitive to me at first, I thought I'd post the code here for everyone.  Hopefully some of you will find it useful.

    HTML:
    <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
        </telerik:RadScriptManager>
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
            <AjaxSettings>
                <telerik:AjaxSetting AjaxControlID="RadListBox1">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="RadListBox2" UpdatePanelCssClass="" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
                <telerik:AjaxSetting AjaxControlID="RadListBox2">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="RadListBox1" UpdatePanelCssClass="" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
            </AjaxSettings>
        </telerik:RadAjaxManager>
        <table>
            <tr>
                <td>
                    <telerik:RadListBox ID="RadListBox1" runat="server" AllowTransfer="True" TransferToID="RadListBox2"
                        SelectionMode="Multiple" AutoPostBackOnTransfer="true" Width="300px" Height="300px" EnableDragAndDrop="true">
                        <ButtonSettings TransferButtons="All"></ButtonSettings>
                        <Items>
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem1" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem2" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem3" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem4" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem5" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem6" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem7" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem8" />
                            <telerik:RadListBoxItem runat="server" Text="RadListBoxItem9" />
                        </Items>
                    </telerik:RadListBox>
                </td>
                <td>
                    <telerik:RadListBox ID="RadListBox2" runat="server" SelectionMode="Multiple" AllowReorder="true"
                        EnableDragAndDrop="true" Width="300px" Height="300px">
                        <Items>
                            <telerik:RadListBoxItem runat="server" Text="RequiredItem1 (required)" />
                            <telerik:RadListBoxItem runat="server" Text="RequiredItem2 (required)" />
                        </Items>
                    </telerik:RadListBox>
                </td>
            </tr>
        </table>
    </asp:Content>

    Code-Behind:
    private const string REQUIRED_FLAG = "(required)";
     
    protected void Page_Init(object sender, EventArgs e)
    {
        RadListBox1.Transferred += new Telerik.Web.UI.RadListBoxTransferredEventHandler(RadListBox1_Transferred);
        RadListBox1.Transferring += new Telerik.Web.UI.RadListBoxTransferringEventHandler(RadListBox1_Transferring);
        RadListBox1.Reordered += new RadListBoxEventHandler(RadListBox1_Reordered);
    }
     
    protected void Page_Load(object sender, EventArgs e)
    {
    }
     
    void RadListBox1_Transferred(object sender, Telerik.Web.UI.RadListBoxTransferredEventArgs e)
    {
        RadListBox1.Sort = Telerik.Web.UI.RadListBoxSort.Ascending;
        RadListBox1.SortItems();
    }
     
    void RadListBox1_Transferring(object sender, Telerik.Web.UI.RadListBoxTransferringEventArgs e)
    {
        Boolean transferFail = false;
     
        foreach (RadListBoxItem item in e.Items)
        {
            if (item.Text.EndsWith(REQUIRED_FLAG))
            {
                transferFail = true;
                break;
            }
        }
     
        // only do special processing if required fields are in e.Items
        // otherwise, let the Transferring and Transferred events fire normally
        if (transferFail)
        {
            // cancel the event
            // (this also prevents the Transferred event from firing after)
            e.Cancel = true;
            foreach (RadListBoxItem item in e.Items)
            {
                if (!item.Text.EndsWith(REQUIRED_FLAG))
                {
                    //e.SourceListBox.Transfer(item,e.SourceListBox,e.DestinationListBox);
                    e.SourceListBox.Items.Remove(item);
                    e.DestinationListBox.Items.Add(item);
                }
            }
     
            // Since the Transferred event doesn't fire, sort items
            e.DestinationListBox.Sort = RadListBoxSort.Ascending;
            e.DestinationListBox.SortItems();
        }
    }
     
    void RadListBox1_Reordered(object sender, RadListBoxEventArgs e)
    {
        // Needed to sort AFTER the automatic reordering that Telerik does during the drag-n-drop action
        RadListBox1.Sort = Telerik.Web.UI.RadListBoxSort.Ascending;
        RadListBox1.SortItems();
    }

Back to Top