Imagine the following situation - say you've got a set of documents which are all children of one container document. From within this parent container document you want to be able to quickly change the order in which the child documents appear. Sound familiar? It's a scenario I've come across a couple of times before and only now have I found a solution I'm happy with enough to share.
A Real-World Scenario
Let's use the example of a newsletter document. In this case the parent form is called something like newsletter and simply contains the title and date of the newsletter. Once saved we can add the child news item document to it. It's these news items that it would be nice to be able to sort as the author pleases.
In most cases news would be sorted by date/time. However with newsletter this is not always the case and so being able to adjust the order is a must in most cases. Whether or not you need to compile newsletters there's bound to be a scenario where the following technique would come in handy.
How to Sort Documents
- Win / IE 6+ (IE 5.5 too?)
- Win & Mac / Mozilla (Firefox 1.5, Camino 1.0 etc)
- Mac / Safari 2.0 (should work in 1.2+ ?)
- Win & Mac / Opera 8.5 (No Ajax, but sorting and form submission work)
- Win / Opera 9.0 (sorting broken)
- Mac / IE 5.2 (no Ajax OR sorting. dead browser anyhow)
Flesh-out the following items:
- An embedded view is treated as HTML and renders a set of LI elements on the parent document.
- When the page loads the script.aculo.us code makes this list sortable.
- Whenever a news item is moved (i.e the list items) the list of UNIDs for each child (in the new order) is posted to the server as an Ajax request.
- The Ajax request is sent to the UpdateOrder form where the UNIDs are stored in a multivalue field called NewOrder.
- The WQS agent for the UpdateOrder form iterates through each UNID and updates the news item's order (but only if it needs to)
- The agent returns (content-type:text/plain) a list of what it did.
- The browser-side script displays this list of changes to the user and uses the Yellow Fade Technique to highlight the message.
- When Ajax isn't supported the "Update" button can be used. Note, however, that Ajax is only likely not to work on older browser or those with no script support. On these browsers it's unlikely that the drag-n-drop sorting will work and, so, there's not much point in the button. I left the button on because there could be a case when sorting does work but Ajax doesn't. Safari 1.0 or some Opera versions for example.
- Each LI has a hidden field called NewOrder. This is passed via POST to the server when Ajax is not used and the button is pressed instead.
Turned off conflicts in child form.
Mention inclusion of hidden text field in each LI element for use when no Ajax (although not in Safari, where order of fields is not reflected after re-sort)
Most up to date database is Version 0.5
Version 0.5 fixes a problem in all previous versions described in this blog entry and also up
grades to Prototype 1.5 and Scriptaculous 1.7.
Version 0.1 uses the Yahoo! UI Library instead of Script.aculo.us and does NO T use Ajax. Horses for courses.
Taking It Further
Rep conflicts are a problem. How about having the Ajax call check the last-mod dates. Or with XML
Put summary here
Is using Ajax a good idea?