diff --git a/equal-nodes-span b/equal-nodes-span
new file mode 100644
index 0000000..1a6df44
--- /dev/null
+++ b/equal-nodes-span
@@ -0,0 +1,220 @@
+(function($) {
+
+ $.fn.jOrgChart = function(options) {
+ var opts = $.extend({}, $.fn.jOrgChart.defaults, options);
+ var $appendTo = $(opts.chartElement);
+
+ $this = $(this);
+ var $container = $("
");
+ 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("");
+ 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 = $("");
+ var $tbody = $("");
+
+ // Construct the node container(s)
+ var $nodeRow = $("
").addClass("node-cells");
+ var $nodeCell = $(" | ").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 = $("").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
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 = $("
");
+ var $downLineCell = $(" | ").attr("colspan", $childNodes.length*2);
+ $downLineRow.append($downLineCell);
+
+ // draw the connecting line from the parent node to the horizontal line
+ $downLine = $("").addClass("line down");
+ $downLineCell.append($downLine);
+ $tbody.append($downLineRow);
+
+ // Draw the horizontal lines
+ var $linesRow = $("
");
+ $childNodes.each(function() {
+ var $left = $(" | ").addClass("line left top");
+ var $right = $(" | ").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 = $("
");
+ $childNodes.each(function() {
+ var $td = $(" | ");
+ $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);