treeTable.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. var com_github_culmat_jsTreeTable = (function(){
  2. function depthFirst(tree, func, childrenAttr) {
  3. childrenAttr = childrenAttr || 'children'
  4. function i_depthFirst(node) {
  5. if (node[childrenAttr]) {
  6. $.each(node[childrenAttr], function(i, child) {
  7. i_depthFirst(child)
  8. })
  9. }
  10. func(node)
  11. }
  12. $.each(tree, function(i, root) {
  13. i_depthFirst(root)
  14. })
  15. return tree
  16. }
  17. /*
  18. * make a deep copy of the object
  19. */
  20. function copy(data){
  21. return JSON.parse(JSON.stringify(data))
  22. }
  23. function makeTree (data, idAttr, refAttr, childrenAttr) {
  24. var data_tmp = data
  25. idAttr = idAttr || 'id'
  26. refAttr = refAttr || 'parent'
  27. childrenAttr = childrenAttr || 'children'
  28. var byName = []
  29. $.each(data_tmp, function(i, entry) {
  30. byName[entry[idAttr]] = entry
  31. })
  32. var tree = []
  33. $.each(data_tmp, function(i, entry) {
  34. var parents = entry[refAttr]
  35. if(!$.isArray(parents)){
  36. parents = [parents]
  37. }
  38. if(parents.length == 0){
  39. tree.push(entry)
  40. } else {
  41. var inTree = false;
  42. $.each(parents, function(i,parentID){
  43. var parent = byName[parentID]
  44. if (parent) {
  45. if (!parent[childrenAttr]) {
  46. parent[childrenAttr] = []
  47. }
  48. if($.inArray(entry, parent[childrenAttr])< 0)
  49. parent[childrenAttr].push(entry)
  50. inTree = true
  51. }
  52. })
  53. if(!inTree){
  54. tree.push(entry)
  55. }
  56. }
  57. })
  58. return tree
  59. }
  60. function renderTree(tree, childrenAttr, idAttr, attrs, renderer, tableAttributes) {
  61. childrenAttr = childrenAttr || 'children'
  62. idAttr = idAttr || 'id'
  63. tableAttributes = tableAttributes || {}
  64. var maxLevel = 0;
  65. var ret = []
  66. var table = $("<table>")
  67. $.each(tableAttributes, function(key, value){
  68. if(key == 'class' && value != 'jsTT') {
  69. table.addClass(value)
  70. } else {
  71. table.attr(key, value)
  72. }
  73. })
  74. var thead = $("<thead>")
  75. var tr = $("<tr>")
  76. var tbody = $("<tbody>")
  77. table.append(thead)
  78. thead.append(tr)
  79. table.append(tbody)
  80. if (attrs) {
  81. $.each(attrs, function(attr, desc) {
  82. $(tr).append($('<th>' + desc + '</th>'))
  83. })
  84. } else {
  85. $(tr).append($('<th>' + idAttr + '</th>'))
  86. $.each(tree[0], function(key, value) {
  87. if (key != childrenAttr && key != idAttr)
  88. $(tr).append($('<th>' + key + '</th>'))
  89. })
  90. }
  91. function render(node, parent) {
  92. var tr = $("<tr>")
  93. $(tr).attr('data-tt-id', node[idAttr])
  94. $(tr).attr('data-tt-level', node['data-tt-level'])
  95. if(!node[childrenAttr] || node[childrenAttr].length == 0)
  96. $(tr).attr('data-tt-isleaf', true)
  97. else
  98. $(tr).attr('data-tt-isnode', true)
  99. if (parent) {
  100. $(tr).attr('data-tt-parent-id', parent[idAttr])
  101. }
  102. if (renderer) {
  103. renderer($(tr), node)
  104. }else if (attrs) {
  105. $.each(attrs, function(attr, desc) {
  106. $(tr).append($('<td>' + node[attr] + '</td>'))
  107. })
  108. } else {
  109. $(tr).append($('<td>' + node[idAttr] + '</td>'))
  110. $.each(node, function(key, value) {
  111. if (key != childrenAttr && key != idAttr && key != 'data-tt-level')
  112. $(tr).append($('<td>' + value + '</td>'))
  113. })
  114. }
  115. tbody.append(tr)
  116. }
  117. function i_renderTree(subTree, childrenAttr, level, parent) {
  118. maxLevel = Math.max(maxLevel, level)
  119. $.each(subTree, function(i, node) {
  120. node['data-tt-level'] = level
  121. render(node, parent)
  122. if (node[childrenAttr]) {
  123. $.each(node[childrenAttr], function(i, child) {
  124. i_renderTree([ child ], childrenAttr, level + 1, node)
  125. })
  126. }
  127. })
  128. }
  129. i_renderTree(tree, childrenAttr, 1)
  130. if (tree[0])
  131. tree[0].maxLevel = maxLevel
  132. return table
  133. }
  134. function attr2attr(nodes, attrs){
  135. $.each(nodes, function(i, node) {
  136. $.each(attrs, function(j, at) {
  137. node[at] = $(node).attr(at)
  138. })
  139. })
  140. return nodes
  141. }
  142. function treeTable(table){
  143. table.addClass('jsTT')
  144. table.expandLevel = function (n) {
  145. $("tr[data-tt-level]", table).each(function(index) {
  146. var level = parseInt($(this).attr('data-tt-level'))
  147. if (level > n-1) {
  148. this.trCollapse(true)
  149. } else if (level == n-1){
  150. this.trExpand(true)
  151. }
  152. })
  153. }
  154. function getLevel(node){
  155. var level = node.attr('data-tt-level')
  156. if(level != undefined ) return parseInt(level)
  157. var parentID = node.attr('data-tt-parent-id')
  158. if( parentID == undefined){
  159. return 0
  160. } else {
  161. return getLevel($('tr[data-tt-id="'+parentID+'"]', table).first()) + 1
  162. }
  163. }
  164. $("tr[data-tt-id]", table).each(function(i,node){
  165. node = $(node)
  166. node.attr('data-tt-level', getLevel(node))
  167. })
  168. var dat = $("tr[data-tt-level]", table).get()
  169. $.each(dat, function(j, d) {
  170. d.trChildrenVisible = true
  171. d.trChildren = []
  172. })
  173. dat = attr2attr(dat, ['data-tt-id', 'data-tt-parent-id'])
  174. dat = makeTree(dat, 'data-tt-id', 'data-tt-parent-id', 'trChildren')
  175. var imgExpand = "data:image/png;base64,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"
  176. var imgCollapse = "data:image/png;base64,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"
  177. $("tr[data-tt-level]", table).each(function(index, tr) {
  178. var level = $(tr).attr('data-tt-level')
  179. var td = $("td",tr).first()
  180. if(tr.trChildren.length>0){
  181. td.prepend($('<img id="state" style="cursor:pointer" src="'+imgCollapse+'"/>'))
  182. } else {
  183. td.prepend($('<span style="padding-left:16px;" /></span>'))
  184. }
  185. td.prepend($('<span style="padding-left:'+(15*parseInt(level-1))+'px;" /></span>'))
  186. // td.css('white-space','nowrap')
  187. tr.trExpand = function(changeState){
  188. if(this.trChildren.length < 1) return
  189. if(changeState) {
  190. this.trChildrenVisible = true
  191. $('#state', this).get(0).src= imgCollapse
  192. }
  193. var doit = changeState || this.trChildrenVisible
  194. $.each(this.trChildren, function(i, ctr) {
  195. if(doit) $(ctr).css('display', 'table-row')
  196. ctr.trExpand()
  197. })
  198. }
  199. tr.trCollapse = function(changeState){
  200. if(this.trChildren.length < 1) return
  201. if(changeState) {
  202. this.trChildrenVisible = false
  203. $('#state', this).get(0).src= imgExpand
  204. }
  205. $.each(this.trChildren, function(i, ctr) {
  206. $(ctr).css('display', 'none')
  207. ctr.trCollapse()
  208. })
  209. }
  210. $(tr).click(function() {
  211. this.trChildrenVisible ? this.trCollapse(true) : this.trExpand(true)
  212. })
  213. })
  214. return table
  215. }
  216. function appendTreetable(tree, options) {
  217. function inALine(nodes) {
  218. var tr = $('<tr>')
  219. $.each(nodes, function(i, node){
  220. tr.append($('<td style="padding-right: 20px;">').append(node))
  221. })
  222. return $('<table border="0"/>').append(tr)
  223. }
  224. options = options || {}
  225. options.idAttr = (options.idAttr || 'id')
  226. options.childrenAttr = (options.childrenAttr || 'children')
  227. var controls = (options.controls || [])
  228. if (!options.mountPoint)
  229. options.mountPoint = $('body')
  230. if (options.depthFirst)
  231. depthFirst(tree, options.depthFirst, options.childrenAttr)
  232. var rendered = renderTree(tree, options.childrenAttr, options.idAttr,
  233. options.renderedAttr, options.renderer, options.tableAttributes)
  234. treeTable(rendered)
  235. if (options.replaceContent) {
  236. options.mountPoint.html('')
  237. }
  238. var initialExpandLevel = options.initialExpandLevel ? parseInt(options.initialExpandLevel) : -1
  239. initialExpandLevel = Math.min(initialExpandLevel, tree[0].maxLevel)
  240. rendered.expandLevel(initialExpandLevel)
  241. if(options.slider){
  242. var slider = $('<div style="margin-right: 15px;">')
  243. slider.width('200px')
  244. slider.slider({
  245. min : 1,
  246. max : tree[0].maxLevel,
  247. range : "min",
  248. value : initialExpandLevel,
  249. slide : function(event, ui) {
  250. rendered.expandLevel(ui.value)
  251. }
  252. })
  253. controls = [slider].concat(options.controls)
  254. }
  255. if(controls.length >0){
  256. options.mountPoint.append(inALine(controls))
  257. }
  258. options.mountPoint.append(rendered)
  259. return rendered
  260. }
  261. return {
  262. depthFirst : depthFirst,
  263. makeTree : makeTree,
  264. renderTree : renderTree,
  265. attr2attr : attr2attr,
  266. treeTable : treeTable,
  267. appendTreetable : appendTreetable,
  268. jsTreeTable : '1.0',
  269. register : function(target){
  270. $.each(this, function(key, value){ if(key != 'register') target[key] = value})
  271. }
  272. }
  273. })();