YUI 3.x Home -

Site Search (YDN & YUIBlog):

# YUI Library Examples: Drag & Drop: Interaction Groups

## Drag & Drop: Interaction Groups

Using interaction groups, this example demonstrates how to tie into the Drag & Drop Utility's interesting moments to provide visual affordances for the current drag operation.

View example in new window.

1
3
4
5
6
2
1
2
3
4
5
6

### Setting up the Work Area

First we need to create the work area, players (drags) and slots (drops).

    <div id="workarea">     <div class="slot" id="t1">1</div>    <div class="slot bottom" id="b1">3</div>    <div class="slot bottom" id="b2">4</div>    <div class="slot bottom" id="b3">5</div>    <div class="slot bottom" id="b4">6</div>    <div class="slot" id="t2">2</div>      <div class="player" id="pt1">1</div>    <div class="player" id="pt2">2</div>    <div class="player" id="pb1">3</div>    <div class="player" id="pb2">4</div>    <div class="player" id="pboth1">5</div>    <div class="player" id="pboth2">6</div> </div>

    <div id="workarea">

        <div class="slot" id="t1">1</div>
        <div class="slot bottom" id="b1">3</div>
        <div class="slot bottom" id="b2">4</div>
        <div class="slot bottom" id="b3">5</div>
        <div class="slot bottom" id="b4">6</div>
        <div class="slot" id="t2">2</div>

        <div class="player" id="pt1">1</div>
        <div class="player" id="pt2">2</div>
        <div class="player" id="pb1">3</div>
        <div class="player" id="pb2">4</div>
        <div class="player" id="pboth1">5</div>
        <div class="player" id="pboth2">6</div>

    </div>

<div id="workarea"> <div class="slot" id="t1">1</div> <div class="slot bottom" id="b1">3</div> <div class="slot bottom" id="b2">4</div> <div class="slot bottom" id="b3">5</div> <div class="slot bottom" id="b4">6</div> <div class="slot" id="t2">2</div> <div class="player" id="pt1">1</div> <div class="player" id="pt2">2</div> <div class="player" id="pb1">3</div> <div class="player" id="pb2">4</div> <div class="player" id="pboth1">5</div> <div class="player" id="pboth2">6</div> </div>

Now we give them some CSS to make them visible.

    .slot {    border: 2px solid #808080;    background-color: #CDCDCD;    color: #666666;    text-align: center;    position: relative;    float: left;    margin: 4px;    width: 60px;    height: 60px;    z-index: 0;}.player {    border: 2px solid #808080;    color: #ffffff;    text-align: center;    position: relative;    float: left;    margin: 4px;    width: 60px;    height: 60px;    top: 150px;    z-index: 1;    cursor: move;}#pt1 {    clear: both;}.bottom {    top: 50px;} #pt1, #pt2 {    background-color: #71241A;}#pb1, #pb2 {    background-color: #004C6D;} #pboth1, #pboth2 {    background-color: #FFA928;} #workarea {    position: relative;    height: 300px;    width: 500px;}#workarea .yui3-dd-drop-active-valid {    border: 2px solid green;}#workarea .yui3-dd-drop-over {    background-color: green;}#workarea .yui3-dd-drop-active-invalid {    border: 2px solid red;}

    .slot {
        border: 2px solid #808080;
        background-color: #CDCDCD;
        color: #666666;
        text-align: center;
        position: relative;
        float: left;
        margin: 4px;
        width: 60px;
        height: 60px;
        z-index: 0;
    }
    .player {
        border: 2px solid #808080;
        color: #ffffff;
        text-align: center;
        position: relative;
        float: left;
        margin: 4px;
        width: 60px;
        height: 60px;
        top: 150px;
        z-index: 1;
        cursor: move;
    }
    #pt1 {
        clear: both;
    }
    .bottom {
        top: 50px;
    }

    #pt1, #pt2 {
        background-color: #71241A;
    }
    #pb1, #pb2 {
        background-color: #004C6D;
    }

    #pboth1, #pboth2 {
        background-color: #FFA928;
    }

    #workarea {
        position: relative;
        height: 300px;
        width: 500px;
    }
    #workarea .yui3-dd-drop-active-valid {
        border: 2px solid green;
    }
    #workarea .yui3-dd-drop-over {
        background-color: green;
    }
    #workarea .yui3-dd-drop-active-invalid {
        border: 2px solid red;
    }

.slot { border: 2px solid #808080; background-color: #CDCDCD; color: #666666; text-align: center; position: relative; float: left; margin: 4px; width: 60px; height: 60px; z-index: 0; } .player { border: 2px solid #808080; color: #ffffff; text-align: center; position: relative; float: left; margin: 4px; width: 60px; height: 60px; top: 150px; z-index: 1; cursor: move; } #pt1 { clear: both; } .bottom { top: 50px; } #pt1, #pt2 { background-color: #71241A; } #pb1, #pb2 { background-color: #004C6D; } #pboth1, #pboth2 { background-color: #FFA928; } #workarea { position: relative; height: 300px; width: 500px; } #workarea .yui3-dd-drop-active-valid { border: 2px solid green; } #workarea .yui3-dd-drop-over { background-color: green; } #workarea .yui3-dd-drop-active-invalid { border: 2px solid red; }

#### Setting up the YUI Instance

Now we need to create our YUI instance and tell it to load the `dd-drop`, `dd-proxy` and `dd-constrain` modules.

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain');

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain');

YUI().use('dd-drop', 'dd-proxy', 'dd-constrain');

#### Setting up the Drop Targets

Now that we have a YUI instance with the requested modules, we are going to create our Drop Targets.

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) {    //Get all the nodes with the class of .slot under #workarea    var slots = Y.one('#workarea').all('.slot');    //Loop through them    Y.each(slots, function(v, k) {        var id = v.get('id'), groups = ['two'];        //Assign them to different groups        switch (id) {            case 't1':            case 't2':                groups = ['one'];                break;        }        //Create the Drop object        var drop = new Y.DD.Drop({            node: v,            //With the new groups array as a config option            groups: groups        });    });});

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) {
        //Get all the nodes with the class of .slot under #workarea
        var slots = Y.one('#workarea').all('.slot');
        //Loop through them
        Y.each(slots, function(v, k) {
            var id = v.get('id'), groups = ['two'];
            //Assign them to different groups
            switch (id) {
                case 't1':
                case 't2':
                    groups = ['one'];
                    break;
            }
            //Create the Drop object
            var drop = new Y.DD.Drop({
                node: v,
                //With the new groups array as a config option
                groups: groups
            });
        });
    });

YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) { //Get all the nodes with the class of .slot under #workarea var slots = Y.one('#workarea').all('.slot'); //Loop through them Y.each(slots, function(v, k) { var id = v.get('id'), groups = ['two']; //Assign them to different groups switch (id) { case 't1': case 't2': groups = ['one']; break; } //Create the Drop object var drop = new Y.DD.Drop({ node: v, //With the new groups array as a config option groups: groups }); }); });

#### Setting up the Drag Nodes

Now we need to create the Drag Nodes and assign them to the proper group.

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) {    //Snipped    var players = Y.one('#workarea').all('.player');    Y.each(players, function(v, k) {        var id = v.get('id'), groups = ['one', 'two'];        switch (id) {            case 'pt1':            case 'pt2':                groups = ['one'];                break;            case 'pb1':            case 'pb2':                groups = ['two'];                break;        }        var drag = new Y.DD.Drag({            node: v,            //Assign the Groups            groups: groups,            //Use Intersect Mode for the Target Calculations            dragMode: 'intersect',        }).plug(Y.Plugin.DDProxy, {            //We don't want the node to move on end drag            moveOnEnd: false        }).plug(Y.Plugin.DDConstrained, {            //Keep me inside the workarea            constrain2node: '#workarea'        });});

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) {
        //Snipped
        var players = Y.one('#workarea').all('.player');
        Y.each(players, function(v, k) {
            var id = v.get('id'), groups = ['one', 'two'];
            switch (id) {
                case 'pt1':
                case 'pt2':
                    groups = ['one'];
                    break;
                case 'pb1':
                case 'pb2':
                    groups = ['two'];
                    break;
            }
            var drag = new Y.DD.Drag({
                node: v,
                //Assign the Groups
                groups: groups,
                //Use Intersect Mode for the Target Calculations
                dragMode: 'intersect',
            }).plug(Y.Plugin.DDProxy, {
                //We don't want the node to move on end drag
                moveOnEnd: false
            }).plug(Y.Plugin.DDConstrained, {
                //Keep me inside the workarea
                constrain2node: '#workarea'
            });
    });

YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) { //Snipped var players = Y.one('#workarea').all('.player'); Y.each(players, function(v, k) { var id = v.get('id'), groups = ['one', 'two']; switch (id) { case 'pt1': case 'pt2': groups = ['one']; break; case 'pb1': case 'pb2': groups = ['two']; break; } var drag = new Y.DD.Drag({ node: v, //Assign the Groups groups: groups, //Use Intersect Mode for the Target Calculations dragMode: 'intersect', }).plug(Y.Plugin.DDProxy, { //We don't want the node to move on end drag moveOnEnd: false }).plug(Y.Plugin.DDConstrained, { //Keep me inside the workarea constrain2node: '#workarea' }); });

#### Handling the Drops and Moments

Now we are going to listen for Four Drag Events: `drag:start, drag:end, drag:drophit, drag:dropmiss`

    drag.on('drag:start', function() {    //In this event we setup some styles to make the nodes look pretty    var p = this.get('dragNode'),        n = this.get('node');        n.setStyle('opacity', .25);        if (!this._playerStart) {            this._playerStart = this.nodeXY;        }    //Put the Drag's HTML inside the proxy    p.set('innerHTML', n.get('innerHTML'));    //set some styles on the proxy    p.setStyles({        backgroundColor: n.getStyle('backgroundColor'),        color: n.getStyle('color'),        opacity: .65    });});drag.on('drag:end', function() {    //Undo some of the styles from the start    var n = this.get('node');    n.setStyle('opacity', '1');});drag.on('drag:drophit', function(e) {    //If we drop on a target, move to its position    var xy = e.drop.get('node').getXY();    this.get('node').setXY(xy);});drag.on('drag:dropmiss', function(e) {    //If we miss a target, move back to our start position    if (this._playerStart) {        this.get('node').setXY(this._playerStart);        this._playerStart = null;    }});

    drag.on('drag:start', function() {
        //In this event we setup some styles to make the nodes look pretty
        var p = this.get('dragNode'),
            n = this.get('node');
            n.setStyle('opacity', .25);
            if (!this._playerStart) {
                this._playerStart = this.nodeXY;
            }
        //Put the Drag's HTML inside the proxy
        p.set('innerHTML', n.get('innerHTML'));
        //set some styles on the proxy
        p.setStyles({
            backgroundColor: n.getStyle('backgroundColor'),
            color: n.getStyle('color'),
            opacity: .65
        });
    });
    drag.on('drag:end', function() {
        //Undo some of the styles from the start
        var n = this.get('node');
        n.setStyle('opacity', '1');
    });
    drag.on('drag:drophit', function(e) {
        //If we drop on a target, move to its position
        var xy = e.drop.get('node').getXY();
        this.get('node').setXY(xy);
    });
    drag.on('drag:dropmiss', function(e) {
        //If we miss a target, move back to our start position
        if (this._playerStart) {
            this.get('node').setXY(this._playerStart);
            this._playerStart = null;
        }
    });

drag.on('drag:start', function() { //In this event we setup some styles to make the nodes look pretty var p = this.get('dragNode'), n = this.get('node'); n.setStyle('opacity', .25); if (!this._playerStart) { this._playerStart = this.nodeXY; } //Put the Drag's HTML inside the proxy p.set('innerHTML', n.get('innerHTML')); //set some styles on the proxy p.setStyles({ backgroundColor: n.getStyle('backgroundColor'), color: n.getStyle('color'), opacity: .65 }); }); drag.on('drag:end', function() { //Undo some of the styles from the start var n = this.get('node'); n.setStyle('opacity', '1'); }); drag.on('drag:drophit', function(e) { //If we drop on a target, move to its position var xy = e.drop.get('node').getXY(); this.get('node').setXY(xy); }); drag.on('drag:dropmiss', function(e) { //If we miss a target, move back to our start position if (this._playerStart) { this.get('node').setXY(this._playerStart); this._playerStart = null; } });

#### Full Javascript Code

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) {     var slots = Y.one('#workarea').all('.slot');    Y.each(slots, function(v, k) {        var id = v.get('id'), groups = ['two'];        switch (id) {            case 't1':            case 't2':                groups = ['one'];                break;        }        var drop = new Y.DD.Drop({            node: v,            groups: groups        });    });     var players = Y.one('#workarea').all('.player');    Y.each(players, function(v, k) {        var id = v.get('id'), groups = ['one', 'two'];        switch (id) {            case 'pt1':            case 'pt2':                groups = ['one'];                break;            case 'pb1':            case 'pb2':                groups = ['two'];                break;        }        var drag = new Y.DD.Drag({            node: v,            groups: groups,            dragMode: 'intersect'        }).plug(Y.Plugin.DDProxy, {            moveOnEnd: false        }).plug(Y.Plugin.DDConstrained, {            constrain2node: '#workarea'        });        drag.on('drag:start', function() {            var p = this.get('dragNode'),                n = this.get('node');                n.setStyle('opacity', .25);                if (!this._playerStart) {                    this._playerStart = this.nodeXY;                }            p.set('innerHTML', n.get('innerHTML'));            p.setStyles({                backgroundColor: n.getStyle('backgroundColor'),                color: n.getStyle('color'),                opacity: .65            });        });        drag.on('drag:end', function() {            var n = this.get('node');            n.setStyle('opacity', '1');        });        drag.on('drag:drophit', function(e) {            var xy = e.drop.get('node').getXY();            this.get('node').setXY(xy);        });        drag.on('drag:dropmiss', function(e) {            if (this._playerStart) {                this.get('node').setXY(this._playerStart);                this._playerStart = null;            }        });    });  });

    YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) {

        var slots = Y.one('#workarea').all('.slot');
        Y.each(slots, function(v, k) {
            var id = v.get('id'), groups = ['two'];
            switch (id) {
                case 't1':
                case 't2':
                    groups = ['one'];
                    break;
            }
            var drop = new Y.DD.Drop({
                node: v,
                groups: groups
            });
        });

        var players = Y.one('#workarea').all('.player');
        Y.each(players, function(v, k) {
            var id = v.get('id'), groups = ['one', 'two'];
            switch (id) {
                case 'pt1':
                case 'pt2':
                    groups = ['one'];
                    break;
                case 'pb1':
                case 'pb2':
                    groups = ['two'];
                    break;
            }
            var drag = new Y.DD.Drag({
                node: v,
                groups: groups,
                dragMode: 'intersect'
            }).plug(Y.Plugin.DDProxy, {
                moveOnEnd: false
            }).plug(Y.Plugin.DDConstrained, {
                constrain2node: '#workarea'
            });
            drag.on('drag:start', function() {
                var p = this.get('dragNode'),
                    n = this.get('node');
                    n.setStyle('opacity', .25);
                    if (!this._playerStart) {
                        this._playerStart = this.nodeXY;
                    }
                p.set('innerHTML', n.get('innerHTML'));
                p.setStyles({
                    backgroundColor: n.getStyle('backgroundColor'),
                    color: n.getStyle('color'),
                    opacity: .65
                });
            });
            drag.on('drag:end', function() {
                var n = this.get('node');
                n.setStyle('opacity', '1');
            });
            drag.on('drag:drophit', function(e) {
                var xy = e.drop.get('node').getXY();
                this.get('node').setXY(xy);
            });
            drag.on('drag:dropmiss', function(e) {
                if (this._playerStart) {
                    this.get('node').setXY(this._playerStart);
                    this._playerStart = null;
                }
            });
        });

    });

YUI().use('dd-drop', 'dd-proxy', 'dd-constrain', function(Y) { var slots = Y.one('#workarea').all('.slot'); Y.each(slots, function(v, k) { var id = v.get('id'), groups = ['two']; switch (id) { case 't1': case 't2': groups = ['one']; break; } var drop = new Y.DD.Drop({ node: v, groups: groups }); }); var players = Y.one('#workarea').all('.player'); Y.each(players, function(v, k) { var id = v.get('id'), groups = ['one', 'two']; switch (id) { case 'pt1': case 'pt2': groups = ['one']; break; case 'pb1': case 'pb2': groups = ['two']; break; } var drag = new Y.DD.Drag({ node: v, groups: groups, dragMode: 'intersect' }).plug(Y.Plugin.DDProxy, { moveOnEnd: false }).plug(Y.Plugin.DDConstrained, { constrain2node: '#workarea' }); drag.on('drag:start', function() { var p = this.get('dragNode'), n = this.get('node'); n.setStyle('opacity', .25); if (!this._playerStart) { this._playerStart = this.nodeXY; } p.set('innerHTML', n.get('innerHTML')); p.setStyles({ backgroundColor: n.getStyle('backgroundColor'), color: n.getStyle('color'), opacity: .65 }); }); drag.on('drag:end', function() { var n = this.get('node'); n.setStyle('opacity', '1'); }); drag.on('drag:drophit', function(e) { var xy = e.drop.get('node').getXY(); this.get('node').setXY(xy); }); drag.on('drag:dropmiss', function(e) { if (this._playerStart) { this.get('node').setXY(this._playerStart); this._playerStart = null; } }); }); });

Copyright © 2010 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings