source: trunk/LATMOS-Accounts-Web/root/static/js/jquery/jquery.orgchart.js @ 1939

Last change on this file since 1939 was 1939, checked in by nanardon, 7 years ago

A real chart for poeple

File size: 8.5 KB
Line 
1/**
2 * JQuery Organisation Chart Plugin.
3 *
4 * Author: Mark Lee
5 * Copyright (C)2013-2015 Caprica Software Limited
6 * http://www.capricasoftware.co.uk
7 *
8 * Contributions by: Paul Lautman <paul.lautman at gmail.com>
9 *
10 * This software is licensed under the Creative Commons Attribution-ShareAlike 3.0 License,
11 * see here for license terms:
12 *
13 *     http://creativecommons.org/licenses/by-sa/3.0
14 */
15(function($) {
16
17    $.fn.orgChart = function(options) {
18        var opts = $.extend({}, $.fn.orgChart.defaults, options);
19
20        return this.each(function() {
21            var $chartSource = $(this);
22            // Clone the source list hierarchy so levels can be non-destructively removed if needed
23            // before creating the chart
24            $this = $chartSource.clone();
25            if (opts.levels > -1) {
26                $this.find("ul").andSelf().filter(function() {return $chartSource.parents("ul").length+1 > opts.levels;}).remove();
27            }
28            // Store the original element
29            $this.data("chart-source", $chartSource);
30            // Build the chart...
31            var $container = $("<div class='" + opts.chartClass + "'/>");
32            if (opts.interactive) {
33                $container.addClass("interactive");
34            }
35            // The chart may be sourced from either a "ul", or an "li" element...
36            var $root;
37            if ($this.is("ul")) {
38                $root = $this.find("li:first");
39            }
40            else if ($this.is("li")) {
41                $root = $this;
42            }
43            if ($root) {
44                buildNode($root, $container, 0, 0, opts);
45                // Special case for any hyperlink anchor in the chart to prevent the click on the node itself from propagating
46                $container.find("div.node a").click(function(evt) {
47                    evt.stopImmediatePropagation();
48                });
49                if(opts.replace) {
50                    opts.container.empty();
51                }
52                opts.container.append($container);
53            }
54        });
55    };
56
57    $.fn.orgChart.defaults = {
58        container  : $("body"),
59        depth      : -1,
60        levels     : -1,
61        showLevels : -1,
62        stack      : false,
63        chartClass : "orgChart",
64        hoverClass : "hover",
65        nodeText   : function($node) {return $node.clone().children("ul,li").remove().end().html();},
66        interactive: false,
67        fade       : false,
68        speed      : "slow",
69        nodeClicked: function($node) {},
70        copyClasses: true,
71        copyData   : true,
72        copyStyles : true,
73        copyTitle  : true,
74        replace    : true
75    };
76
77    function buildNode($node, $appendTo, level, index, opts) {
78        var $table = $("<table cellpadding='0' cellspacing='0' border='0'/>");
79        var $tbody = $("<tbody/>");
80
81        // Make this node...
82        var $nodeRow = $("<tr/>").addClass("nodes");
83        var $nodeCell = $("<td/>").addClass("node").attr("colspan", 2);
84        var $childNodes = $node.children("ul:first").children("li");
85        if ($childNodes.length > 1) {
86            $nodeCell.attr("colspan", $childNodes.length*2);
87        }
88
89        var $adjunct = $node.children("adjunct").eq(0);
90        if ($adjunct.length > 0) {
91            var $adjunctDiv = $("<div>").addClass("adjunct node").addClass("level"+level).addClass("node"+index).addClass("level"+level+"-node"+index).append(opts.nodeText($adjunct));
92            $adjunctDiv.appendTo($nodeCell);
93            var $linkDiv = $("<div>").addClass("adjunct-link");
94            $linkDiv.appendTo($nodeCell);
95            $adjunct.remove();
96        }
97
98        var $heading = $("<h2>").html(opts.nodeText($node));
99        var $nodeDiv = $("<div>").addClass("node").addClass("level"+level).addClass("node"+index).addClass("level"+level+"-node"+index).append($heading);
100
101        // Copy classes from the source list to the chart node
102        if (opts.copyClasses) {
103            $nodeDiv.addClass($node.attr("class"));
104        }
105
106        // Copy data from the source list to the chart node
107        if (opts.copyData) {
108            $nodeDiv.data($node.data());
109        }
110
111        // Copy CSS styles from the source list to the chart node
112        if (opts.copyStyles) {
113            $nodeDiv.attr("style", $node.attr("style"));
114        }
115
116        // Copy the title attribute from the source list to the chart node
117        if (opts.copyTitle) {
118            $nodeDiv.attr("title", $node.attr("title"));
119        }
120
121        $nodeDiv.data("orgchart-level", level).data("orgchart-node", $node);
122
123        $nodeCell.append($nodeDiv);
124        $nodeRow.append($nodeCell);
125        $tbody.append($nodeRow);
126
127        $nodeDiv.click(function() {
128            var $this = $(this);
129            opts.nodeClicked($this.data("orgchart-node"), $this);
130            if (opts.interactive) {
131                var $row = $this.closest("tr");
132                if ($row.next("tr").is(":visible")) {
133                    if (opts.fade) {
134                        $row.nextAll("tr").fadeOut(opts.speed);
135                    }
136                    else {
137                        $row.nextAll("tr").hide();
138                    }
139                    $this.removeClass("shownChildren").addClass("hiddenChildren");
140                }
141                else {
142                    $this.removeClass("hiddenChildren").addClass("shownChildren");
143                    if (opts.fade) {
144                        $row.nextAll("tr").fadeIn(opts.speed);
145                    }
146                    else {
147                        $row.nextAll("tr").show();
148                    }
149                }
150            }
151        });
152
153        if ($childNodes.length > 0) {
154            if (opts.depth == -1 || level+1 < opts.depth) {
155                var $downLineRow = $("<tr/>").addClass("lines");
156                var $downLineCell = $("<td/>").attr("colspan", $childNodes.length*2);
157                $downLineRow.append($downLineCell);
158
159                var $downLineTable = $("<table cellpadding='0' cellspacing='0' border='0'>");
160                $downLineTable.append("<tbody>");
161                var $downLineLine = $("<tr/>").addClass("lines x");
162                var $downLeft = $("<td>").addClass("line left");
163                var $downRight = $("<td>").addClass("line right");
164                $downLineLine.append($downLeft).append($downRight);
165                $downLineTable.children("tbody").append($downLineLine);
166                $downLineCell.append($downLineTable);
167
168                $tbody.append($downLineRow);
169
170                if ($childNodes.length > 0) {
171                    $nodeDiv.addClass("hasChildren");
172                    if (opts.showLevels == -1 || level < opts.showLevels-1) {
173                        $nodeDiv.addClass("shownChildren");
174                    }
175                    else {
176                        $nodeDiv.addClass("hiddenChildren");
177                    }
178                    if (opts.interactive) {
179                        $nodeDiv.hover(function() {$(this).addClass(opts.hoverClass);}, function() {$(this).removeClass(opts.hoverClass)});
180                    }
181                }
182
183                // Recursively make child nodes...
184                var $linesRow = $("<tr/>").addClass("lines v");
185                $childNodes.each(function() {
186                    var $left = $("<td/>").addClass("line left top");
187                    var $right = $("<td/>").addClass("line right top");
188                    $linesRow.append($left).append($right);
189                });
190                $linesRow.find("td:first").removeClass("top");
191                $linesRow.find("td:last").removeClass("top");
192                $tbody.append($linesRow);
193                var $childNodesRow = $("<tr/>");
194                $childNodes.each(function(index) {
195                    var $td = $("<td/>");
196                    $td.attr("colspan", 2);
197                    buildNode($(this), $td, level+1, index, opts);
198                    $childNodesRow.append($td);
199                });
200                $tbody.append($childNodesRow);
201            }
202            else if (opts.stack) {
203                var $stackNodes = $childNodes.clone();
204                var $list = $("<ul class='stack'>").append($stackNodes).addClass("level"+level).addClass("node"+index).addClass("level"+level+"-node"+index);
205                var $stackContainer = $("<div class='stack-container'>").append($list);
206                $nodeDiv.after($stackContainer);
207            }
208        }
209
210        if (opts.showLevels > -1 && level >= opts.showLevels-1) {
211            $nodeRow.nextAll("tr").hide();
212        }
213
214        $table.append($tbody);
215        $appendTo.append($table);
216    };
217
218})(jQuery);
Note: See TracBrowser for help on using the repository browser.