cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<div class="intro">
663272199096ed57917f2bfb1d748a0a622b7b24Tinderbox User<p>This example shows how to make a sortable list using Custom Event Bubbling.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<div class="example">
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed {{>list-drag-source}}
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<h3>Setting up the lists</h3>
663272199096ed57917f2bfb1d748a0a622b7b24Tinderbox User<p>First we will make some lists that we want to make sortable.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<div id="play">
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <ul id="list1">
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list1">Item #1</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list1">Item #2</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list1">Item #3</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list1">Item #4</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list1">Item #5</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <ul id="list2">
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User <li class="list2">Item #1</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list2">Item #2</li>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User <li class="list2">Item #3</li>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed <li class="list2">Item #4</li>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User <li class="list2">Item #5</li>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User<h3>Setting up the YUI Instance</h3>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User<p>Now we need to create our YUI instance and tell it to load the `dd-constrain`, `dd-proxy` and `dd-drop`, modules.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy ReedYUI().use('dd-constrain', 'dd-proxy', 'dd-drop', function(Y) {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<h3>Making the Nodes Drag Instances and Drop Targets</h3>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User<p>Now we have our YUI instance ready, we can make the list items draggable. We will do this using `Y.Node.all`</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<p>We will be passing the selector string `#play ul li` to `Y.Node.all` to have it return a `NodeList` of the li's in our two lists.
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy ReedUsing this selector syntax we will be able to add new list markup to the `#play` div and not have to change our code.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<p>Then we will walk that `NodeList` and create our draggable Nodes.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<p>Note that we are adding the `DDProxy` and `DDConstrained` plugins to each Drag instance, and setting the following configuration options: `moveOnEnd, constrain2node, target`.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed//Get the list of li's in the lists and make them draggable
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reedvar lis = Y.Node.all('#play ul li');
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reedlis.each(function(v, k) {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed var dd = new Y.DD.Drag({
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Make it Drop target and pass this config to the Drop constructor
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User padding: '0 0 0 20'
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Don't move the node at the end of the drag
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User moveOnEnd: false
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Keep it inside the #play node
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed constrain2node: '#play'
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<h3>Making the List Drop Targets too</h3>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<p>We need to make the UL nodes a Drop Target so we can catch drops on the empty space of the list.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox UserUsing this selector syntax we will be able to add new list markup to the `#play` div and not have to change our code.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed//Create simple targets for the 2 lists.
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reedvar uls = Y.Node.all('#play ul');
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reeduls.each(function(v, k) {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed var tar = new Y.DD.Drop({
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User<h3>Using Event Bubbling</h3>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<p>By default, all Drag and Drop instances bubble their events up to the DragDropMgr. In this example we are assuming that there are no other Drag Operations in this YUI Instance.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<h3>Start Drag Event</h3>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User<p>The first thing we will do is handle the drag:start event. In this event, we will set up some styles to apply to the `node` and `dragNode` of the current Drag instance.</p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<p>We will also be copying the `innerHTML` of the `node` and copying that to the `innerHTML` of the `dragNode`. </p>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User<p><em>It should be noted, that
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userdoing this will also copy any `id`'s of the nodes inside the `node`. So if you are using this on something that is `id` based, you may need to remove the `id`'s
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userof the nodes inside the `node` that is being dragged.
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy ReedY.DD.DDM.on('drag:start', function(e) {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Get our drag object
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Set some styles here
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed drag.get('node').setStyle('opacity', '.25');
drag.get('dragNode').setStyles({
borderColor: drag.get('node').getStyle('borderColor'),
backgroundColor: drag.get('node').getStyle('backgroundColor')
Y.DD.DDM.on('drag:end', function(e) {
var drag = e.target;
drag.get('node').setStyles({
<p>In this event, we will track the up/down movement for later use.</p>
Y.DD.DDM.on('drag:drag', function(e) {
var y = e.target.lastXY[1];
<p>In this event, know which Target we are over, so we add the Drag node to the list either above or below the current Drop Target.</p>
Y.DD.DDM.on('drop:over', function(e) {
var drag = e.drag.get('node'),
drop = e.drop.get('node');
if (drop.get('tagName').toLowerCase() === 'li') {
drop = drop.get('nextSibling');
e.drop.get('node').get('parentNode').insertBefore(drag, drop);
<p>In this event, we check to see if the target that was dropped on was not an LI node. If it wasn't, then we know it was dropped on the empty space of the UL.</p>
Y.DD.DDM.on('drag:drophit', function(e) {
var drop = e.drop.get('node'),
drag = e.drag.get('node');
if (drop.get('tagName').toLowerCase() !== 'li') {
if (!drop.contains(drag)) {
drop.appendChild(drag);