Warning

This document hasn't been checked for compatibility with current versions of Plone. Use at your own risk.

Create javascript for drag and drop sorting

by Edmund Moseley last modified Dec 30, 2008 03:06 PM
Modify the javascript used by folder_contents to allow sorting of individual cells in our grid

The main difference between this javascript file and the one used for folder_contents, is that I replaced  the swapElement function with an insertElement function. 
When sorting the rows in folder_contents, as you drag an item up or down, it swaps location with the next item it comes to;  However, with a two dimensional grid layout, this works fine when you drag an item along the same row, but if you drag it up to the next row, it swaps postion with that item. This is not the desired affect, as items jump around the screen.

This "bug" can also been demonstrated in folder_contents by selecting an item to drag, dragging it outside of the table, and then back into the table at a different point.  The item where you re-enter the table then gets swapped with the position of the dragged-item.  This is only a visual affect, but is a little confusing.

Instead of swapping elements, we simply want to insert the element we are dragging, and bump the other items along.

Below is a snippet of the dragdropslidesorter.js, showing the new insertElement function:

<snip>
dndSlideSorter.insertElement = function(child1, child2) {
    // child1 = target (current location of cursor)
    // child2 = item being dragged
    var parent = child1.parentNode;
    var children = parent.childNodes;
    var items = new Array();
    // get index of target and dragged item
    var target_pos, drag_pos = 0;
    for (var i = 0; i < children.length; i++) {
        var node = children[i];
        items[i] = node
        if (node.id) {
            removeClassName(node, "even");
            removeClassName(node, "odd");
            if (node.id == child1.id)
                target_pos = i;
            if (node.id == child2.id)
                drag_pos = i;
        }
    }
    // move dragged item to index of target (don't swap, just insert)
    // swapping meant that with new layout, index 1 could get swapped with
    // 7 and images visually jump around rather than insert
    if (drag_pos > target_pos)
        {
        // insert dragged
        items.splice(target_pos,0,items[drag_pos]);
        // delete original
        items.splice(drag_pos+1,1);
        }
    else{
        // insert dragged
        items.splice(target_pos+1,0,items[drag_pos]);
        // delete original
        items.splice(drag_pos,1);
        }

    Sarissa.clearChildNodes(parent);
    var pos = 0;
    for (var i = 0; i < items.length; i++) {
        var node = parent.appendChild(items[i]);
        if (node.id) {
            if (pos % 2)
                addClassName(node, "even");
            else
                addClassName(node, "odd");
            pos++;
        }
    }
}
<snip>

The other major change between the original dragdropreorder.js and this one,  is to fetch our draggable items identified by the id #slide-sortable and class .sortable-cell rather than by the table elements.


Contribute

Something wrong or out of date? Anybody can edit or create a new article in the knowledge base. Simply create an account on this site, log in, and click the Edit button to contribute.