Click here to Skip to main content
15,881,281 members
Articles / Web Development / HTML
Article

Persisting changes made to the ASP.NET AJAX ReorderList

Rate me:
Please Sign up or sign in to vote.
3.45/5 (8 votes)
23 Jun 2007CPOL2 min read 96.9K   572   27   22
The ASP.NET AJAX ReorderList has no in-built property to retrieve the changes made in the client side. This article shows a workaround to this problem.

Screenshot - PersistentReorderList1.jpg

Introduction

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

Background

The ReorderList control provides a very smooth cross-browser experience with draggable list items. However, it behaves quite differently than most other controls in the sense that, accessing changes made to the list is not a built-in feature and requires some special treats! I wanted to show a list of visitors on my page, reorder it as necessary, and save the changed order when the page is submitted. However, 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, and 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

1. The database

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

The ReorderList Order Saved

Note: The Priority column determines the initial presentation order (ascending).

2. The WorkItem and WorkItemsHelper classes

C#
/////////////////////////////////////////////
/// 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 Session Scope

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

3. The ReorderList markup code

ASP.NET
<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>

4. The EventHandler code

This sample application takes care of the following events to function properly:

  • Session_Start: Loads the WorkItems to the current session.
  • C#
    void Session_Start(object sender, EventArgs e) 
    {
        // Load WorkItems to the current session.
    
        WorkItemsHelper.LoadWorkItems();
    }
  • Page_Load: Binds the ReorderList with data each time the page is loaded.
  • C#
    protected void Page_Load(object sender, EventArgs e)
    {
        //Bind the ReorderList - its a must
    
        rlWorkItems.DataSource = WorkItemsHelper.GetWorkItems();
        rlWorkItems.DataBind();
    }
  • rlWorkItems_ItemReorder: Saves the new order as it is changed at the client.
  • C#
    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: Shows the new order to the browser.
  • C#
    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

  • The ReorderList's DataSource expects an implementation of IList. So, supplying it a DataTable instead will behave unexpectedly and show up and error for the first time, but only throws exceptions on subsequent postbacks.
  • One can choose the Application collection (HttpContext.Current.Application) or the Cache (HttpContext.Current.Cache) instead of the Session, if applicable.
  • OnItemReorder must be registered, and the persistence mechanism must take place on this event handling routine.

History

  • June 24, 2007 - initial composition date.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other ThoughtWorks
Canada Canada
Consultant
Read my blog at http://smsohan.blogspot.com

Comments and Discussions

 
GeneralProject Files Pin
prontoo12323-Apr-09 23:50
prontoo12323-Apr-09 23:50 
QuestionEdit and Delete the Description Pin
sutha274-Nov-08 12:50
sutha274-Nov-08 12:50 
AnswerRe: Edit and Delete the Description Pin
S. M. SOHAN4-Nov-08 16:01
S. M. SOHAN4-Nov-08 16:01 
Generalpersist reorder without a postback Pin
RobertBroomandan12-Aug-08 13:30
RobertBroomandan12-Aug-08 13:30 
GeneralRe: persist reorder without a postback Pin
S. M. SOHAN12-Aug-08 17:52
S. M. SOHAN12-Aug-08 17:52 
GeneralRe: persist reorder without a postback Pin
RobertBroomandan13-Aug-08 6:46
RobertBroomandan13-Aug-08 6:46 
GeneralRe: persist reorder without a postback Pin
shanesawyer24-Oct-08 12:36
shanesawyer24-Oct-08 12:36 
QuestionNice work but how is the data persisted? Pin
bevans197527-Mar-08 10:20
bevans197527-Mar-08 10:20 
Generalnice one! Pin
Alan Kirk29-Dec-07 18:11
Alan Kirk29-Dec-07 18:11 
GeneralDelete/Edit in ReorderList Pin
engern11-Dec-07 22:50
engern11-Dec-07 22:50 
GeneralHuge problem Pin
t3hr3ap3r1-Nov-07 6:53
t3hr3ap3r1-Nov-07 6:53 
GeneralRe: Huge problem Pin
justinsaraceno18-Jul-08 8:12
justinsaraceno18-Jul-08 8:12 
GeneralThanks! Pin
Daniel Niklasson26-Oct-07 3:01
Daniel Niklasson26-Oct-07 3:01 
General_ItemReorder Event Handler [modified] Pin
expinch26-Sep-07 7:53
expinch26-Sep-07 7:53 
GeneralRe: _ItemReorder Event Handler Pin
Daniel Niklasson26-Oct-07 3:02
Daniel Niklasson26-Oct-07 3:02 
GeneralRe: _ItemReorder Event Handler Pin
expinch26-Oct-07 4:13
expinch26-Oct-07 4:13 
GeneralRe: _ItemReorder Event Handler Pin
wakefib8-Nov-07 2:35
wakefib8-Nov-07 2:35 
GeneralRe: _ItemReorder Event Handler Pin
expinch8-Nov-07 3:54
expinch8-Nov-07 3:54 
GeneralRe: _ItemReorder Event Handler Pin
S. M. SOHAN4-Nov-08 16:08
S. M. SOHAN4-Nov-08 16:08 
GeneralRe: _ItemReorder Event Handler Pin
eneg12-Nov-09 13:12
eneg12-Nov-09 13:12 
GeneralRe: _ItemReorder Event Handler Pin
S. M. SOHAN12-Nov-09 13:57
S. M. SOHAN12-Nov-09 13:57 
GeneralDB Structure Pin
eldeejay22-Aug-07 23:54
eldeejay22-Aug-07 23:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.