Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create equal-nodes-span #68

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 220 additions & 0 deletions equal-nodes-span
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
(function($) {

$.fn.jOrgChart = function(options) {
var opts = $.extend({}, $.fn.jOrgChart.defaults, options);
var $appendTo = $(opts.chartElement);

$this = $(this);
var $container = $("<div class='" + opts.chartClass + "'/>");
if($this.is("ul")) {
buildNode($this.find("li:first"), $container, 0, opts);
}
else if($this.is("li")) {
buildNode($this, $container, 0, opts);
}
$appendTo.append($container);

// add drag and drop if enabled
if(opts.dragAndDrop){
$('div.node').draggable({
cursor : 'move',
distance : 40,
helper : 'clone',
opacity : 0.8,
revert : 'invalid',
revertDuration : 100,
snap : 'div.node.expanded',
snapMode : 'inner',
stack : 'div.node'
});

$('div.node').droppable({
accept : '.node',
activeClass : 'drag-active',
hoverClass : 'drop-hover'
});

// Drag start event handler for nodes
$('div.node').bind("dragstart", function handleDragStart( event, ui ){

var sourceNode = $(this);
sourceNode.parentsUntil('.node-container')
.find('*')
.filter('.node')
.droppable('disable');
});

// Drag stop event handler for nodes
$('div.node').bind("dragstop", function handleDragStop( event, ui ){

/* reload the plugin */
$(opts.chartElement).children().remove();
$this.jOrgChart(opts);
});

// Drop event handler for nodes
$('div.node').bind("drop", function handleDropEvent( event, ui ) {

var targetID = $(this).data("tree-node");
var targetLi = $this.find("li").filter(function() { return $(this).data("tree-node") === targetID; } );
var targetUl = targetLi.children('ul');

var sourceID = ui.draggable.data("tree-node");
var sourceLi = $this.find("li").filter(function() { return $(this).data("tree-node") === sourceID; } );
var sourceUl = sourceLi.parent('ul');

if (targetUl.length > 0){
targetUl.append(sourceLi);
} else {
targetLi.append("<ul></ul>");
targetLi.children('ul').append(sourceLi);
}

//Removes any empty lists
if (sourceUl.children().length === 0){
sourceUl.remove();
}

}); // handleDropEvent

} // Drag and drop
};

// Option defaults
$.fn.jOrgChart.defaults = {
chartElement : 'body',
depth : -1,
chartClass : "jOrgChart",
dragAndDrop: false
};

var nodeCount = 0;
// 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();

//Increaments the node count which is used to link the source list and the org chart
nodeCount++;
$node.data("tree-node", nodeCount);
$nodeDiv = $("<div>").addClass("node")
.data("tree-node", nodeCount)
.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('display', '');

// Update the <li> appropriately so that if the tree redraws collapsed/non-collapsed nodes
// maintain their appearance
$node.removeClass('collapsed');
}else{
$this.css('cursor','s-resize');
$tr.removeClass('expanded').addClass('contracted');
$tr.nextAll("tr").css('display', 'none');

$node.addClass('collapsed');
}
});
}

$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');

// 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') {
console.log($node);
$nodeRow.nextAll('tr').css('display', 'none');
$nodeRow.removeClass('expanded');
$nodeRow.addClass('contracted');
$nodeDiv.css('cursor','s-resize');
} else {
$nodeDiv.addClass(item);
}
});
}

$table.append($tbody);
$appendTo.append($table);

/* Prevent trees collapsing if a link inside a node is clicked */
$nodeDiv.children('a').click(function(e){
console.log(e);
e.stopPropagation();
});
};

})(jQuery);