#

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));
        });

    });