Eat my shorts! AJAX drag-and-drop baby!

New article on Piper’s Pages:

In my neverending quest to learn (everything?) AJAX, I decided to dip my fingertips into the pond that is drag-and-drop.

Probably the most famous of AJAX techniques, it allows you to grab something on a page and move it somewhere else – either because you like to assert your creativity, or because you want to Do Something(tm) (like add an item to shopping cart).

Well ladies and gents, we’ve taken our implementation of drag-and-drop to a Whole New Level(tm).

You may recall that we’ve had AJAX popups for ages now (ages <= 1 year) and you could grab those popups and move ’em around, just cause they might be covering stuff you want to see. Cool, but… that didn’t DO anything really.

So here’s what I envisioned.

I envisioned an interface with multiple panes – one for browsing, one may contain a zone, and another may contain a list. It would be wicked and wild if you could drag an album on your list or onto the zone to queue that album.

This obviously requires more kung-fu than just moving popups around the screen.

So…. if I’m not mistaken I’ve been using Scriptaculous for the popup dragging, and after trying to bake my own more-advanced solution I realized that Scriptaculous could do what I wanted (and it was even using the same terminology I was using – “draggables” and “droppables”).

So the first crack at this yielded the ability to drag stuff from the browse view onto the link that indicates your working list. That causes the album/song to be added (or removed) from said list, which also happens to flick the checkmark for that item (this happens as a result of existing code).

Okay, so that’s cool I guess, but said checkmark could simply be clicked to achieve the same results. Nothing really new here folks, so move along!

My pleasure. My next effort was to enable drag-and-drop table reordering. Currently, in list view, you’ve got teeny weeny icons that you can use to move a row up or down, one at a time. Sure, you can select a bunch of rows and move them all up or down at once, but again they’ll move one at a time.

With these handy dandy scrolling tables, it sure would be nice to grab a row by the scruff of its neck and manhandle it into a new position, right?

Yes, it would. And while Scriptaculous provides an easy breezy way to get this done, fact is that my implementation of dynamic tables is slightly incompatible with Scriptaculous. If I had to actually take time to explain why, I would say that it has to do with my padding process – which means that in any given table, some of the rows have actual data and some do not. I use different DOM ID prefixes to track this, but even if I used a seperate array to do the same thing I’m pretty sure we’d run into context issues: does it make sense to reorder a row that hasn’t been filled in yet?

Sure, the way I’m registering draggable items means those rows wouldn’t be considered draggable by Scriptaculous until they were force-fed useable data by backend, but… why are you trying to convince me to use Scriptaculous for this??? Look, the fact is I wanted to keep my DOM ID convention, and I don’t like the way Scriptaculous reports the new ordering to the backend. When you’ve got a table that can contain, oh, 30000 rows the last thing you want to do is iterate through a serialized list of row IDs and tell a DBMS to reorder based on that list. Ugh.

So I baked my own solution, which was based on the work I did (and partially abandoned) for effort 1.

And… it works!

At least in Firefox. It looks like it wants to work in Chrome and Opera, but I’ve got stoopid text selection issues to overcome still. But at least the concept works, and admittedly it’s quite handy.

So ya – drag-and-drop/table-reordering with backend updates. Funky fresh.