2016-03-24



alvinashcraft
shared this story
from Rick Strahl's Web Log.

This post is going back to some basics, but it's a useful trick for many applications that's easy to
implement and

implement, but
can make a big difference in usability. Quite frequently in an application you might have a server generated list of items to display that can be displayed in a
reversible or other sortable

certain
order. While you can build the logic into a server side application to let you switch the sort order by re-reading content from the server, it's actually quite easy to make
the server generated
list client side sortable. Client side sorting is nearly instant and doesn't require server round trips
to server
and it's pretty easy to implement.

An Example: Messages in a Thread

For example, I've recently re-written the Message Board application I use
for support on my Web

on my
site, and in it I show a list of message in a
thread. One

thread and one
of the first requests that came up was: Can I see the list in reverse order with the last messages posted showing first.

Yup I can relate: I use my message board to support customers, and I frequently deal with long threads and it is useful to be able to see the last messages without having to scroll past a million messages that I have previously read and replied to. Not unexpected at all.

The UI I ended up with is a sort button on the top of the thread header with the message list below:



The server side code in this application simply returns the HTML of the sorted list in ascending/default order, which is what is the most common scenario. Most people prefer to read messages chronologically. The only people who usually want to only read the last messages are moderators or support people like myself who need to sift  through lots of posts and reply to answer messages.

Advertisement

Making the List Client Side Reversible

It's actually quite easy to make any list client side sortable or reversible, by adding an initial sort order indicator to the sortable elements in the page. So for example in my app I generate my list items like this using ASP.NET MVC and Razor on the server:

The key here is the data-sort="@counter" attribute which effectively defines an initial sort order for the messages in this thread which generates:

At this point you have an ascending sorted list of messages.

Toggling the List to make it Reversible

The data-sort key is important even though it's not used in the ascending order, but it gives a basic comparer value to each DOM element that you can then use to sort the DOM elements. And how do we sort DOM elements you might ask?

jQuery actually makes this pretty damn simple because you can simply select all of your list elements and then run JavaScript's sort() function over the resulting element array. The steps for this are:

Keep a static variable that holds the sort state (asc/desc)

Select all the child elements with jQuery

Run sort() over the result jQuery result set

Detach and re-attach the elements to the parent node

Here's what this looks like:

How it Works

The code starts by declaring a static variable
somewhere
where it's globally accessible. I use wwthreads.sortAscendingwhich represents the toggle state of the sort option. To
toggle the order all I

change all we
do is not the value which effectively reverses the flag. As a side note I also load topics via AJAX requests, and whenever a topic is loaded the sortAscending flag is reset to true to make sure the initial message is displayed in the right order before it can be toggled.

The sort operation is initiated by the click on the #ReverseMessageOrder icon button which is also generated as part of the
server side
message. The first thing that happens is that I toggle the ascending order flag, so whatever the order currently is we're going to reverse it.

Next I capture all the message elements into a jQuery
selected

selection
set. The nice thing about jQuery selectors is that they produce an array (actually and array-like list) that you can treat like an
array using array functions.

array.
Which means we can use the JavaScript Array.sort() method on the result set. Sort iterates over the DOM elements and
uses a Comparer function to receive

receives
two parameters for DOM elements to compare. Sort is internal and it shuffles elements asking your code to provide the logic to compare the two elements and return 1, –1, 0 to determine if the value is greater than, smaller than or equal.

So in our case, I look at the data-sort attribute's value
for both elements passed,

and
turn that value into a number (by multiplying by 1),
and then decide depending on the sort order which value is 'larger'.

that I can use to compare the values.
Depending on whether we're doing ascending or descending order we then add a multiplier of 1 or –1 respectively. For ascending (natural) order we multiple by 1 which leaves the original order intact. For descending/reverse order we multiply by –1 which effectively reverses the sort logic.

And that's it for the Comparer function.When the .sort() completes

At this point
the list has been resorted, but this doesn't affect the DOM as the list is only pointing at the existing DOM
elements – although we sorted the list the DOM elements haven't changed.

elements.
In order to update the DOM we have to actually detach the existing list, and reattach it to the parent element using this simple line:

And voila – the list is instantly updated.

This code is very simple and fairly generic to plug into any application easily, and it's a great client side enhancement feature you can easily add to server side application as an easy value add.

Bonus: Generating the Client Side data-sort Order

In the example above I used server side rendering to generate the initial sortorder and data-sort attribute, but that's not actually necessary (but easier if you can do it!). If you can't control the server side generated code for your sortable list you can generate the data-sort attributes yourself when the page loads (or when it refreshes as in my AJAX reloads). Assuming the initial list is in a specific order you can simply add the data-id using a little jQuery code:

This will work the same as server generated code but you have to be careful if you reload content via AJAX as to make sure the list is updated each time the data is loaded. But, this is a good way to handle the list sort entirely on the client side – the server doesn't need to contribute anything to the behavior.

Summary

This is certainly not a new trick, but it's something that I do quite frequently in my
applications,

application,
and I'm often surprised that this functionality is not provided in popular Web sites or customer
implementations

implementation
when this functionality is so easy to implement and add to any kind of application. Choice is good and your users will thank you for the option to quickly view things in a different order.

© Rick Strahl, West Wind Technologies, 2005-2016

Posted in JavaScriptjQueryASP.NET

Tweet

Show more