Preface
ReorderList is an ASP.NET AJAX control that implements a bulleted, data-bound list with items that can be reordered interactively. To reorder the items in the list, the user simply drags the item's control bar to its new location. Graphical feedback is shown where the item will be placed as it is dragged by the user. The data source is updated after the item is dropped in its new location.
Sometimes we may need to handle the drag event to change the dragged item's style or popup some message after dropping it to a new location. Firstly, let's dig into the design code to find some useful handlers or events.
Background
// void onDragStart()
onDragStart: function() {
this._validate();
},
add_reorderComplete : function(handler) {
this.get_events().addHandler("reorderComplete", handler);
},
remove_reorderComplete : function(handler) {
this.get_events().removeHandler("reorderComplete", handler);
},
Scenario
Here is a scenario. One customer placed a Command Button inside the ItemTemplate, then he can execute some operation in the server side command event. His target was to changing the selected item's style to specify it when clicking on the command button.
We need to split this goal into points:
- As the events of ReorderList are client side events, we need to change the style at client side.
- The ReorderList creates the DragVisual based on the dragged item including the style, so, we have to recover the original style of the items before dragging or after dropping.
- The command button would make a post back after clicking on it, so, we have to cache the selected item's index in the cookie, then, changing the style after page's reload at client side.
Code
Here is my detail code of this solution:
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="TestChangeStyleWhenClicked.aspx.vb"
Inherits="SoluTest_ReorderList.TestChangeStyleWhenClicked" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="AjaxControlToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
function pageLoad() {
//Find the ReorderList's Client Behavior by accessing this parameter--the ID_dItemEx;
//Then, add a handler to the dragStart and reorderComplete event to recover all the items' original style
$find("ReorderList1_dItemEx").onDragStart = function() {
recoverStyle();
$find("ReorderList1_dItemEx")._validate();
};
$find("ReorderList1_dItemEx").add_reorderComplete(recoverStyle);
if (getCookie()) {
//Change the selected item's style
$get(getCookie()).className = "itemClicked";
}
}
function changeClickedStyle(button) {
//To recover all the items' original style
recoverStyle();
//Change the selected item's style
//$get(button.id.replace('commandButton', 'item')).className = "itemClicked";
setCookie(button.id.replace('commandButton', 'item'));
}
function recoverStyle() {
//To recover all the items' original style
for (i = 0; i < $find("ReorderList1_dItemEx")._element.children.length; i++) {
var item = $get($find("ReorderList1_dItemEx")._element.children[i].id + '_item');
item.className = "itemArea";
}
}
function setCookie(cookieValue) {
sVar = "selectedIndex";
//the default expiration time is 1 minute
var date = new Date();
date.setTime(new Date().getTime() + (60 * 1000));
theCookie = sVar + '=' + cookieValue + '; expires=' + date.toGMTString();
document.cookie = theCookie;
}
function getCookie() {
sVar = "selectedIndex";
cookies = document.cookie.split('; ');
for (var i = 1; i <= cookies.length; i++) {
if (cookies[i - 1].split('=')[0] == sVar) {
return cookies[i - 1].split('=')[1];
}
}
}
style type="text/css">
/*Reorder List*/.dragHandle
{
width: 10px;
height: 15px;
background-color: Blue;
background-image: url(images/bg-menu-main.png);
cursor: move;
border: outset thin white;
}
.callbackStyle
{
border: thin blue inset;
}
.callbackStyle table
{
background-color: #5377A9;
color: Black;
}
.reorderListDemo li
{
list-style: none;
margin: 2px;
background-image: url(images/bg_nav.gif);
background-repeat: repeat-x;
color: #FFF;
}
.reorderListDemo li a
{
color: #FFF !important;
font-weight: bold;
}
.reorderCue
{
border: dashed thin black;
width: 100%;
height: 25px;
}
.itemArea
{
margin-left: 15px;
font-family: Black, Verdana, sans-serif;
font-size: 1em;
text-align: left;
color: Black;
}
.itemClicked
{
margin-left: 15px;
font-family: Arial, Verdana, sans-serif;
font-size: 1em;
background-color: Yellow;
color: Red;
text-align: left;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="reorderListDemo">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<AjaxControlToolkit:ReorderList ID="ReorderList1" runat="server" AllowReorder="True"
DataSourceID="SqlDataSource1" PostBackOnReorder="false" CallbackCssStyle="callbackStyle"
DragHandleAlignment="Left" ItemInsertLocation="Beginning" DataKeyField="ID" SortOrderField="Priority"
Width="400px">
<ItemTemplate>
<asp:Panel runat="server" CssClass="itemArea" ID="item">
<asp:Label ID="Label1" runat="server" Text='<%# HttpUtility.HtmlEncode(Convert.ToString(Eval("USER"))) %>' />
<span>- </span>
<asp:Label ID="lblCategory" runat="server" Text='<%# HttpUtility.HtmlEncode(Convert.ToString(Eval("CATEGORY"))) %>' />
<asp:Button runat="server" ID="commandButton" CommandName="Click" Text="Select to change style" OnClientClick="changeClickedStyle(this);" />
</asp:Panel>
</ItemTemplate>
<ReorderTemplate>
<asp:Panel ID="Panel2" runat="server" CssClass="reorderCue" />
</ReorderTemplate>
<DragHandleTemplate>
<div class="dragHandle">
</div>
</DragHandleTemplate>
</AjaxControlToolkit:ReorderList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Reorder-MasterAndDetailConnectionString1 %>"
DeleteCommand="DELETE FROM [MASTER] WHERE [ID] = ?" InsertCommand="INSERT INTO [MASTER] ([USER], [CATEGORY], [Priority]) VALUES (?, ?, ?)"
ProviderName="<%$ ConnectionStrings:Reorder-MasterAndDetailConnectionString1.ProviderName %>"
SelectCommand="SELECT [ID], [USER], [CATEGORY], [Priority] FROM [MASTER]" UpdateCommand="UPDATE [MASTER] SET [USER] = ?, [CATEGORY] = ?, [Priority] = ? WHERE [ID] = ?">
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="USER" Type="String" />
<asp:Parameter Name="CATEGORY" Type="String" />
<asp:Parameter Name="Priority" Type="Int32" />
<asp:Parameter Name="ID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="USER" Type="String" />
<asp:Parameter Name="CATEGORY" Type="String" />
<asp:Parameter Name="Priority" Type="Int32" />
</InsertParameters>
</asp:SqlDataSource>
</div>
</form>
</body>
</html>
Note
This is only a particular sample to handle the drag/drop event. You can modify it based on your own request. Feel free to discuss this UI with me here or in the ASP.NET Ajax Forum.
The related thread url: http://forums.asp.net/t/1380407.aspx