Skip to main content
Email Password   helpLost your password?

Screenshot - PersistentReorderList1.jpg

Introduction

This article demonstrates how to use ASP.NET AJAX ReorderList with the ability to retrieve and save changes made to it.

Background

The ReorderList control provides a very smooth cross-browser experience with dragable list items. However, it behaves quite differently from most other controls in the sense that accessing changes made to the list has no in-built property and requires some special treats!

I wanted to show a list to the visitors of my page and let them reorder it as necessary, saving the changed order when the page is submitted. However, while surfing the internet I found it hard to get a clear solution. I hope this article will help someone with similar needs.

Using the code

This article is described in terms of the code. For better understanding, I have divided the code into necessary parts as follows:

  1. The database
  2. The WorkItem and WorkItemsHandler classes
  3. The ReorderList markup code
  4. The EventHandler code

The database

My sample database has only one table named WorkItems with the following sample data:

Screenshot - PersistentReorderList2.jpg


Note that the Priority column determines the initial presentation order.

The WorkItem and WorkItemsHandler classes

/////////////////////////////////////////////

/// Code fragment from App_Code/WorkItem.cs 

/////////////////////////////////////////////

public class WorkItem
{
    public WorkItem(int itemID, int priority, 
        string title, string description)
    {
        _ItemID         = itemID;
        _Priority       = priority;
        _Title          = title;
        _Description    = description;
    }

    private int _ItemID;
    public int ItemID
    {
        get { return _ItemID;  }
        set { _ItemID = value;  }
    }

    private int _Priority;
    public int Priority
    {
        get { return _Priority; }
        set { _Priority = value; }
    }

    private string _Title;
    public string Title
    {
        get { return _Title; }
        set { _Title = value; }
    }

    private string _Description;
    public string Description
    {
        get { return _Description; }
        set { _Description = value; }
    }

    public override string ToString()
    {
        return string.Format(
        "Item: ID:{0}\tPriority:{1}\tTitle{2}\tDecription{3}", 
        _ItemID, _Priority, _Title, _Description);
    }
}

/////////////////////////////////////////////

/// Code fragment from App_Code/WorkItemsHelper.cs 

/////////////////////////////////////////////

public class WorkItemsHelper
{    
    //Loads the Work items to the Session Scope

    public static void LoadWorkItems()
    {        
        HttpContext.Current.Session["WorkItems"] =  
            WorkItemsHelper.GetWorkItems();
    }
    //Returns the WorkItems - either from database or 

    //from Session scope (if its there!)

    public static List<WorkItem> GetWorkItems()
    {
        if (HttpContext.Current.Session["WorkItems"] == null)
        {

            DataTable table = new WorkItemsTableAdapter().GetWorkItems();
            List<WorkItem> workItems = new List<WorkItem>();
            foreach (DataRow row in table.Rows)
            {
                workItems.Add(new WorkItem(
                    int.Parse(row["ItemID"].ToString()),
                    int.Parse(row["Priority"].ToString()),
                    row["Title"].ToString(),
                    row["Description"].ToString()));
            }
            return workItems;
        }
        return (List<WorkItem>)HttpContext.Current.Session["WorkItems"];
    }
    //Save the workItems to the SessionScope

    public static void SaveWorkItems(List<WorkItem> workItems)
    {
        HttpContext.Current.Session["WorkItems"] = workItems;
    }
}

The ReorderList markup code

<div class="ClsReorderListContainer">
    <ajaxToolkit:ReorderList ID="rlWorkItems" runat="server" 
        DragHandleAlignment="Left"
        ItemInsertLocation="Beginning" DataKeyField="ItemID" 
        SortOrderField="Priority"
        EnableViewState="true" OnItemReorder="rlWorkItems_ItemReorder" 
        CallbackCssStyle="ClsCallBackStyle">
        <ItemTemplate>
            <div class="ClsItemArea">
                <table style="width: 100%;">
                    <tr>
                        <td class="ClsItem">
                            <asp:Label ID="Title" runat="server" 
                                Text='<%# Eval("Title") %>'></asp:Label>
                            <asp:Label ID="Description" runat="server" 
                                Text='<%# Eval("Description") %>'></asp:Label>
                        </td>
                    </tr>
                </table>
            </div>
        </ItemTemplate>
        <ReorderTemplate>
            <asp:Panel ID="Panel2" runat="server" CssClass="ClsReorderCue">
            </asp:Panel>
        </ReorderTemplate>
        <DragHandleTemplate>
            <div class="ClsDragHandle">
            </div>
        </DragHandleTemplate>
    </ajaxToolkit:ReorderList>
</div>

The EventHandler code

The sample application takes care of the following events in order to function properly.

Session_Start

Session_Start loads the WorkItems into the current session, as follows:

void Session_Start(object sender, EventArgs e) 
{
    // Load WorkItems to the current session.

    WorkItemsHelper.LoadWorkItems();
}

Page_Load

Page_Load binds the ReorderList with data each time the page is loaded:

protected void Page_Load(object sender, EventArgs e)
{
    //Bind the ReorderList - its a must

    rlWorkItems.DataSource = WorkItemsHelper.GetWorkItems();
    rlWorkItems.DataBind();
}

rlWorkItems_ItemReorder

rlWorkItems_ItemReorder saves the order as it is changed by the client:

protected void rlWorkItems_ItemReorder(object sender, 
    AjaxControlToolkit.ReorderListItemReorderEventArgs e)
{
    //Item Reordered, so save the current order to the Session scope

    WorkItemsHelper.SaveWorkItems((List<WorkItem>)rlWorkItems.DataSource);
}

btnSubmit_Click

btnSubmit_Click shows the new order to the browser:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    //Show the current order

    divMessage.InnerHtml = "New Order <hr />";
    foreach (WorkItem item in WorkItemsHelper.GetWorkItems())
    {
        divMessage.InnerHtml += item.ToString()+"<br />";
    }
}

Important issues

  1. ReorderList's DataSource expects an implementation of IList. So, if you supply it a DataTable instead, it will behave unexpectedly. It will show up for the first time, but will throw exceptions on subsequent post-backs.
  2. One can choose Application collection (HttpContext.Current.Application) or Cache (HttpContext.Current.Cache) instead of the Session if applicable.
  3. OnItemReorder must be registered and persistence mechanism must take place on this event handling routine.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralThanks for sharing Pin
GreggS
8:27 29 Nov '07  
Generalvb reorderlist Pin
mmm!@#
16:36 24 Sep '07  
AnswerRe: vb reorderlist Pin
S. M. SOHAN
18:54 24 Sep '07  
GeneralAwesome! Pin
keith_fra
8:53 24 Jul '07  
Generaldatasource = null Pin
corymillican
13:06 13 Jul '07  
GeneralRe: datasource = null Pin
expinch
11:54 28 Sep '07  
GeneralRe: datasource = null Pin
Programmers
17:14 9 Oct '07  
AnswerRe: datasource = null Pin
chrcha
6:10 14 Nov '07  
QuestionRe: datasource = null Pin
Fantini
4:01 1 Feb '08  
GeneralGood Post Pin
kazimanzurrashid
11:03 1 Jul '07  
GeneralRe: Good Post Pin
S. M. SOHAN
7:47 3 Jul '07  
GeneralRe: Good Post Pin
keith_fra
11:26 25 Jul '07  


Last Updated 29 Jun 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009