Click here to Skip to main content
Click here to Skip to main content

Persisting changes made to the ASP.NET AJAX ReorderList

, 23 Jun 2007 CPOL
Rate this:
Please Sign up or sign in to vote.
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

/////////////////////////////////////////////
/// 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

<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.
  • 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.
  • 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.
  • 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.
  • 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)

Share

About the Author

S. M. SOHAN
Other ThoughtWorks
Canada Canada
Consultant
Read my blog at http://smsohan.blogspot.com
Follow on   Twitter

Comments and Discussions

 
GeneralProject Files Pinmemberpronto12323-Apr-09 23:50 
QuestionEdit and Delete the Description Pinmembersutha274-Nov-08 12:50 
AnswerRe: Edit and Delete the Description PinmemberS. M. SOHAN4-Nov-08 16:01 
Generalpersist reorder without a postback PinmemberMember 358207112-Aug-08 13:30 
GeneralRe: persist reorder without a postback PinmemberS. M. SOHAN12-Aug-08 17:52 
GeneralRe: persist reorder without a postback PinmemberRobBroomandan13-Aug-08 6:46 
GeneralRe: persist reorder without a postback Pinmembershanesawyer24-Oct-08 12:36 
QuestionNice work but how is the data persisted? Pinmemberbevans197527-Mar-08 10:20 
Generalnice one! PinmemberAlan Kirk29-Dec-07 18:11 
GeneralDelete/Edit in ReorderList Pinmemberengern11-Dec-07 22:50 
GeneralHuge problem Pinmembert3hr3ap3r1-Nov-07 6:53 
GeneralRe: Huge problem Pinmemberjustinsaraceno18-Jul-08 8:12 
GeneralThanks! PinmemberDaniel Niklasson26-Oct-07 3:01 
General_ItemReorder Event Handler [modified] Pinmemberexpinch26-Sep-07 7:53 
GeneralRe: _ItemReorder Event Handler PinmemberDaniel Niklasson26-Oct-07 3:02 
GeneralRe: _ItemReorder Event Handler Pinmemberexpinch26-Oct-07 4:13 
GeneralRe: _ItemReorder Event Handler Pinmemberwakefib8-Nov-07 2:35 
GeneralRe: _ItemReorder Event Handler Pinmemberexpinch8-Nov-07 3:54 
GeneralRe: _ItemReorder Event Handler PinmemberS. M. SOHAN4-Nov-08 16:08 
GeneralRe: _ItemReorder Event Handler Pinmembereneg12-Nov-09 13:12 
GeneralRe: _ItemReorder Event Handler PinmemberS. M. SOHAN12-Nov-09 13:57 
GeneralDB Structure Pinmembereldeejay22-Aug-07 23:54 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 24 Jun 2007
Article Copyright 2007 by S. M. SOHAN
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid