scroll-list.mustache revision 5b139d58acfcae4b1bcab5a895706abafc2a87a0
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<div class="intro">
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>This example shows how to make a sortable list using Custom Event Bubbling and Node scrolling.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<div class="example">
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass {{>scroll-list-source}}
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Setting up the lists</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>First we will make a list that we want to make sortable.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass {{>scroll-list-source-html}}
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Make it scrollable</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>Now add some CSS to make it scrollable.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass /* Snipped */
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass overflow: auto;
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Setting up the YUI Instance</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>Now we need to create our YUI instance and tell it to load the `dd-constrain`,
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass`dd-proxy`, `dd-drop` and `dd-scroll`, modules.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassYUI().use('dd-constrain', 'dd-proxy', 'dd-drop', 'dd-scroll', function(Y) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Making the Nodes Drag Instances and Drop Targets</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>Now we have our YUI instance ready, we can make the list items draggable. We will do this using `Y.Node.all`</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>We will be passing the selector string `#play ul li` to `Y.all` to have it return us a `NodeList` of the li's in our 2 lists.
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassUsing this selector syntax we will be able to add new list markup to the `#play` div and not have to change our code.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>Then we will walk that `NodeList` and create our draggable Nodes.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>Also note that we are using the Node's `parentNode` as our node in the DDNodeScroll plugin.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass//Get the list of li's in the lists and make them draggable
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glassvar lis = Y.all('#play ul li');
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glasslis.each(function(v, k) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass var dd = new Y.DD.Drag({
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Make it Drop target and pass this config to the Drop constructor
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass padding: '0 0 0 20'
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Don't move the node at the end of the drag
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass moveOnEnd: false
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Keep it inside the #play node
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass constrain2node: '#play'
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass node: v.get('parentNode')
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Making the List Drop Targets too</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>We need to make each UL node a Drop Target so we can catch drops on the empty space of the list.
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassUsing this selector syntax we will be able to add new list markup to the `#play` div and not have to change our code.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass//Create simple targets for the 2 lists.
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glassvar uls = Y.all('#play ul');
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glassuls.each(function(v, k) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass var tar = new Y.DD.Drop({
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Using Event Bubbling</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<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>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Start Drag Event</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>The first thing we will do is handle the `drag:start` event. In this event, we will setup some styles to apply to the `node` and `dragNode` of the current Drag instance.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>We will also be copying the `innerHTML` of the `node` and copying that to the `innerHTML` of the `dragNode`.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p><em>It should be noted, that
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glassdoing 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
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glassof the nodes inside the `node` that is being dragged.
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassY.DD.DDM.on('drag:start', function(e) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Get our drag object
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Set some styles here
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drag.get('node').setStyle('opacity', '.25');
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drag.get('dragNode').setStyles({
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass opacity: '.5',
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass borderColor: drag.get('node').getStyle('borderColor'),
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass backgroundColor: drag.get('node').getStyle('backgroundColor')
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>End Drag Event</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>In this event, we will reset some of the styles set in the `drag:start` event.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassY.DD.DDM.on('drag:end', function(e) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Put out styles back
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drag.get('node').setStyles({
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass visibility: '',
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass opacity: '1'
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Drag Event</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>In this event, we will track the up/down movement for later use.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassY.DD.DDM.on('drag:drag', function(e) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Get the last y point
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //is it greater than the lastY var?
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass if (y < lastY) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //We are going up
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass goingUp = true;
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //We are going down.
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass goingUp = false;
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Cache for next check
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Added to support scrolling
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Over Drop Event</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>In this event, we know which target we are over, so we add the Drag node to the list either above or below the current Drop Target.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<p>Here we also change the node which needs to be scrolled. Since we are changing lists, we need to tell the scrolling plugin instance that it needs to check against another node.</p>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassY.DD.DDM.on('drop:over', function(e) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Get a reference to out drag and drop nodes
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass var drag = e.drag.get('node'),
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drop = e.drop.get('node');
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Are we dropping on a li node?
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass if (drop.get('tagName').toLowerCase() === 'li') {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Are we not going up?
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass if (!goingUp) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drop = drop.get('nextSibling');
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Add the node to this list
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass e.drop.get('node').get('parentNode').insertBefore(drag, drop);
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Set the new parentScroll on the nodescroll plugin
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass e.drag.nodescroll.set('parentScroll', e.drop.get('node').get('parentNode'));
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Resize this node's shim, so we can drop on it later.
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Drop Hit Event</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<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>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav GlassY.DD.DDM.on('drag:drophit', function(e) {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass var drop = e.drop.get('node'),
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass drag = e.drag.get('node');
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //if we are not on an li, we must have been dropped on a ul
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass if (drop.get('tagName').toLowerCase() !== 'li') {
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass //Set the new parentScroll on the nodescroll plugin
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass e.drag.nodescroll.set('parentScroll', e.drop.get('node'));
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass<h3>Full Javascript Source</h3>
5b139d58acfcae4b1bcab5a895706abafc2a87a0Dav Glass{{>scroll-list-source-js}}