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

Realtime Reordering Using the ASP.NET AJAX Control Toolkit’s ReorderList Control with LINQ to SQL

, 3 Sep 2008
Rate this:
Please Sign up or sign in to vote.
An article on using LINQ to SQL with the ASP.NET AJAX Control Toolkit’s ReorderList control.

Introduction

The ReorderList is a very powerful piece of the ASP.NET AJAX Control Toolkit. It gives you the ability to interactively reorder a list of items.

Article.jpg

The Problem

I put together this demonstration to go over how to wire the ASP.NET AJAX Toolkit’s ReorderList control to a LINQ to SQL data source. Out of the box, the ReorderList control gives you the ability to easily reorder items in a list on the client side. Where I found it fell short was in how the reordering changes that you make get committed back to the database.

The Solution

I created a fairly straightforward way to commit reordering changes back to the database at the time the reorder event takes place. In doing this, the reordering changes you make get committed to the database in real-time, as opposed to making a bunch of changes and clicking a Reorder button. I believe this is a much better way of doing it because there is a lower chance of changes getting lost, and this helps resolve contention issues in a multi-user reordering scenario.

The web page:

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="RealtimeReorderList.aspx.cs"
    Inherits="RealtimeReorderlist.RealtimeReorderList" %>

<%@ Register Assembly="AjaxControlToolkit" 
  Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!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">
    <link rel="Stylesheet" type="text/css" 
       href="ReorderList.css" />
    <title>Realtime Reorderable List Using LINQ to SQL</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <fieldset>
                    <legend>Reorderable List Items</legend>
                    <div style="width: 850px">
                        <div class="reorderListDemo" 
                               style="padding-bottom: 50px">
                            <ajaxToolkit:ReorderList ID="rlItemList" 
                                  DragHandleAlignment="Left" 
                                  PostBackOnReorder="true"
                                  CallbackCssStyle="callbackStyle" 
                                  ItemInsertLocation="End" 
                                  ShowInsertItem="false"
                                  runat="server">
                                <DragHandleTemplate>
                                    <div class="dragHandle">
                                    </div>
                                </DragHandleTemplate>
                                <ItemTemplate>
                                    <div class="itemArea">
                                        <span style="float: right">
                                            <asp:Button Width="50" ID="Button3" 
                                              CommandName="Delete" 
                                              runat="server" Text="Delete" />
                                        </span>
                                        <asp:Label ID="ID" Visible="false" 
                                          runat="server" 
                                          Text='<%# Eval("ID") %>'></asp:Label>

                                        <asp:Label ID="Order" Visible="false" 
                                          runat="server" 
                                          Text='<%# Eval("ListOrder") %>'></asp:Label>
                                        <asp:Label ID="Name" runat="server" 
                                          Text='<%# Eval("Name") %>'></asp:Label>:  
                                        <asp:Label ID="Label1" runat="server" 
                                          Text='<%# Eval("Description") %>'></asp:Label>
                                    </div>
                                </ItemTemplate>
                                <ReorderTemplate>
                                    <asp:Panel ID="Panel2" runat="server" 
                                       CssClass="reorderCue" />
                                </ReorderTemplate>
                            </ajaxToolkit:ReorderList>
                        </div>
                    </div>
                </fieldset>
                <fieldset>
                    <legend>Add List Item</legend>
                    <div>
                        <asp:TextBox ID="tbItemName" 
                                 runat="server"></asp:TextBox>
                        <ajaxToolkit:TextBoxWatermarkExtender ID="TBWE1" 
                            runat="server" TargetControlID="tbItemName"
                            WatermarkText="Name" 
                            WatermarkCssClass="watermarkTextBox" />
                    </div>
                    <div>
                        <asp:TextBox Rows="4" ID="tbItemDescription" 
                          runat="server" Height="51px" 
                          TextMode="MultiLine"></asp:TextBox>
                        <ajaxToolkit:TextBoxWatermarkExtender ID="TBWE2" 
                          runat="server" 
                          TargetControlID="tbItemDescription"
                          WatermarkText="Description" 
                          WatermarkCssClass="watermarkTextBox" />
                    </div>
                    <div>
                        <asp:Button ID="btnAddReorderListItem" 
                          runat="server" Text="Add" 
                          OnClick="AddReorderListItem_Click" />
                    </div>
                </fieldset>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

The code-behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;

namespace RealtimeReorderlist
{
    public partial class RealtimeReorderList : System.Web.UI.Page
    {
        protected int NewListOrderNumber;
        protected List<reorderlistitem> ListDataItems;

        protected void Page_Load(object sender, EventArgs e)
        {

            rlItemList.ItemReorder += new EventHandler<reorderlistitemreordereventargs>
                                          (rlItemList_ItemReorder);

            // Event handler for deleting items from the list
            rlItemList.ItemCommand += new EventHandler<reorderlistcommandeventargs>
                                          (rlItemList_ItemCommand);

            GetListData();
            if (!Page.IsPostBack)
                BindData();
        }


