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:-
- The database
- The
WorkItem
and WorkItemsHandler
classes - The
ReorderList
markup code - The
EventHandler
code
1. The database
My sample database has only one table named WorkItems, with the following sample data:
Note: The Priority
column determines the initial presentation order (ascending).
2. The WorkItem and WorkItemsHelper classes
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);
}
}
public class WorkItemsHelper
{
public static void LoadWorkItems()
{
HttpContext.Current.Session["WorkItems"] =
WorkItemsHelper.GetWorkItems();
}
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"];
}
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 WorkItem
s to the current session.
void Session_Start(object sender, EventArgs e)
{
WorkItemsHelper.LoadWorkItems();
}
Page_Load
: Binds the ReorderList
with data each time the page is loaded.
protected void Page_Load(object sender, EventArgs e)
{
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)
{
WorkItemsHelper.SaveWorkItems((List<WorkItem>)rlWorkItems.DataSource);
}
btnSubmit_Click
: Shows the new order to the browser.
protected void btnSubmit_Click(object sender, EventArgs e)
{
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.