Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Building an AJAX based Specials Sorter


:P
On this page:

I spent a few hours today building an AJAX form in my West Wind Web Store that’s used to resort the Specials displayed on the home page. I needed to build something to manage this list anyway, so I figured I might as well put Jason Diamond’s My Ajax.Net through its paces with something that would be useful in light of Tim Haines’ BlogConversation regarding AJAX integration into an online store application.

 

The page I ended up building is available here:

 

http://www.west-wind.com/webstoresandbox/admin/SpecialsManager.aspx

 

The idea is that I have a list of items in the store that have a Special flag set that are displayed on the home page of the store. The Special flag also serves as a sort order. Prior to the above page there’s was no easy way to manage the Specials, other than visit each item in the inventory and more or less remember which item was a special.

 

So the purpose of this form is to show you all the specials and allow sorting them in a somewhat visual way, as well as providing easy access to the inventory items for editing and managing the entire process of creating these Specials.

 

As it turns out I’m not sure if much was gained by using an AJAX approach to this form. Certainly I can tell you that it would have taken me a fraction of the time to build this form with pure server side code. The main advantage of the AJAX approach is that it’s relatively easy to keep the form in context and the selected item active and visually displayed. You can do that with ASP.NET server side too, but it doesn’t work all that well…

 

The end result is that much less data is passed over the wire than would be with full page redraws. With my Cable IP Connection moving things around the list is reasonably fast – there’s a little hesitation, but it’s acceptable and definitely faster than a server PostBack would be. Anybody have a dial-up connection? Curious to see how this would look.

Still a lot of server processing/transferring

So let’s talk about the issues here. The big issues I ran into here are that unless you plan on writing very sophisticated code on the client, you still end up doing a lot of processing and data transfer to the server. If you take a look at the traffic I’m generating between the client and server with Fiddler or the like you’ll see that I’m actually not resorting the list on the client, but rather sending back the changes to the server (which has to happen no matter what), then having the server sort and renumber the list, then send it back to the client. JD’s Ajax Library makes this process fairly painless by supporting DataTable’s sent to the client and a client side object that can access the DataTable easily. You can View Source to see how this works – it’s straight forward and easy to code.

 

Lots of hard to debug JavaScript code

Of course, ‘easy’ is relative here. I’m no JavaScript jockey. I hate JS – it’s a PITA and damn time consuming although in light of all the AJAX stuff I’ve been doing recently I’m getting much better at it. Heck at least some upside.

 

But doing stuff on the client is no picnic. This page has what I consider a lot of code on the client. Most of the logic is on the client. The server has very little code actually. There’s the base population of the Item listbox which is not AJAX (and probably the biggest size advantage that the AJAX solution would have over a server side solution). Beyond that the server merely has three methods that handle the client side requests. Here’s the entire server side ASP.NET 2.0 C# code:

 

public partial class SpecialsManager : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        Ajax.Manager.Register(this, "Callback", Ajax.Debug.Errors);

 

        if (!Ajax.Manager.IsCallBack)

        {

            busItem Item = WebStoreFactory.GetbusItem();

            int Count = Item.GetItemList("pk,sku,descript","","descript");

 

            this.lstItems.DataSource = Item.DataSet.Tables["ItemList"];

            this.lstItems.DataTextField = "Descript";

            this.lstItems.DataValueField = "sku";

            this.lstItems.DataBind();

 

            this.lstItems.Items.Insert(0, new ListItem("*** Select an item"));

            this.lstItems.Attributes.Add("onchange","SelectItem(this.value)");

        }

    }

 

    [Ajax.Method]

    public DataTable GetItemList()

    {

        busItem Item = WebStoreFactory.GetbusItem();

       

        // *** Run query and return result into Item.ItemList Table

        int Count = Item.GetItemList("pk,Sku,Descript,Special,SpecialHd,SpecialTxt,SortOrder,ItemImage",

                                     "Special!=0",

                                     "Special desc,Descript");

 

        return Item.DataSet.Tables["ItemList"];

    }

 

    [Ajax.Method]

    public bool SaveItem(int Pk, int Special)

    {

        busItem Item = WebStoreFactory.GetbusItem();

        if (!Item.Load(Pk))

            throw new ApplicationException("Invalid Item passed back.");

 

        wws_itemsRow ItemEntity = Item.GetTypedDataRow();

        ItemEntity.Special = Special;

        Item.Save();

 

        return true;

    }

 

    [Ajax.Method]

    public void ResortSpecials()

    {

        busItem Item = WebStoreFactory.GetbusItem();

        Item.ResortSpecials();

    }

 

}

 

All of the UI management is on the client side. This is no small page – there’s a lot of script code that deals with drawing the list, setting the selections. The freaking highlighting code makes up most of the client code – something that has very little to do with the business logic.

 

In addition, this brings up another issue: Some business logic now has been pushed down to the client. Sure, it’s mostly high level UI scripting code, but still this splits the business logic between client and server sides in a tightly coupled manner.

 

Granted I didn’t spend a lot of time here, designing this. Rather the UI capabilities really were the driving factor for how this form works. There are not too many ways you can make something like this work with limited scripting controls.

Passing data back to the server?

My original plan was to send down a list of table items, then have the client resort the list, then when down send the entire list back to the server. The user would have been able to edit items directly in the list. But that fell flat when I realized that it’s a bitch to pass data back to the server as effectively as it’s coming down with tools like JD Ajax.Net library. You can easily pass a DataTable down to the client which is great, but you can’t just as easily pass that object back to the server – at least not without building some sort of serializer that goes the other way.

 

So ultimately I ended up doing the thing that was most important – sorting using AJAX, and delegating the editing and updating to the existing interfaces. This is a smarter approach anyway I think. Since the main inventory editor form already has all the error handling built-in. If I had done in place editing I would have had to deal with the assigning the data and then validating the data as well, which would have resulted in a bit of duplication.

 

So in the end for my first cut I ended up with a hybrid approach. You can play around with this form and check it out – press F1 (in IE) or click on the Help icon to see how this form is supposed to work in case it isn’t quite obvious <g>.

 

 

So overall, while I think this turned out nicely, I can’t say that there’s an overwhelming reason to use AJAX for something like this. I guess I could see spending a bit more time and avoid having the server to reload the list completely from the server for each move, which would improve the performance considerably, but this gets very tricky as the server and client can easily get out of sync.


The Voices of Reason


 

Tim Haines
September 11, 2005

# Rick's AJAX article in CoDe Magazine


Rick Strahl's Web Log
September 29, 2006

# Past the AJAX Hype - Some things to think about - Rick Strahl's Web Log

Tim Haines is running an interesting 'contst' asking for suggestions to AJAX enable his Web Store application. There are some interesting suggestions, but more than anything some of the suggestions really show some of the issues and open questions that exists with AJAX technology today.

Rick Strahl's Web Log
October 15, 2006

# The problem with posting demos... - Rick Strahl's Web Log

Last night I posted an AJAX demo of my Specials Sorter for my store for people to check out. Well, it turns out that doing that wasn’t the most optimal idea as people started playing with the sorter simultaneously for a feature that was really meant for a single user - yielding, uh, unpredictable results. A few smart asses also decided it'd be neat to wipe out all Specials so a few workarounds were required.

# DotNetSlackers: Building an AJAX based Specials Sorter


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024