        /// <summary>
        /// Reorder list items in the database when a reorder event occurs
        /// </summary>
        protected void rlItemList_ItemReorder(object sender, 
                       ReorderListItemReorderEventArgs e)
        {
            var NewOrder = e.NewIndex + 1;
            var OldOrder = e.OldIndex + 1;

            var ReorderListItemID = Convert.ToInt32(((Label)(
                e.Item.FindControl("ID"))).Text);

            var db = new RealTimeReorderListDataDataContext();

            var ListItemCount = 1;

            var ListData = from ld in db.ReorderListItems
                           orderby ld.ListOrder
                           select ld;
            foreach (var ListDataItem in ListData)
            {
                // Move forward items in this range
                if (OldOrder > NewOrder
                    && ListItemCount >= NewOrder
                    && ListItemCount <= OldOrder
                    )
                    ListDataItem.ListOrder = ListItemCount + 1;
                // Move backward items in this range
                else if
                    (OldOrder < NewOrder
                    && ListItemCount <= NewOrder
                    && ListItemCount >= OldOrder
                    )
                    ListDataItem.ListOrder = ListItemCount - 1;

                ListItemCount++;

                // Set the changed item into the newly numerical gap
                if (ListDataItem.ID == ReorderListItemID)
                    ListDataItem.ListOrder = NewOrder;
            }

            db.SubmitChanges();

            GetListData();
            BindData();
        }


        /// <summary>
        /// ItemCommand event used to delete list items
        /// </summary>
        void rlItemList_ItemCommand(object sender, ReorderListCommandEventArgs e)
        {
            // If you want support for multiple commands
            if (e.CommandName != "Delete")
                return;

            var db = new RealTimeReorderListDataDataContext();

            var ListData = from ld in db.ReorderListItems
                           where ld.ID == Convert.ToInt32(((Label)
                              (e.Item.FindControl("ID"))).Text)
                           select ld;
            db.ReorderListItems.DeleteAllOnSubmit(ListData);
            db.SubmitChanges();
            GetListData();
            BindData();
        }


        /// <summary>
        /// Add button click event used to inset a new list item into the database
        /// </summary>
        protected void AddReorderListItem_Click(object sender, EventArgs e)
        {
            GetListData(); // Get the current NewListOrderNumber
            var db = new RealTimeReorderListDataDataContext();
            var RLI = new ReorderListItem
            {
                ListOrder = NewListOrderNumber,
                Name = tbItemName.Text,
                Description = tbItemDescription.Text
            };
            db.ReorderListItems.InsertOnSubmit(RLI);
            db.SubmitChanges();
            
            // Clear the form values so that watermark shows
            tbItemName.Text = "";
            tbItemDescription.Text = "";

            GetListData(); //Get the list with the newly inserted item
            BindData();

        }

        /// <summary>
        /// Retrieve the list items from the database
        /// </summary>
        protected void GetListData()
        {
            var db = new RealTimeReorderListDataDataContext();
            var ListData = from ld in db.ReorderListItems
                           orderby ld.ListOrder
                           select ld;
            ListDataItems = ListData.ToList();
            NewListOrderNumber = ListDataItems.Count() + 1;
        }

        /// <summary>
        /// Bind the data the to the ReorderList control
        /// </summary>
        protected void BindData()
        {
            rlItemList.DataSource = ListDataItems;
            rlItemList.DataBind();
        }

    }
}

The SQL schema:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ReorderList](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ListOrder] [int] NULL,
    [Name] [nvarchar](256) NULL,
    [Description] [nvarchar](4000) NULL,
 CONSTRAINT [PK_ReorderList] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, 
  ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

License

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

About the Author

jaaaames
Web Developer
United States United States
I have been working in software development as a software developer, release engineer, and QA engineer for over fifteen years now. I have expertise in UI design, business process analysis, process automation, defining methodology, integration engineering, configuration and quality control.
In the last few years I have taking a special liking to ASP.NET and c#. I am really enjoy using it to solve fun and interesting problems.

Comments and Discussions

 
QuestionApplication Error Pinmemberdileepkumarpd18-Jul-12 0:52 
GeneralMy vote of 1 Pinmembereass43012-Nov-10 9:09 
GeneralRe: My vote of 1 PinmemberJason Silvestri20-Sep-13 22:33 
GeneralRealTimeReorderListDataDataContext Pinmembermeccode16-Jul-10 10:31 
Generalinserting data PinmemberMember 268792928-Jan-10 10:54 
QuestionASP.NET 2.0 Example? Pinmemberrobbierad6-Oct-08 9:18 
GeneralReorder List PinmemberVivekVashisht15-Sep-08 23:59 

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
Web01 | 2.8.140709.1 | Last Updated 3 Sep 2008
Article Copyright 2008 by jaaaames
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid