advanced web statistics

An Actual Reorder List Control with Substance Part 1

11/2/2007 12:03:06 AM

Just as the title says.  I can't even begin to tell you how much I absolutely hate the Ajax Toolkit Reorder List control.  I've blogged about this many times.  It sucks. Big time.  I've told many colleagues (real-life and internet-life) the story about how I got tired of trying to strong-arm the Reorder List control and after fruitless efforts I decided to learn a little JavaScript and roll-my-own functionality.

I figure it would be fun to prove this and share some code with everyone.  The task is very involved so I will publish in installments.  When all is said-and-done I will give away the code along with a sample project and you can all do what you will.  Again, since I've been extremely busy both at work and at play this will take some time but should be fun nonetheless.

So.  The example will focus on reordering products within product groups.  Each product group has products attributed to it.  It's not rocket science.  This is also a very real possibility and something that could benefit from having a drag-and-drop interface.  Our project will use the following 2 objects: Product and ProductGroup.

Product

public class Product
{
   private int _productId = 0;
   private string _productName = string.Empty;
   private decimal _productPrice = 0m;

   public int ProductId
   {
      get { return _productId; }
      set { _productId = value; }
   }

   public string ProductName
   {
      get { return _productName; }
      set { _productName = value; }|
   }

   public decimal ProductPrice
   {
      get { return _productPrice; }
      set { _productPrice = value; }
   }
}

ProductGroup

using System.Collections.Generic;

public class ProductGroup
{
   private int _productGroupId = 0;
   private string _productGroupName = string.Empty;
   private List<Product> _products = new List<Product>();

   public int ProductGroupId
   {
      get { return _productGroupId; }
      set { _productGroupId = value; }
   }

   public string ProductGroupName
   {
      get { return _productGroupName; }
      set { _productGroupName = value; }
   }

   public List<Product> Products
   {
      get { return _products; }
      set { _products = value; }
   }
}

Pretty straight-forward.  For this project I will use one Default.aspx and a javascript file which I won't publish all the code for right now as it won't make sense.  What I will do is give some snippets and show an animated demo of the code in action, then spend some time in the future dissecting it / answering questions that come to me in the form of comments, etc...

So what I like to do with drag-and-drop web applications is create an xml document representing our objects.  I like to think of drag and drop applications as a sort of Xml parent-child node issue.  If you ever find yourself needing to program functionality that allows the moving of nodes then drag-and-drop might be a viable option.  For this first installment I am simply creating an xml document and binding it to an Xml object that we can reference using the JavaScript DOM (aka XPath queries!).  For the following demo I am using this Xml format:

<?xml version="1.0" encoding="utf-8"?>
<
root>
   <
productGroup productGroupId="1">
      <
product id="1" name="Product-1" price="1" />
      <
product id="2" name="Product-2" price="2" />
      <
product id="3" name="Product-3" price="3" />
      <
product id="4" name="Product-4" price="4" />
   </
productGroup>
   <
productGroup productGroupId="2">
      <
product id="5" name="Product-5" price="5" />
      <
product id="6" name="Product-6" price="6" />
      <
product id="7" name="Product-7" price="7" />
      <
product id="8" name="Product-8" price="8" />
   </
productGroup>
   <
productGroup productGroupId="3">
      
<product id="9" name="Product-9" price="9" />
      <
product id="10" name="Product-10" price="10" />
      <
product id="11" name="Product-11" price="11" />
      <
product id="12" name="Product-12" price="12" />
   </
productGroup>
</
root>

This file is created with this code:

private void CreateXmlFile(string xmlFilePath)
{
   int productGroupId = 1;

   using (XmlTextWriter xml = new XmlTextWriter(Server.MapPath(xmlFilePath), new UTF8Encoding(false)))
   {
      xml.Formatting = Formatting.Indented;
      xml.Indentation = 5;
      xml.WriteStartDocument();
      xml.WriteStartElement("root"); // <root>

      ProductGroup.RetrieveAll().ForEach(
         delegate(ProductGroup productGroup)
            {
               xml.WriteStartElement("productGroup"); // <productGroup>
               
xml.WriteAttributeString("productGroupId", productGroupId.ToString());
         
               productGroup.Products.ForEach(
                  delegate(Product product)
                     {
                        xml.WriteStartElement("product"); // <product>
                        
xml.WriteAttributeString("id", product.ProductId.ToString());
                        xml.WriteAttributeString("name", product.ProductName);
                        xml.WriteAttributeString("price", product.ProductPrice.ToString());
                        xml.WriteEndElement(); // </product>
                     
});

         xml.WriteEndElement(); // </productGroup>

         ++productGroupId;
      });

      xml.WriteEndElement(); // </root>
   
}

   xmlData.Attributes.Add("src", xmlFilePath);

You see that I add xmlData src attribute to this file? That is simply an xml object in my .aspx that looks like this:

<xml id="xmlData" runat="server" /> 

Before I get an influx of inquiries asking why I just didn't use an ASP:XmlDataSource control I don't like the xml being displayed in my source. I'm a little picky and a little old school at the same time.

I'm going to skip all the JavaScript explanation because I just got done splitting and stacking over a cord and a half of firewood after working 60+ hours this week.  The JavaScript is a whole other post in and of itself.

Demo

A little preface.  I have 3 rows of 4 products.  A row is a product group and a textbox is representing a product.  The numbers in the textbox represent the product price (I know, cheesy) and the label with the $ represent the total of the numbers in the textbox. Again, this is only to pique your interest.  If you are interested then stay tuned. If not, then still stay tuned and let me know how much of an idiot I am for not being able to do this with the AJAX Toolkit.  One major advantage to rolling your own is that instead of dragging the ENTIRE object up one row, you can pick and choose and have a TRUE drag-and-drop interface.  When I first rolled this out to production I added empty textboxes that could be used as well.  This way one parent could have 5 children, one could have 1 and another could have 0 (I had functionality to delete nodes as well).

I tried to go pretty slow and only showed 3 moves to give you time to count and verify that this is actually working.  Again, I haven't showed yet how I'm doing the javascript.  Right now the javascript file is about 75 lines or so.  In the end, depending on how ambitious I am, we'll be at about 200 or so as I'd like to give you all the ability to swap parent nodes as well as child nodes.  The JavaScript might be a little heavy but in my opinion, it is a small price to pay to get the ACTUAL functionality that you want!  Animated demo below.

Drag and Drop 01

Easy. Stay tuned for HOW I did that.

Related
An Actual Reorder List Control with Substance Part 2

AJAX, JavaScript

kick it on DotNetKicks.com

Leave a Comment

   

  Enter the text to proceed!