kvaTree jQuery plugin
Last week I was working on my CMS and I found out I need to implement a tree structure menu. I thought there will be a lot of such plugins for jQuery already. Well, there were some, there were not much, but what's really important, none of them did fit my expectations right. Well, you know, you want something programmed to fit your needs, you best do it yourself :)
So here I was standing on the zero point. I wanted also break into the jQuery plugin development (yes, this is my first jQuery plugin) and this was fine opportunity. Well, enough of preface, let's stick to the business.
I'll start with a link to demonstration page, so you can see the result of my work, here it is: demo page.
It's a really simple tree with only a few available settings. I didn't want a robust plugin, because I know how to manage my AJAX functionalities, animations and effects and I think that I'm not the only one with this oppinion. I really didn't need some tree to do this for me (or force me to do so). One last thought here. The word unobtrusive is used frequently on jQuery page (no arguments here) and among jQuery plugins, but I lacked this feeling when I was searching for the tree plugin. I'm not calling my kvaTree unobtrusive! ... :)
If you saw the demo page and if you're interested in implementing my kvaTree, here's the documentation. You'll need to download and unpack the demo file package. In this package the index.html file is for the sake of example, besides there are three dirs there: css, img and js. All three are important and you'll have to use them in order to use kvaTree. One comment for the js dir. There are four script files:
jquery.js - jQuery library v1.2.6 (full, not packed)
jquery-ui-personalized-1.5.3.min.js - jQuery UI v1.5.3 (ui.core, ui.draggable, ui.droppable)
kvaTree.js - kvaTree js file (full, not packed)
kvaTree.min.js - kvaTree js file packed
In my demo page and in this download I use kvaTree.min.js as default. I packed full version if someone would like to see / edit my code.
One important thing - Due to the fact, that jQuery UI v1.5.3 is compatible with jQuery 1.2.6 you have to use these library versions. You can also (I guess, not tested) use the following combination:
jQuery v1.3.1 and jQuery UI v1.6.x.
Provided you downloaded this package I'll stick to the documentation:
The simple initialization looks like this:
Note: Be sure to identify the ul by className or id to prevent launching kvaTree on other UL's or children UL's.
kvaTree applies only on UL elements. There's only one rule for the UL element: his LI elements have to have their texts wrapped in SPAN elements. The last thing you may or may not need to do is assign open class to the LI elements, which you want to be expanded on the start. If you don't want some nodes (folders) level to be increased (via adding a node [subtree] or via dropping a node [subtree]) you can prevent this by adding a fixedLevel class to this node (Leafs can still be added to this node!). Your HTML code of the UL you want to kvaTree may look like this:
Tip: If you want node to be displayed as node (folder) by default just assign class node to this LI node.
Tip: If you want an UL element inside kvaTree not to be processed by kvaTree just assign class name non-kvaTree to this UL element.
When you click the sign (plus or minus) the corresponding node will expand | collapse.
When you click a node (to be exact - the text of this node) the active class will be assigned to this node (by default, you can override this behavior - explained later on).
When you double click a node with subitems (children ULs) this node is expanded | collapsed (by default, you can override this behavior - explained later on).
The other functionalities such as tree management and drag & drop are explained on the demo page.
There are few settings available for kvaTree:
autoclose - close opened sibilng(s) on Expand? Default true. (Boolean)
background - background color of kvaTree (default: white). When your background of kvaTree is different than white, you have to set this value to this background color, for proper cleaners drawing. (String)
imgFolder - kvaTree images folder (default: "img"). Since some background CSS properties are being set in the kvaTree.js, this option has to be set properly. (String)
overrideEvents - If true - the custom defined events will not fire default behavior, if false (default) - the custom events fire default behavior before launching custom event. (Boolean)
dragdrop - Enable drag & drop (default true - Boolean)
And a few events for kvaTree:
onClick(event,node) - event fired after node is clicked
onDblClick(event,node) - event fired after node is double clicked
onDrag(event,node) - event fired after node is dragged
onDrop(event,node) - event fired after node is dropped
onExpand(node) - event fired after node (with subitems) is expanded
onCollapse(node) - event fired after node (with subitems) is collapsed
onAddNode(node) - event fired after node is added
onEditNode(node) - event fired after node is edited
onDeleteNode(node,parent) - event fired after node is deleted
Note: all these events take the node argument. This node passed to these events is always (for the first four - non manipulation - mentioned events) the jQuery object of the LI element which holds either the text span you clicked or the sign span you clicked. For the manipulation events (the last three mentioned) - the node argument represents the jQuery object of the manipulated LI element. The onDeleteNode event takes also a second argument - parent. This is always the parent LI.node of the deleted node.
Here is how the initialization with full featured settings may look like:
If you want your kvaTree to be manageable you will have to assign this functionality to your custom elements ... I will post a simple way to do this which I used in my demo page too.
The important thing is to use methods AddNode, EditNode ... with the o (kvaTree obj) parameter. I provided it through the Bind function. This may be a little confusing, since I use another parameter, the important is pretty much just the inside of each click event function.
If you want to use AJAX to alter UL structure, you'll need to reinitialize kvaTree after it's done. The simplest way to do it is may look like this:
Few words for this example. I used obj var for my UL jQuery object (This is important since we have to launch initialization on this object). Options are the same as on the example above with slight difference - I created new object for them. The final step is (as explained in comments in this code) to put the line - obj.kvaTree.InitKvaTree(obj); in code to the place where your AJAX request is done. This will reinitialize your kvaTree.
You can download the demo file package which contains everything needed. Feel free to use this package and all its parts in any way. You can use it, edit it, reproduce it ...
I declare kvaTree complete. If I found any bug or if a bug will be reported to me I will try to fix it for sure :)
This plugin was tested successfully on Firefox 3+, Opera 9.5+, Chrome 1.0 and Internet Explorer 6.
So here I was standing on the zero point. I wanted also break into the jQuery plugin development (yes, this is my first jQuery plugin) and this was fine opportunity. Well, enough of preface, let's stick to the business.
kvaTree plugin demo
I'll start with a link to demonstration page, so you can see the result of my work, here it is: demo page.
It's a really simple tree with only a few available settings. I didn't want a robust plugin, because I know how to manage my AJAX functionalities, animations and effects and I think that I'm not the only one with this oppinion. I really didn't need some tree to do this for me (or force me to do so). One last thought here. The word unobtrusive is used frequently on jQuery page (no arguments here) and among jQuery plugins, but I lacked this feeling when I was searching for the tree plugin. I'm not calling my kvaTree unobtrusive! ... :)
Documentation
If you saw the demo page and if you're interested in implementing my kvaTree, here's the documentation. You'll need to download and unpack the demo file package. In this package the index.html file is for the sake of example, besides there are three dirs there: css, img and js. All three are important and you'll have to use them in order to use kvaTree. One comment for the js dir. There are four script files:
jquery.js - jQuery library v1.2.6 (full, not packed)
jquery-ui-personalized-1.5.3.min.js - jQuery UI v1.5.3 (ui.core, ui.draggable, ui.droppable)
kvaTree.js - kvaTree js file (full, not packed)
kvaTree.min.js - kvaTree js file packed
In my demo page and in this download I use kvaTree.min.js as default. I packed full version if someone would like to see / edit my code.
One important thing - Due to the fact, that jQuery UI v1.5.3 is compatible with jQuery 1.2.6 you have to use these library versions. You can also (I guess, not tested) use the following combination:
jQuery v1.3.1 and jQuery UI v1.6.x.
Provided you downloaded this package I'll stick to the documentation:
The simple initialization looks like this:
$(function () { $('ul#ulid').kvaTree(); });
Note: Be sure to identify the ul by className or id to prevent launching kvaTree on other UL's or children UL's.
kvaTree applies only on UL elements. There's only one rule for the UL element: his LI elements have to have their texts wrapped in SPAN elements. The last thing you may or may not need to do is assign open class to the LI elements, which you want to be expanded on the start. If you don't want some nodes (folders) level to be increased (via adding a node [subtree] or via dropping a node [subtree]) you can prevent this by adding a fixedLevel class to this node (Leafs can still be added to this node!). Your HTML code of the UL you want to kvaTree may look like this:
<ul> <li><span>Item 1 here</span></li> <li><span>Item 2 here</span></li> <li class="open"> <span>Item 3 here</span> <ul> <li><span>Item 1 here</span></li> <li><span>Item 2 here</span></li> <li><span>Item 3 here</span></li> <li><span>Item 4 here</span></li> </ul> </li> <li> <span>Item 4 here</span> <ul> <li><span>Item 1 here</span></li> <li><span>Item 2 here</span></li> <li><span>Item 3 here</span></li> <li><span>Item 4 here</span></li> </ul> </li> </ul>
Tip: If you want node to be displayed as node (folder) by default just assign class node to this LI node.
Tip: If you want an UL element inside kvaTree not to be processed by kvaTree just assign class name non-kvaTree to this UL element.
kvaTree behavior
When you click the sign (plus or minus) the corresponding node will expand | collapse.
When you click a node (to be exact - the text of this node) the active class will be assigned to this node (by default, you can override this behavior - explained later on).
When you double click a node with subitems (children ULs) this node is expanded | collapsed (by default, you can override this behavior - explained later on).
The other functionalities such as tree management and drag & drop are explained on the demo page.
kvaTree options
There are few settings available for kvaTree:
autoclose - close opened sibilng(s) on Expand? Default true. (Boolean)
background - background color of kvaTree (default: white). When your background of kvaTree is different than white, you have to set this value to this background color, for proper cleaners drawing. (String)
imgFolder - kvaTree images folder (default: "img"). Since some background CSS properties are being set in the kvaTree.js, this option has to be set properly. (String)
overrideEvents - If true - the custom defined events will not fire default behavior, if false (default) - the custom events fire default behavior before launching custom event. (Boolean)
dragdrop - Enable drag & drop (default true - Boolean)
And a few events for kvaTree:
onClick(event,node) - event fired after node is clicked
onDblClick(event,node) - event fired after node is double clicked
onDrag(event,node) - event fired after node is dragged
onDrop(event,node) - event fired after node is dropped
onExpand(node) - event fired after node (with subitems) is expanded
onCollapse(node) - event fired after node (with subitems) is collapsed
onAddNode(node) - event fired after node is added
onEditNode(node) - event fired after node is edited
onDeleteNode(node,parent) - event fired after node is deleted
Note: all these events take the node argument. This node passed to these events is always (for the first four - non manipulation - mentioned events) the jQuery object of the LI element which holds either the text span you clicked or the sign span you clicked. For the manipulation events (the last three mentioned) - the node argument represents the jQuery object of the manipulated LI element. The onDeleteNode event takes also a second argument - parent. This is always the parent LI.node of the deleted node.
Here is how the initialization with full featured settings may look like:
$(function () { $('ul#ulid').kvaTree({ autoclose: true, background: 'white', imgFolder: 'img/kvaTree/', overrideEvents: true, dragdrop: false, onClick: function (event,node) { //your custom onClick function }, onDblClick: function (event,node) { //your custom onDblClick function }, onExpand: function (node) { //your custom onExpand function }, onCollapse: function (node) { //your custom onCollapse function }, onAddNode: function (node) { //your custom onAddNode function }, onEditNode: function (node) { //your custom onEditNode function }, onDeleteNode: function (node,parent) { //your custom onDeleteNode function } }); });
Managing kvaTree
If you want your kvaTree to be manageable you will have to assign this functionality to your custom elements ... I will post a simple way to do this which I used in my demo page too.
function Bind(h,o) { $(h + ' p.addnode').click(function () { o.kvaTree.AddNode(o,'node'); }); $(h + ' p.addleaf').click(function () { o.kvaTree.AddNode(o,'leaf'); }); $(h + ' p.edit').click(function () { o.kvaTree.EditNode(o); }); $(h + ' p.del').click(function () { o.kvaTree.DeleteNode(o); }); }//Bind $(function () { var obj = $('ul#tree1'); var opts = {}; obj.kvaTree(opts); Bind('.ctrls:eq(0)',obj); });
The important thing is to use methods AddNode, EditNode ... with the o (kvaTree obj) parameter. I provided it through the Bind function. This may be a little confusing, since I use another parameter, the important is pretty much just the inside of each click event function.
Important - when you use AJAX
If you want to use AJAX to alter UL structure, you'll need to reinitialize kvaTree after it's done. The simplest way to do it is may look like this:
var obj = $('ul#ulid'); //your UL you want to kvaTree var opts = { //options for your kvaTree onExpand: function (node) { //your custom onExpand function AJAXRequest('','test/lol.php',function (xml) { node.find('ul').append('<li><span>' + $(xml).find('ul').text() + '</span></li>'); obj.kvaTree.InitKvaTree(obj); /** * * AJAXRequest is my AJAX call function, it's not important how this function works, * the only important thing is to call(!!!) the line: * * obj.kvaTree.InitKvaTree(obj); * * after your AJAX request is done to apply kvaTree on your new structure * */ }); } }; obj.kvaTree(opts); //kvaTree itself - new form
Few words for this example. I used obj var for my UL jQuery object (This is important since we have to launch initialization on this object). Options are the same as on the example above with slight difference - I created new object for them. The final step is (as explained in comments in this code) to put the line - obj.kvaTree.InitKvaTree(obj); in code to the place where your AJAX request is done. This will reinitialize your kvaTree.
Download
You can download the demo file package which contains everything needed. Feel free to use this package and all its parts in any way. You can use it, edit it, reproduce it ...
Future development
I declare kvaTree complete. If I found any bug or if a bug will be reported to me I will try to fix it for sure :)
Compatibility
This plugin was tested successfully on Firefox 3+, Opera 9.5+, Chrome 1.0 and Internet Explorer 6.
Dec
31st