cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<div class="intro">
663272199096ed57917f2bfb1d748a0a622b7b24Tinderbox User<p>This example shows how to make a sortable list using Custom Event Bubbling.</p>
663272199096ed57917f2bfb1d748a0a622b7b24Tinderbox User</div>
01eb8e213b335b77b114202e8152c8114de8ddecAutomatic Updater
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed<div class="example">
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed {{>list-drag-source}}
663272199096ed57917f2bfb1d748a0a622b7b24Tinderbox User</div>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed
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
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
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>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User </ul>
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>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed </ul>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User</div>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
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>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User```
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy ReedYUI().use('dd-constrain', 'dd-proxy', 'dd-drop', function(Y) {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed
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
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
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 node: v,
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Make it Drop target and pass this config to the Drop constructor
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User target: {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User padding: '0 0 0 20'
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User }).plug(Y.Plugin.DDProxy, {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Don't move the node at the end of the drag
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User moveOnEnd: false
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed }).plug(Y.Plugin.DDConstrained, {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Keep it inside the #play node
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed constrain2node: '#play'
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed });
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User});
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
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
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User```
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 node: v
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed });
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User});
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed
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>
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User
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.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User</em></p>
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed```
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy ReedY.DD.DDM.on('drag:start', function(e) {
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Get our drag object
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User var drag = e.target;
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed //Set some styles here
cdcd52e680bd80f0da612c0fcf949b50ef86500bJeremy Reed drag.get('node').setStyle('opacity', '.25');
drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
drag.get('dragNode').setStyles({
opacity: '.5',
borderColor: drag.get('node').getStyle('borderColor'),
backgroundColor: drag.get('node').getStyle('backgroundColor')
});
});
```
<h3>End Drag Event</h3>
<p>In this event, we will reset some of the styles set in the drag:start event.</p>
```
Y.DD.DDM.on('drag:end', function(e) {
var drag = e.target;
//Put our styles back
drag.get('node').setStyles({
visibility: '',
opacity: '1'
});
});
```
<h3>Drag Event</h3>
<p>In this event, we will track the up/down movement for later use.</p>
```
Y.DD.DDM.on('drag:drag', function(e) {
//Get the last y point
var y = e.target.lastXY[1];
//is it greater than the lastY var?
if (y &lt; lastY) {
//We are going up
goingUp = true;
} else {
//We are going down.
goingUp = false;
}
//Cache for next check
lastY = y;
});
```
<h3>Over Drop Event</h3>
<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) {
//Get a reference to our drag and drop nodes
var drag = e.drag.get('node'),
drop = e.drop.get('node');
//Are we dropping on a li node?
if (drop.get('tagName').toLowerCase() === 'li') {
//Are we not going up?
if (!goingUp) {
drop = drop.get('nextSibling');
}
//Add the node to this list
e.drop.get('node').get('parentNode').insertBefore(drag, drop);
//Resize this nodes shim, so we can drop on it later.
e.drop.sizeShim();
}
});
```
<h3>Drop Hit Event</h3>
<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 we are not on an li, we must have been dropped on a ul
if (drop.get('tagName').toLowerCase() !== 'li') {
if (!drop.contains(drag)) {
drop.appendChild(drag);
}
}
});
```
<h3>Full Javascript Source</h3>
```
{{>list-drag-source-js}}
```