collapsing parts of the tree doesn't make sibling trees move

master
Wes 2012-03-16 14:14:54 +00:00
commit fb6808bd07
3 changed files with 467 additions and 473 deletions

View File

@ -1,87 +1,85 @@
/** /**
* jQuery org-chart/tree plugin. * jQuery org-chart/tree plugin.
* *
* Author: Wes Nolte * Author: Wes Nolte
* http://twitter.com/wesnolte * http://twitter.com/wesnolte
* *
* Based on the work of Mark Lee * Based on the work of Mark Lee
* http://www.capricasoftware.co.uk * http://www.capricasoftware.co.uk
* *
* ID implementation fixed by Adrian Hinz * This software is licensed under the Creative Commons Attribution-ShareAlike
* * 3.0 License.
* This software is licensed under the Creative Commons Attribution-ShareAlike *
* 3.0 License. * See here for license terms:
* * http://creativecommons.org/licenses/by-sa/3.0
* See here for license terms: */
* http://creativecommons.org/licenses/by-sa/3.0
*/
(function($) { (function($) {
$.fn.jOrgChart = function(options) { $.fn.jOrgChart = function(options) {
var opts = $.extend({}, $.fn.jOrgChart.defaults, options); var opts = $.extend({}, $.fn.jOrgChart.defaults, options);
var $appendTo = $(opts.chartElement); var $appendTo = $(opts.chartElement);
// build the tree // build the tree
$this = $(this); $this = $(this);
var $container = $("<div class='" + opts.chartClass + "'/>"); var $container = $("<div class='" + opts.chartClass + "'/>");
if($this.is("ul")) { if($this.is("ul")) {
buildNode($this.find("li:first"), $container, 0, opts); buildNode($this.find("li:first"), $container, 0, opts);
} }
else if($this.is("li")) { else if($this.is("li")) {
buildNode($this, $container, 0, opts); buildNode($this, $container, 0, opts);
} }
$appendTo.append($container); $appendTo.append($container);
// add drag and drop if enabled // add drag and drop if enabled
if(opts.dragAndDrop){ if(opts.dragAndDrop){
$('div.node').draggable({ $('div.node').draggable({
cursor : 'move', cursor : 'move',
distance : 40, distance : 40,
helper : 'clone', helper : 'clone',
opacity : 0.8, opacity : 0.8,
revert : true, revert : true,
revertDuration : 100, revertDuration : 100,
snap : 'div.node.expanded', snap : 'div.node.expanded',
snapMode : 'inner', snapMode : 'inner',
stack : 'div.node' stack : 'div.node'
}); });
$('div.node').droppable({ $('div.node').droppable({
accept : '.node', accept : '.node',
activeClass : 'drag-active', activeClass : 'drag-active',
hoverClass : 'drop-hover' hoverClass : 'drop-hover'
}); });
// Drag start event handler for nodes // Drag start event handler for nodes
$('div.node').bind("dragstart", function handleDragStart( event, ui ){ $('div.node').bind("dragstart", function handleDragStart( event, ui ){
var sourceNode = $(this); var sourceNode = $(this);
sourceNode.parentsUntil('.node-container') sourceNode.parentsUntil('.node-container')
.find('*') .find('*')
.filter('.node') .filter('.node')
.droppable('disable'); .droppable('disable');
}); });
// Drag stop event handler for nodes // Drag stop event handler for nodes
$('div.node').bind("dragstop", function handleDragStop( event, ui ){ $('div.node').bind("dragstop", function handleDragStop( event, ui ){
/* reload the plugin */ /* reload the plugin */
$(opts.chartElement).children().remove(); $(opts.chartElement).children().remove();
$this.jOrgChart(opts); $this.jOrgChart(opts);
}); });
// Drop event handler for nodes // Drop event handler for nodes
$('div.node').bind("drop", function handleDropEvent( event, ui ) { $('div.node').bind("drop", function handleDropEvent( event, ui ) {
var sourceNode = ui.draggable; var sourceNode = ui.draggable;
var targetNode = $(this); var targetNode = $(this);
// finding nodes based on plaintext and html // finding nodes based on plaintext and html
// content is hard! // content is hard!
var targetLi = $('li').filter(function(){ var targetLi = $('li').filter(function(){
li = $(this).clone() li = $(this).clone()
.children("ul,li") .children("ul,li")
.remove() .remove()
.end(); .end();
var attr = li.attr('id'); var attr = li.attr('id');
if (typeof attr !== 'undefined' && attr !== false) { if (typeof attr !== 'undefined' && attr !== false) {
@ -91,13 +89,13 @@
return li.html() == targetNode.html(); return li.html() == targetNode.html();
} }
}); });
var sourceLi = $('li').filter(function(){ var sourceLi = $('li').filter(function(){
li = $(this).clone() li = $(this).clone()
.children("ul,li") .children("ul,li")
.remove() .remove()
.end(); .end();
var attr = li.attr('id'); var attr = li.attr('id');
if (typeof attr !== 'undefined' && attr !== false) { if (typeof attr !== 'undefined' && attr !== false) {
@ -107,161 +105,160 @@
return li.html() == sourceNode.html(); return li.html() == sourceNode.html();
} }
}); });
var sourceliClone = sourceLi.clone(); var sourceliClone = sourceLi.clone();
var sourceUl = sourceLi.parent('ul'); var sourceUl = sourceLi.parent('ul');
if(sourceUl.children('li').size() > 1){ if(sourceUl.children('li').size() > 1){
sourceLi.remove(); sourceLi.remove();
}else{
sourceUl.remove();
}
var id = sourceLi.attr("id");
if(targetLi.children('ul').size() >0){
if (typeof id !== 'undefined' && id !== false) {
targetLi.children('ul').append('<li id="'+id+'">'+sourceliClone.html()+'</li>');
}else{
targetLi.children('ul').append('<li>'+sourceliClone.html()+'</li>');
}
}else{
if (typeof id !== 'undefined' && id !== false) {
targetLi.append('<ul><li id="'+id+'">'+sourceliClone.html()+'</li></ul>');
}else{
targetLi.append('<ul><li>'+sourceliClone.html()+'</li></ul>');
}
}
}); // handleDropEvent
} // Drag and drop
};
// Option defaults
$.fn.jOrgChart.defaults = {
chartElement : 'body',
depth : -1,
chartClass : "jOrgChart",
dragAndDrop: false
};
// Method that recursively builds the tree
function buildNode($node, $appendTo, level, opts) {
var $table = $("<table cellpadding='0' cellspacing='0' border='0'/>");
var $tbody = $("<tbody/>");
// Construct the node container(s)
var $nodeRow = $("<tr/>").addClass("node-cells");
var $nodeCell = $("<td/>").addClass("node-cell").attr("colspan", 2);
var $childNodes = $node.children("ul:first").children("li");
var $nodeDiv;
if($childNodes.length > 1) {
$nodeCell.attr("colspan", $childNodes.length * 2);
}
// Draw the node
// Get the contents - any markup except li and ul allowed
var $nodeContent = $node.clone()
.children("ul,li")
.remove()
.end()
.html();
var new_node_id = $node.attr("id")
if (typeof new_node_id !== 'undefined' && new_node_id !== false) {
$nodeDiv = $("<div>").addClass("node").attr("id", $node.attr("id")).append($nodeContent);
}else{ }else{
$nodeDiv = $("<div>").addClass("node").append($nodeContent); sourceUl.remove();
} }
// Expand and contract nodes var id = sourceLi.attr("id");
if ($childNodes.length > 0) {
$nodeDiv.click(function() {
var $this = $(this);
var $tr = $this.closest("tr");
$tr.nextAll("tr").fadeToggle("fast");
if($tr.hasClass('contracted')){
$this.css('cursor','n-resize');
$tr.removeClass('contracted');
$tr.addClass('expanded');
}else{
$this.css('cursor','s-resize');
$tr.removeClass('expanded');
$tr.addClass('contracted');
}
});
}
$nodeCell.append($nodeDiv);
$nodeRow.append($nodeCell);
$tbody.append($nodeRow);
if($childNodes.length > 0) {
// if it can be expanded then change the cursor
$nodeDiv.css('cursor','n-resize').addClass('expanded');
// recurse until leaves found (-1) or to the level specified
if(opts.depth == -1 || (level+1 < opts.depth)) {
var $downLineRow = $("<tr/>");
var $downLineCell = $("<td/>").attr("colspan", $childNodes.length*2);
$downLineRow.append($downLineCell);
// draw the connecting line from the parent node to the horizontal line
$downLine = $("<div></div>").addClass("line down");
$downLineCell.append($downLine);
$tbody.append($downLineRow);
// Draw the horizontal lines
var $linesRow = $("<tr/>");
$childNodes.each(function() {
var $left = $("<td>&nbsp;</td>").addClass("line left top");
var $right = $("<td>&nbsp;</td>").addClass("line right top");
$linesRow.append($left).append($right);
});
// horizontal line shouldn't extend beyond the first and last child branches
$linesRow.find("td:first")
.removeClass("top")
.end()
.find("td:last")
.removeClass("top");
$tbody.append($linesRow);
var $childNodesRow = $("<tr/>");
$childNodes.each(function() {
var $td = $("<td class='node-container'/>");
$td.attr("colspan", 2);
// recurse through children lists and items
buildNode($(this), $td, level+1, opts);
$childNodesRow.append($td);
});
if(targetLi.children('ul').size() >0){
if (typeof id !== 'undefined' && id !== false) {
targetLi.children('ul').append('<li id="'+id+'">'+sourceliClone.html()+'</li>');
}else{
targetLi.children('ul').append('<li>'+sourceliClone.html()+'</li>');
}
}else{
if (typeof id !== 'undefined' && id !== false) {
targetLi.append('<ul><li id="'+id+'">'+sourceliClone.html()+'</li></ul>');
}else{
targetLi.append('<ul><li>'+sourceliClone.html()+'</li></ul>');
} }
$tbody.append($childNodesRow);
} }
// any classes on the LI element get copied to the relevant node in the tree }); // handleDropEvent
// apart from the special 'collapsed' class, which collapses the sub-tree at this point
if ($node.attr('class') != undefined) { } // Drag and drop
var classList = $node.attr('class').split(/\s+/); };
$.each(classList, function(index,item) {
if (item == 'collapsed') { // Option defaults
$nodeRow.nextAll('tr').css('display', 'none'); $.fn.jOrgChart.defaults = {
chartElement : 'body',
depth : -1,
chartClass : "jOrgChart",
dragAndDrop: false
};
// Method that recursively builds the tree
function buildNode($node, $appendTo, level, opts) {
var $table = $("<table cellpadding='0' cellspacing='0' border='0'/>");
var $tbody = $("<tbody/>");
// Construct the node container(s)
var $nodeRow = $("<tr/>").addClass("node-cells");
var $nodeCell = $("<td/>").addClass("node-cell").attr("colspan", 2);
var $childNodes = $node.children("ul:first").children("li");
var $nodeDiv;
if($childNodes.length > 1) {
$nodeCell.attr("colspan", $childNodes.length * 2);
}
// Draw the node
// Get the contents - any markup except li and ul allowed
var $nodeContent = $node.clone()
.children("ul,li")
.remove()
.end()
.html();
var new_node_id = $node.attr("id")
if (typeof new_node_id !== 'undefined' && new_node_id !== false) {
$nodeDiv = $("<div>").addClass("node").attr("id", $node.attr("id")).append($nodeContent);
}else{
$nodeDiv = $("<div>").addClass("node").append($nodeContent);
}
// Expand and contract nodes
if ($childNodes.length > 0) {
$nodeDiv.click(function() {
var $this = $(this);
var $tr = $this.closest("tr");
if($tr.hasClass('contracted')){
$this.css('cursor','n-resize');
$tr.removeClass('contracted').addClass('expanded');
$tr.nextAll("tr").css('visibility', '');
}else{
$this.css('cursor','s-resize');
$tr.removeClass('expanded').addClass('contracted');
$tr.nextAll("tr").css('visibility', 'hidden');
}
});
}
$nodeCell.append($nodeDiv);
$nodeRow.append($nodeCell);
$tbody.append($nodeRow);
if($childNodes.length > 0) {
// if it can be expanded then change the cursor
$nodeDiv.css('cursor','n-resize').addClass('expanded');
// recurse until leaves found (-1) or to the level specified
if(opts.depth == -1 || (level+1 < opts.depth)) {
var $downLineRow = $("<tr/>");
var $downLineCell = $("<td/>").attr("colspan", $childNodes.length*2);
$downLineRow.append($downLineCell);
// draw the connecting line from the parent node to the horizontal line
$downLine = $("<div></div>").addClass("line down");
$downLineCell.append($downLine);
$tbody.append($downLineRow);
// Draw the horizontal lines
var $linesRow = $("<tr/>");
$childNodes.each(function() {
var $left = $("<td>&nbsp;</td>").addClass("line left top");
var $right = $("<td>&nbsp;</td>").addClass("line right top");
$linesRow.append($left).append($right);
});
// horizontal line shouldn't extend beyond the first and last child branches
$linesRow.find("td:first")
.removeClass("top")
.end()
.find("td:last")
.removeClass("top");
$tbody.append($linesRow);
var $childNodesRow = $("<tr/>");
$childNodes.each(function() {
var $td = $("<td class='node-container'/>");
$td.attr("colspan", 2);
// recurse through children lists and items
buildNode($(this), $td, level+1, opts);
$childNodesRow.append($td);
});
}
$tbody.append($childNodesRow);
}
// any classes on the LI element get copied to the relevant node in the tree
// apart from the special 'collapsed' class, which collapses the sub-tree at this point
if ($node.attr('class') != undefined) {
var classList = $node.attr('class').split(/\s+/);
$.each(classList, function(index,item) {
if (item == 'collapsed') {
$nodeRow.nextAll('tr').css('display', 'none');
$nodeRow.removeClass('expanded'); $nodeRow.removeClass('expanded');
$nodeRow.addClass('contracted'); $nodeRow.addClass('contracted');
$nodeDiv.css('cursor','s-resize'); $nodeDiv.css('cursor','s-resize');
} else { } else {
$nodeDiv.addClass(item); $nodeDiv.addClass(item);
} }
}); });
} }
$table.append($tbody); $table.append($tbody);
$appendTo.append($table); $appendTo.append($table);
}; };
})(jQuery); })(jQuery);

View File

@ -1,87 +1,85 @@
/** /**
* jQuery org-chart/tree plugin. * jQuery org-chart/tree plugin.
* *
* Author: Wes Nolte * Author: Wes Nolte
* http://twitter.com/wesnolte * http://twitter.com/wesnolte
* *
* Based on the work of Mark Lee * Based on the work of Mark Lee
* http://www.capricasoftware.co.uk * http://www.capricasoftware.co.uk
* *
* ID implementation fixed by Adrian Hinz * This software is licensed under the Creative Commons Attribution-ShareAlike
* * 3.0 License.
* This software is licensed under the Creative Commons Attribution-ShareAlike *
* 3.0 License. * See here for license terms:
* * http://creativecommons.org/licenses/by-sa/3.0
* See here for license terms: */
* http://creativecommons.org/licenses/by-sa/3.0
*/
(function($) { (function($) {
$.fn.jOrgChart = function(options) { $.fn.jOrgChart = function(options) {
var opts = $.extend({}, $.fn.jOrgChart.defaults, options); var opts = $.extend({}, $.fn.jOrgChart.defaults, options);
var $appendTo = $(opts.chartElement); var $appendTo = $(opts.chartElement);
// build the tree // build the tree
$this = $(this); $this = $(this);
var $container = $("<div class='" + opts.chartClass + "'/>"); var $container = $("<div class='" + opts.chartClass + "'/>");
if($this.is("ul")) { if($this.is("ul")) {
buildNode($this.find("li:first"), $container, 0, opts); buildNode($this.find("li:first"), $container, 0, opts);
} }
else if($this.is("li")) { else if($this.is("li")) {
buildNode($this, $container, 0, opts); buildNode($this, $container, 0, opts);
} }
$appendTo.append($container); $appendTo.append($container);
// add drag and drop if enabled // add drag and drop if enabled
if(opts.dragAndDrop){ if(opts.dragAndDrop){
$('div.node').draggable({ $('div.node').draggable({
cursor : 'move', cursor : 'move',
distance : 40, distance : 40,
helper : 'clone', helper : 'clone',
opacity : 0.8, opacity : 0.8,
revert : true, revert : true,
revertDuration : 100, revertDuration : 100,
snap : 'div.node.expanded', snap : 'div.node.expanded',
snapMode : 'inner', snapMode : 'inner',
stack : 'div.node' stack : 'div.node'
}); });
$('div.node').droppable({ $('div.node').droppable({
accept : '.node', accept : '.node',
activeClass : 'drag-active', activeClass : 'drag-active',
hoverClass : 'drop-hover' hoverClass : 'drop-hover'
}); });
// Drag start event handler for nodes // Drag start event handler for nodes
$('div.node').bind("dragstart", function handleDragStart( event, ui ){ $('div.node').bind("dragstart", function handleDragStart( event, ui ){
var sourceNode = $(this); var sourceNode = $(this);
sourceNode.parentsUntil('.node-container') sourceNode.parentsUntil('.node-container')
.find('*') .find('*')
.filter('.node') .filter('.node')
.droppable('disable'); .droppable('disable');
}); });
// Drag stop event handler for nodes // Drag stop event handler for nodes
$('div.node').bind("dragstop", function handleDragStop( event, ui ){ $('div.node').bind("dragstop", function handleDragStop( event, ui ){
/* reload the plugin */ /* reload the plugin */
$(opts.chartElement).children().remove(); $(opts.chartElement).children().remove();
$this.jOrgChart(opts); $this.jOrgChart(opts);
}); });
// Drop event handler for nodes // Drop event handler for nodes
$('div.node').bind("drop", function handleDropEvent( event, ui ) { $('div.node').bind("drop", function handleDropEvent( event, ui ) {
var sourceNode = ui.draggable; var sourceNode = ui.draggable;
var targetNode = $(this); var targetNode = $(this);
// finding nodes based on plaintext and html // finding nodes based on plaintext and html
// content is hard! // content is hard!
var targetLi = $('li').filter(function(){ var targetLi = $('li').filter(function(){
li = $(this).clone() li = $(this).clone()
.children("ul,li") .children("ul,li")
.remove() .remove()
.end(); .end();
var attr = li.attr('id'); var attr = li.attr('id');
if (typeof attr !== 'undefined' && attr !== false) { if (typeof attr !== 'undefined' && attr !== false) {
@ -91,13 +89,13 @@
return li.html() == targetNode.html(); return li.html() == targetNode.html();
} }
}); });
var sourceLi = $('li').filter(function(){ var sourceLi = $('li').filter(function(){
li = $(this).clone() li = $(this).clone()
.children("ul,li") .children("ul,li")
.remove() .remove()
.end(); .end();
var attr = li.attr('id'); var attr = li.attr('id');
if (typeof attr !== 'undefined' && attr !== false) { if (typeof attr !== 'undefined' && attr !== false) {
@ -107,161 +105,160 @@
return li.html() == sourceNode.html(); return li.html() == sourceNode.html();
} }
}); });
var sourceliClone = sourceLi.clone(); var sourceliClone = sourceLi.clone();
var sourceUl = sourceLi.parent('ul'); var sourceUl = sourceLi.parent('ul');
if(sourceUl.children('li').size() > 1){ if(sourceUl.children('li').size() > 1){
sourceLi.remove(); sourceLi.remove();
}else{
sourceUl.remove();
}
var id = sourceLi.attr("id");
if(targetLi.children('ul').size() >0){
if (typeof id !== 'undefined' && id !== false) {
targetLi.children('ul').append('<li id="'+id+'">'+sourceliClone.html()+'</li>');
}else{
targetLi.children('ul').append('<li>'+sourceliClone.html()+'</li>');
}
}else{
if (typeof id !== 'undefined' && id !== false) {
targetLi.append('<ul><li id="'+id+'">'+sourceliClone.html()+'</li></ul>');
}else{
targetLi.append('<ul><li>'+sourceliClone.html()+'</li></ul>');
}
}
}); // handleDropEvent
} // Drag and drop
};
// Option defaults
$.fn.jOrgChart.defaults = {
chartElement : 'body',
depth : -1,
chartClass : "jOrgChart",
dragAndDrop: false
};
// Method that recursively builds the tree
function buildNode($node, $appendTo, level, opts) {
var $table = $("<table cellpadding='0' cellspacing='0' border='0'/>");
var $tbody = $("<tbody/>");
// Construct the node container(s)
var $nodeRow = $("<tr/>").addClass("node-cells");
var $nodeCell = $("<td/>").addClass("node-cell").attr("colspan", 2);
var $childNodes = $node.children("ul:first").children("li");
var $nodeDiv;
if($childNodes.length > 1) {
$nodeCell.attr("colspan", $childNodes.length * 2);
}
// Draw the node
// Get the contents - any markup except li and ul allowed
var $nodeContent = $node.clone()
.children("ul,li")
.remove()
.end()
.html();
var new_node_id = $node.attr("id")
if (typeof new_node_id !== 'undefined' && new_node_id !== false) {
$nodeDiv = $("<div>").addClass("node").attr("id", $node.attr("id")).append($nodeContent);
}else{ }else{
$nodeDiv = $("<div>").addClass("node").append($nodeContent); sourceUl.remove();
} }
// Expand and contract nodes var id = sourceLi.attr("id");
if ($childNodes.length > 0) {
$nodeDiv.click(function() {
var $this = $(this);
var $tr = $this.closest("tr");
$tr.nextAll("tr").fadeToggle("fast");
if($tr.hasClass('contracted')){
$this.css('cursor','n-resize');
$tr.removeClass('contracted');
$tr.addClass('expanded');
}else{
$this.css('cursor','s-resize');
$tr.removeClass('expanded');
$tr.addClass('contracted');
}
});
}
$nodeCell.append($nodeDiv);
$nodeRow.append($nodeCell);
$tbody.append($nodeRow);
if($childNodes.length > 0) {
// if it can be expanded then change the cursor
$nodeDiv.css('cursor','n-resize').addClass('expanded');
// recurse until leaves found (-1) or to the level specified
if(opts.depth == -1 || (level+1 < opts.depth)) {
var $downLineRow = $("<tr/>");
var $downLineCell = $("<td/>").attr("colspan", $childNodes.length*2);
$downLineRow.append($downLineCell);
// draw the connecting line from the parent node to the horizontal line
$downLine = $("<div></div>").addClass("line down");
$downLineCell.append($downLine);
$tbody.append($downLineRow);
// Draw the horizontal lines
var $linesRow = $("<tr/>");
$childNodes.each(function() {
var $left = $("<td>&nbsp;</td>").addClass("line left top");
var $right = $("<td>&nbsp;</td>").addClass("line right top");
$linesRow.append($left).append($right);
});
// horizontal line shouldn't extend beyond the first and last child branches
$linesRow.find("td:first")
.removeClass("top")
.end()
.find("td:last")
.removeClass("top");
$tbody.append($linesRow);
var $childNodesRow = $("<tr/>");
$childNodes.each(function() {
var $td = $("<td class='node-container'/>");
$td.attr("colspan", 2);
// recurse through children lists and items
buildNode($(this), $td, level+1, opts);
$childNodesRow.append($td);
});
if(targetLi.children('ul').size() >0){
if (typeof id !== 'undefined' && id !== false) {
targetLi.children('ul').append('<li id="'+id+'">'+sourceliClone.html()+'</li>');
}else{
targetLi.children('ul').append('<li>'+sourceliClone.html()+'</li>');
}
}else{
if (typeof id !== 'undefined' && id !== false) {
targetLi.append('<ul><li id="'+id+'">'+sourceliClone.html()+'</li></ul>');
}else{
targetLi.append('<ul><li>'+sourceliClone.html()+'</li></ul>');
} }
$tbody.append($childNodesRow);
} }
// any classes on the LI element get copied to the relevant node in the tree }); // handleDropEvent
// apart from the special 'collapsed' class, which collapses the sub-tree at this point
if ($node.attr('class') != undefined) { } // Drag and drop
var classList = $node.attr('class').split(/\s+/); };
$.each(classList, function(index,item) {
if (item == 'collapsed') { // Option defaults
$nodeRow.nextAll('tr').css('display', 'none'); $.fn.jOrgChart.defaults = {
chartElement : 'body',
depth : -1,
chartClass : "jOrgChart",
dragAndDrop: false
};
// Method that recursively builds the tree
function buildNode($node, $appendTo, level, opts) {
var $table = $("<table cellpadding='0' cellspacing='0' border='0'/>");
var $tbody = $("<tbody/>");
// Construct the node container(s)
var $nodeRow = $("<tr/>").addClass("node-cells");
var $nodeCell = $("<td/>").addClass("node-cell").attr("colspan", 2);
var $childNodes = $node.children("ul:first").children("li");
var $nodeDiv;
if($childNodes.length > 1) {
$nodeCell.attr("colspan", $childNodes.length * 2);
}
// Draw the node
// Get the contents - any markup except li and ul allowed
var $nodeContent = $node.clone()
.children("ul,li")
.remove()
.end()
.html();
var new_node_id = $node.attr("id")
if (typeof new_node_id !== 'undefined' && new_node_id !== false) {
$nodeDiv = $("<div>").addClass("node").attr("id", $node.attr("id")).append($nodeContent);
}else{
$nodeDiv = $("<div>").addClass("node").append($nodeContent);
}
// Expand and contract nodes
if ($childNodes.length > 0) {
$nodeDiv.click(function() {
var $this = $(this);
var $tr = $this.closest("tr");
if($tr.hasClass('contracted')){
$this.css('cursor','n-resize');
$tr.removeClass('contracted').addClass('expanded');
$tr.nextAll("tr").css('visibility', '');
}else{
$this.css('cursor','s-resize');
$tr.removeClass('expanded').addClass('contracted');
$tr.nextAll("tr").css('visibility', 'hidden');
}
});
}
$nodeCell.append($nodeDiv);
$nodeRow.append($nodeCell);
$tbody.append($nodeRow);
if($childNodes.length > 0) {
// if it can be expanded then change the cursor
$nodeDiv.css('cursor','n-resize').addClass('expanded');
// recurse until leaves found (-1) or to the level specified
if(opts.depth == -1 || (level+1 < opts.depth)) {
var $downLineRow = $("<tr/>");
var $downLineCell = $("<td/>").attr("colspan", $childNodes.length*2);
$downLineRow.append($downLineCell);
// draw the connecting line from the parent node to the horizontal line
$downLine = $("<div></div>").addClass("line down");
$downLineCell.append($downLine);
$tbody.append($downLineRow);
// Draw the horizontal lines
var $linesRow = $("<tr/>");
$childNodes.each(function() {
var $left = $("<td>&nbsp;</td>").addClass("line left top");
var $right = $("<td>&nbsp;</td>").addClass("line right top");
$linesRow.append($left).append($right);
});
// horizontal line shouldn't extend beyond the first and last child branches
$linesRow.find("td:first")
.removeClass("top")
.end()
.find("td:last")
.removeClass("top");
$tbody.append($linesRow);
var $childNodesRow = $("<tr/>");
$childNodes.each(function() {
var $td = $("<td class='node-container'/>");
$td.attr("colspan", 2);
// recurse through children lists and items
buildNode($(this), $td, level+1, opts);
$childNodesRow.append($td);
});
}
$tbody.append($childNodesRow);
}
// any classes on the LI element get copied to the relevant node in the tree
// apart from the special 'collapsed' class, which collapses the sub-tree at this point
if ($node.attr('class') != undefined) {
var classList = $node.attr('class').split(/\s+/);
$.each(classList, function(index,item) {
if (item == 'collapsed') {
$nodeRow.nextAll('tr').css('display', 'none');
$nodeRow.removeClass('expanded'); $nodeRow.removeClass('expanded');
$nodeRow.addClass('contracted'); $nodeRow.addClass('contracted');
$nodeDiv.css('cursor','s-resize'); $nodeDiv.css('cursor','s-resize');
} else { } else {
$nodeDiv.addClass(item); $nodeDiv.addClass(item);
} }
}); });
} }
$table.append($tbody); $table.append($tbody);
$appendTo.append($table); $appendTo.append($table);
}; };
})(jQuery); })(jQuery);

View File

@ -16,7 +16,7 @@ Features include:
* Easy to style. * Easy to style.
* You can specify that sub-trees should start collapsed, which is useful for very large trees * You can specify that sub-trees should start collapsed, which is useful for very large trees
![jQuery OrgChart](http://i.imgur.com/2OpyG.png "jQuery OrgChart") ![jQuery OrgChart](http://i.imgur.com/T8kKA.png "jQuery OrgChart")
---- ----