Google analytics code

Monday, February 24, 2014

Sencha Touch: Reorder a list with drag and drop handles using SortableList

Part of a project I'm working on requires the ability to reorder a list. I was pretty sure sencha touch could handle this, but couldn't figure out how to do it. I searched google for a solid week. I had one lead that turned bad after digging into it further. I basically gave up and moved onto the next issue when I ran across the solution buried in their documentation: SortableList

The second problem arose from the poor documentation on this feature. Outside of the class docs there is nothing explaining how to use it. The upside is at least it's easy to view the source.

I ran across this forum post that talked about a bug in the code. This was the only code I found that gave an example of how the code works.

There are a few things required to use this plugin.

Step 1: Include the plugin

// Make sure the plugin in include when the app builds
requires: ['Ext.plugin.SortableList'],

config:{
        // Include the plugin in your config. Don't forget the period on the class name
        plugins: [{xclass: 'Ext.plugin.SortableList', handleSelector: '.gripper'}],

        
        // These are required to fix a bug that exists in the plugin
        infinite: true,
        variableHeights: true,
        ...
}

Step 2: Configure the drag handle

config: {
        // Set the class to the name you passed in for the handleSelector
        itemTpl: '<span class="gripper"></span>[html goes here]'
        ...
        }

The tag used for the list-sortablehandle is the object that will start the reorder process. This can be styled using whatever you like.

Step 3: Listen for the finishing event

config: {
        listeners:[
            event: 'dragsort',
            // to is the new position in the list
            // from is where the item used to be
            fn: function(listObject, row, to, from)
        ]
        ...
}

It was smooth sailing after this point.

1 comment:

  1. Have you tried to dynamically change the count of the list items. There is an issue if some of the items are removed from storage: When the drag is done, the list items can overlap.
    Also, the plugin code should be fixed as follows:


    onDragStart: function(e) {
    // FIX
    var target = e.getTarget('.' + Ext.baseCSSPrefix + 'list-item');
    if(!target.id) return;
    var row = Ext.getCmp(target.id),
    // FIX
    list = this.getList(),
    store = list.getStore();
    ...
    ...

    if (targetItem) {
    distance = targetIndex - this.currentDragRowIndex;

    if (distance !== 0) {
    draggingUp = (distance < 0);

    for (i = 0, ln = Math.abs(distance); i < ln; i++) {
    if (draggingUp) {
    swapIndex = this.currentDragRowIndex - i;
    item = list.getItemAt(swapIndex - 1);
    } else {
    swapIndex = this.currentDragRowIndex + i;
    item = list.getItemAt(swapIndex + 1);
    }
    // FIX
    if(!item || item.getRecord() == null) {
    return;
    }
    // FIX

    BR,
    Dragan

    ReplyDelete

If you found this page useful, or you have any feedback, please leave a comment.