E-Scribe News : a programmer’s blog

About Me

PBX I'm Paul Bissex, and e-scribe.com is my consulting business. I build web applications using open source software, especially Django. I teach photographers web design and professional skills. In the '90s I did graphic design for newspapers and magazines. Then I wrote technology commentary and reviews for Wired, Salon.com, Chicago Tribune, and lots of little places you've never heard of. Feel free to email me.

Book

Python Web Development with Django I'm co-author of "Python Web Development with Django", an excellent guide to my favorite web framework. Its strong points include an introduction to Python, and better coverage of Django 1.0 than nearly anybody else. Published by Addison-Wesley, it is available from Amazon and your favorite technical bookstore as well.

Colophon

Built using Django, served by Apache and mod_wsgi. The database is SQLite. The operating system is FreeBSD, on a VPS hosted at Johncompanies.com. Comment-spam protection by Akismet. Vintage topo imagery from the Maptech archive. The markup engine is Markdown.

Pile o'Tags

Stuff I Use

Akismet, del.icio.us, Django, dpaste.com, Emacs, FreeBSD, Freenode, jQuery, LaunchBar, MacPorts, Markdown, Mercurial, OS X, Postfix, Python, SQLite, Subversion, TextMate, Trac, Ubuntu Linux, wmii

Spam Report

At least 67570 pieces of comment spam killed since January 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!

Post a comment

Thanks for reading! Please note: Your comment will not appear until approved, which may take a few hours or more. Spammers will be torpedoed.


(Will not be shared)

(Optional)