E-Scribe : a programmer’s blog

About Me

PBX I'm Paul Bissex. I build web applications using open source software, especially Django. Started my career doing graphic design for newspapers and magazines in the '90s. Then wrote tech commentary and reviews for Wired, Salon, Chicago Tribune, and others you never heard of. Then I built operations software at a photography school. Then I helped big media serve 40 million pages a day. Then I worked on a translation services API doing millions of dollars of business. Now I'm building the core platform of a global startup accelerator. Feel free to email me.

Book

I co-wrote "Python Web Development with Django". It was the first book to cover the long-awaited Django 1.0. Published by Addison-Wesley and still in print!

Colophon

Built using Django, served with gunicorn and nginx. The database is SQLite. Hosted on a FreeBSD VPS at Johncompanies.com. Comment-spam protection by Akismet.

Pile o'Tags

Stuff I Use

bitbucket, Django, Emacs, FreeBSD, Git, jQuery, LaunchBar, Markdown, Mercurial, OS X, Python, Review Board, S3, SQLite, Sublime Text, Ubuntu Linux

Spam Report

At least 236325 pieces of comment spam killed since 2008, mostly via Akismet.

Advice on sequencing items in web interfaces?

A small but common task in web interfaces, especially "admin" (back-end, content manager) interfaces, is sequencing items. Any time you have a collection of objects that requires arbitrary, user-defined ordering (i.e. ordering that can't be derived from the objects' values) you are faced with this problem. Navigation is a common example. If people can add items to a dynamically built navigation menu or tree, how do we let them specify the ordering so that "Contact" can appear below "About Us" or vice-versa?

One low-tech way is to add a numeric field that can be manually edited; you then sort the objects by that field before displaying them. (Sub-puzzle: a good one-word label for that sort of field eludes me. "Order" and "sequence" both apply more to the whole set than the individual; "number" is too vague; "precedence" is too technical.) This works, but always feels clunky -- it reminds me of the bad old days of BASIC programming because you end up incrementing by 10s or 100s and then filling in the gaps as more items are added.

Other methods involve a bit more work on the interface end, and include up/down arrows to nudge position, or list boxes with references that can be added or removed by clicking buttons. These don't seem worth the trouble.

Most elegant would be a drag-and-drop ordering solution, the pride of many a glorious Ajax demo. Because I can't think of an appealing simpler alternative (and I really do like simple when I can get it), I'm actually considering this for a new project in which the user needs to be able to rearrange "page" objects in a presentation.

The drag-and-drop Ajax technique would surely be fun to do, but before diving in I wanted to float this quasi-lazyweb post to see if there are other good approaches to this little problem that I'm overlooking.

Friday, January 5th, 2007
+
6 comments

Comment from metapundit , later that day

You're probably going to implement this in Python, but if working with legacy PHP this might be useful...

I encapsulated the scriptaculous drag-n-drop effect along with some JS to serialise the order of the ul and save it to a hidden field in a PEAR QuickForm control. Now in any form I'm using QuickForm to generate, I can get a drag-n-drop list by saying

$page->addElement('sorter','colors','Color Order', array(4 => "Blue",9 => "Red", 13 => "Green"));

And $_POST['colors'] will be a comma separated list of the keys in the order they were arranged.

Code is here and I put up a brief post about it... Feel free to rip off the JS or port to DJango equivalent.

More to the point of your question: the best way to handle this is drag and drop, but it should happen in the context of actual display! I wrote a basic product catalog that lets you put products in multiple categories and has a "Ordering" field for each category the product is in. Same crappy solution: increment ordering by 10 and fill in as needed.

This sort of solution makes sense to programmers because our brains have been damaged by thinking like computers all the time. Real people, however, have had enormous amounts of difficulty handling this sort of interface. As it turns out, I would have been enormously better suited to have invested the time to allow drag and drop ordering on the actual catalog display page so that the operation of ordering was intuitive and the details of implementation (a separate sequence number for every category) are not exposed to the user...

Comment from metapundit , later that day

Whoops, lost my links. Code is at http://metapundit.net/samples/HTML_QuickForm_Sorter.php.txt and post is at http://metapundit.net/sections/blog/42

Comment from Taybin , later that day

Drupal uses the term "weight" for the ordering field name.

Comment from Paul , later that day

"Weight" seems better than most of my ideas. It still isn't perfect since it doesn't make it instantly obvious whether high or low numbers have greater priority, but in practice that's probably not a big hangup.

metapundit -- thanks for that, I'll take a look. I think you're right that in-place editing is often better. I've rarely implemented it, though, mostly due to weak JS chops I think. The toolkits have gotten good enough to override that excuse though.

Comment from tim , 5 weeks later

Rails's acts_as_list defaults to using 'position' as the column name.

Comment from Paul , 5 weeks later

Even better than "weight", thanks!

Comments are closed for this post. But I welcome questions/comments via email or Twitter.