Jump to Table of Contents

Example: Sortable Events

Making a sortable list with drag-and-drop notifications.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. Waiting for a drag and drop...

Setting Up the List

First we need to create the HTML structure for the list. Since Sortable uses Y.DD.Delegate, we need to set up a delegation container (#demo) and the list items (li). We also set up a log list (#log) which will inform us of the drag events.

Note: This example is using CSS Grids to create a two-column layout.

<div class="yui3-g">
    <div class="yui3-u-1-2">
        <div id="demo">
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
                <li>4</li>
                <li>5</li>
                <li>6</li>
                <li>7</li>
                <li>8</li>
                <li>9</li>
                <li>10</li>
            </ul>
        </div>
    </div>

    <div class="yui3-u-1-2">
        <ol id="log">
            <li>Waiting for a drag and drop...</li>
        </ol>
    </div>
</div>

Now we style the list and the log with some CSS to make them visible.

#demo li {
    list-style-type: none;
    padding: 3px;
    margin: 6px;
    width: 150px;
    font-size: 114%;
    background-color: #B6BFDA;
    border: 1px solid #7E869D;
    -moz-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.25);
    -webkit-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.25);
    box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.25);
    cursor: move;
}

#log {
    border: 1px dotted #999;
    background-color: #FFF;
}

#log li {
    padding: 0.3em;
}

Making the List Draggable

Now we need to create our YUI instance and tell it to load the sortable module. Then we need to instantiate the Sortable instance on the list.

YUI().use('sortable', function (Y) {

    var log, sortable;

    // The node where we'll output the drag-and-drop events.
    log = Y.one('#log');

    // Our sortable list instance.
    sortable = new Y.Sortable({
        container: '#demo ul',
        nodes    : 'li',
        opacity  : '0.1'
    });

});

Adding in Events

We have sorting working but we want to know when the user picks up an element and where it ends up. We'll want to hook into drag:end event that DD.Delegate fires. Depending on whether the dragged element was dropped into the middle of the list, or the beginning, or the end, we log a slightly different message.

sortable.delegate.after('drag:end', function (e) {
    var node = sortable.delegate.get('currentNode'),
        prev = node.previous(),
        next = node.next(),
        msg  = 'Moved ' + node.get('text');

    // Customize the log message based on where the `node` moved to.
    if (prev && next) {
        msg += ' between ' + prev.get('text') + ' and ' + next.get('text');
    } else if (prev) {
        msg += ' to the end, after ' + prev.get('text');
    } else if (next) {
        msg += ' to the beginning, before ' + next.get('text');
    }

    // Create a new list item and append it to our log of events.
    log.append(Y.Node.create('<li />').set('text', msg));
});

Putting it together

YUI().use('sortable', function (Y) {

    var log, sortable;

    // The node where we'll output the drag-and-drop events.
    log = Y.one('#log');

    // Our sortable list instance.
    sortable = new Y.Sortable({
        container: '#demo ul',
        nodes    : 'li',
        opacity  : '0.1'
    });

    sortable.delegate.after('drag:end', function (e) {
        var node = sortable.delegate.get('currentNode'),
            prev = node.previous(),
            next = node.next(),
            msg  = 'Moved ' + node.get('text');

        // Customize the log message based on where the `node` moved to.
        if (prev && next) {
            msg += ' between ' + prev.get('text') + ' and ' + next.get('text');
        } else if (prev) {
            msg += ' to the end, after ' + prev.get('text');
        } else if (next) {
            msg += ' to the beginning, before ' + next.get('text');
        }

        // Create a new list item and append it to our log of events.
        log.append(Y.Node.create('<li />').set('text', msg));
    });

});