Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mattparker/358671 to your computer and use it in GitHub Desktop.
Save mattparker/358671 to your computer and use it in GitHub Desktop.
A really simple, drag-drop YUI3 treeview
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- @(#) $Id$ -->
<head>
<title>Extension of sortable lists as a tree view</title>
<!-- Dependency -->
<link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/3.1.0/build/cssfonts/fonts-min.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/3.1.0/build/yui/yui.js"></script>
<!--
<script src="http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js" ></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/selector/selector-min.js" ></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/dom/dom-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/event/event-min.js" ></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/event-delegate/event-delegate-min.js" ></script>
-->
<style type="text/css">
ol{
/* border-left:1px dotted gray;*/
list-style-image:none;
list-style-position:inside;
list-style-type:none;
padding-left:0;
padding-top:0;
}
ol>li.haschildren{
/*background:transparent url(minus.bmp) no-repeat scroll 0 0;*/
background: transparent url(http://yui.yahooapis.com/2.8.0r4/build/treeview/assets/skins/sam/treeview-sprite.gif) no-repeat scroll 0 -6400px;
}
ol>li.collapsed{
/*background:transparent url(plus.bmp) no-repeat scroll 0 0;*/
background:transparent url(http://yui.yahooapis.com/2.8.0r4/build/treeview/assets/skins/sam/treeview-sprite.gif) no-repeat scroll 0 -4000px;
}
ol>li.collapsed ol{
display: none;
}
ol li{
background:transparent url(http://yui.yahooapis.com/2.8.0r4/build/treeview/assets/skins/sam/treeview-sprite.gif) no-repeat scroll 0 -5600px;
margin-left: 0 0 0 -10px;
padding-top:5px;
padding-left:30px;
}
ol li span{
margin-left: -30px;
padding-left: 30px;
}
</style>
</head>
<body>
Playing with sortable in YUI3 <a href="http://developer.yahoo.com/yui/3/sortable/">
http://developer.yahoo.com/yui/3/sortable/</a> and using css to get some treeview
stylee. Reasonable first effort...
<div id="container">
<div>
<ol id="tree">
<li><span>item one</span></li>
<li><span>item 2</span>
<ol>
<li><span>item 2.1</span></li>
<li><span>item 2.2</span>
<ol>
<li><span>item 2.2.1</span></li>
<li><span>item 2.2.2</span></li>
<li><span>item 2.2.3</span></li>
<li><span>item 2.2.4</span></li>
</ol>
</li>
</ol>
</li>
<li><span>item 3</span></li>
</ol>
</div>
</div>
<script type="text/javascript">
//////////////////////////////////////////////////////////
// create a sortable list
// from one of the examples.
YUI( {filter: 'raw'} ).use('dd-constrain', 'sortable', function(Y) {
var list1 = new Y.Sortable({
container: '#tree',
nodes: 'li',
opacity: '.5',
moveType: "insert"
});
list1.delegate.dd.plug(Y.Plugin.DDConstrained, {
constrain2node: '#tree'
});
// Using nested lists with Sortable has a bug... ticket filed!
///////////////////////////////////////////////////////////////
// Handle the drag drop events
// Key thing is
// nodes we're moving around
var addedNode, newNode;
// make a new node that can be inserted as a new tree sometimes
Y.DD.DDM.on("drag:start", function(ev){
//newNode = document.createElement("ol");
newNode = Y.Node.create( "<ol></ol>" );
newNode.setAttribute("id", Y.guid() );
//newNode.appendChild( document.createElement( "ol" ) );
});
// insert the nodes where needed
Y.DD.DDM.on("drag:over", function(ev){
var t = ev.drop.get("node"),
tOl = t.one( "ol" );
// if we've over an li, add the new ol child block
switch( t.get("nodeName").toLowerCase() ) {
case "li":
// try and append it to existing ol on the target
if( tOl ) {
try {
tOl.append( ev.drag.get("node") );
} catch(e){}
}
// else add a new ol to the target
else {
// remove it from where it was
if( addedNode !== undefined ) {
try{
addedNode.remove();
} catch(e){}
}
// try adding it
try{
t.append( newNode );
newNode.append( ev.drag.get( "node" ) );
addedNode = newNode;//.getAttribute("id") );
} catch(e){ }
}
break;
// if we're over an ol, just add this as a new li child
case "ol":
try{
t.append( ev.drag.get("node" ) );
}
catch(e){}
break;
default:
ev.halt();
break;
}
});
// reset things at the end of the drag
Y.DD.DDM.after("drag:end", function( ev ){
addedNode = undefined;
newNode = undefined;
// DD somewhere sets some element styles, which mess up alignment somewhere
// in IE
ev.target.get("node").removeAttribute( "style" );
// re-read the DOM of the tree to put + and - classes in the right places
TreeView( "#tree" );
} );
///////////////////////////////////////////////////
// The 'TreeView'
// add a delegated listener to expand collapsed sub trees
Y.one( "#tree" ).delegate( "click" , function( ev ){
if( ev.currentTarget.get('parentNode').one("ol") ){
ev.currentTarget.get('parentNode').toggleClass("collapsed");
}
} , "li.haschildren span" );
// add "haschildren" classes where needed
// just iterates the DOM looking for li's with ol li children (ie a sub tree)
var TreeView = function( el ){
Y.each( Y.one( el ).all( "li" ) , function(node){
if( node.one( "ol li" ) ) {
node.addClass( "haschildren" );
} else {
node.removeClass( "haschildren" );
}
});
}
// call treeview first time
TreeView( "#tree" );
});
/*
var Dom = YAHOO.util.Dom;
YAHOO.util.Event.delegate( "tree" , "click" , function(ev , el){
console.log(arguments);
if( Dom.hasClass( el.parentNode , "collapsed" ) ){
Dom.removeClass( el.parentNode , "collapsed" );
} else {
Dom.addClass( el.parentNode, "collapsed" );
}
}, "li.haschildren span" );
*/
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment