Yahoo! UI dragdrop sortable list 1
Dragdrop sortable lists are difficult. Deciding how the lists should work is the trickier part but also partitioning responsibility in the code is challenging. Here is my try.
The Yahoo! UI sortable list example has each element in the list behaving as a target. This makes it possible to detect above or below which item you would like to insert the dragged item. That is fine but I don't really think of the items in a list (ie. the <li>'s) as being the target. I think of the list itself (ie. the <ul>) as the target. With the Yahoo! UI example if all of the items are dragged out of the list then how do you drag anything back into the list. There wouldn't be any targets.
The script.aculo.us sortable list example (which doesn't seem to work on my computer) makes the list items (<li>'s) and the list (<ul>) targets. So if the list is empty then the list itself can accept a new item. This seems like too much of a special case and the list items are still targets.
In this example, I tried making only the list itself a target. The list is an instance of a DDTarget subclass called "Basket" and the list items are instances of a DDProxy subclass called "Apple". At all times a Basket instance knows the apples it contains but doesn't need to know their order.
When a dragStart occurs, the code caches the regions of all the baskets that are legal targets for the dragged apple. For each of these baskets, the region of each contained apple is also cached.
When an onDragOver fires, the vertical coordinates of the cached regions are used to determine if the dragged apple should be placed above an apple in the basket or at the bottom of the list. It makes no difference if the basket has apples or not.
I doubt my experiment would be useful in all sortable list applications but it does have an advantage over the list items being targets. In the example, you will see that if you are dragging inside the basket but outside any contained apples then the position of insertion can still be calculated. This would work if the gaps between the individual apples is very large or if the basket is much bigger in length or width than the contained apples.
For me it also just seems right. The basket is the target. The other apples are not targets.
Have something to write? Comment on this article.