otsdaq_utilities  v2_05_02_indev
data_tree.js
1 var DataTree = function(table){
2  this.table = table;
3  this.indent = 10;
4  this.field = "";
5  this.collapseEl = null;
6  this.expandEl = null;
7  this.branchEl = null;
8  this.elementField = false;
9 
10  this.startOpen = function(){};
11 
12  this.displayIndex = 0;
13 };
14 
15 DataTree.prototype.initialize = function(){
16  var dummyEl = null,
17  firstCol = this.table.columnManager.getFirstVisibileColumn(),
18  options = this.table.options;
19 
20  this.field = options.dataTreeChildField;
21  this.indent = options.dataTreeChildIndent;
22  this.elementField = options.dataTreeElementColumn || (firstCol ? firstCol.field : false);
23 
24  if(options.dataTreeBranchElement){
25 
26  if(options.dataTreeBranchElement === true){
27  this.branchEl = document.createElement("div");
28  this.branchEl.classList.add("tabulator-data-tree-branch");
29  }else{
30  if(typeof options.dataTreeBranchElement === "string"){
31  dummyEl = document.createElement("div");
32  dummyEl.innerHTML = options.dataTreeBranchElement;
33  this.branchEl = dummyEl.firstChild;
34  }else{
35  this.branchEl = options.dataTreeBranchElement;
36  }
37  }
38  }
39 
40  if(options.dataTreeCollapseElement){
41  if(typeof options.dataTreeCollapseElement === "string"){
42  dummyEl = document.createElement("div");
43  dummyEl.innerHTML = options.dataTreeCollapseElement;
44  this.collapseEl = dummyEl.firstChild;
45  }else{
46  this.collapseEl = options.dataTreeCollapseElement;
47  }
48  }else{
49  this.collapseEl = document.createElement("div");
50  this.collapseEl.classList.add("tabulator-data-tree-control");
51  this.collapseEl.tabIndex = 0;
52  this.collapseEl.innerHTML = "<div class='tabulator-data-tree-control-collapse'></div>";
53  }
54 
55  if(options.dataTreeExpandElement){
56  if(typeof options.dataTreeExpandElement === "string"){
57  dummyEl = document.createElement("div");
58  dummyEl.innerHTML = options.dataTreeExpandElement;
59  this.expandEl = dummyEl.firstChild;
60  }else{
61  this.expandEl = options.dataTreeExpandElement;
62  }
63  }else{
64  this.expandEl = document.createElement("div");
65  this.expandEl.classList.add("tabulator-data-tree-control");
66  this.expandEl.tabIndex = 0;
67  this.expandEl.innerHTML = "<div class='tabulator-data-tree-control-expand'></div>";
68  }
69 
70 
71  switch(typeof options.dataTreeStartExpanded){
72  case "boolean":
73  this.startOpen = function(row, index){
74  return options.dataTreeStartExpanded;
75  };
76  break;
77 
78  case "function":
79  this.startOpen = options.dataTreeStartExpanded;
80  break;
81 
82  default:
83  this.startOpen = function(row, index){
84  return options.dataTreeStartExpanded[index];
85  };
86  break;
87  }
88 };
89 
90 DataTree.prototype.initializeRow = function(row){
91  var childArray = row.getData()[this.field];
92  var isArray = Array.isArray(childArray);
93 
94  var children = isArray || (!isArray && typeof childArray === "object" && childArray !== null) ;
95 
96  row.modules.dataTree = {
97  index:0,
98  open:children ? this.startOpen(row.getComponent(), 0) : false,
99  controlEl:false,
100  branchEl:false,
101  parent:false,
102  children:children,
103  };
104 };
105 
106 
107 DataTree.prototype.layoutRow = function(row){
108  var cell = this.elementField ? row.getCell(this.elementField) : row.getCells()[0],
109  el = cell.getElement(),
110  config = row.modules.dataTree;
111 
112  if(config.branchEl){
113  config.branchEl.parentNode.removeChild(config.branchEl);
114  }
115 
116  this.generateControlElement(row, el);
117 
118  row.element.classList.add("tabulator-tree-level-" + config.index);
119 
120  if(config.index){
121  if(this.branchEl){
122  config.branchEl = this.branchEl.cloneNode(true);
123  el.insertBefore(config.branchEl, el.firstChild);
124  config.branchEl.style.marginLeft = (((config.branchEl.offsetWidth + config.branchEl.style.marginRight) * (config.index - 1)) + (config.index * this.indent)) + "px";
125  }else{
126  el.style.paddingLeft = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + (config.index * this.indent) + "px";
127  }
128  }
129 };
130 
131 DataTree.prototype.generateControlElement = function(row, el){
132  var config = row.modules.dataTree,
133  el = el || row.getCells()[0].getElement(),
134  oldControl = config.controlEl;
135 
136  if(config.children !== false){
137 
138  if(config.open){
139  config.controlEl = this.collapseEl.cloneNode(true);
140  config.controlEl.addEventListener("click", (e) => {
141  e.stopPropagation();
142  this.collapseRow(row);
143  });
144  }else{
145  config.controlEl = this.expandEl.cloneNode(true);
146  config.controlEl.addEventListener("click", (e) => {
147  e.stopPropagation();
148  this.expandRow(row);
149  });
150  }
151 
152  config.controlEl.addEventListener("mousedown", (e) => {
153  e.stopPropagation();
154  });
155 
156  if(oldControl && oldControl.parentNode === el){
157  oldControl.parentNode.replaceChild(config.controlEl,oldControl);
158  }else{
159  el.insertBefore(config.controlEl, el.firstChild);
160  }
161  }
162 };
163 
164 DataTree.prototype.setDisplayIndex = function (index) {
165  this.displayIndex = index;
166 };
167 
168 DataTree.prototype.getDisplayIndex = function () {
169  return this.displayIndex;
170 };
171 
172 DataTree.prototype.getRows = function(rows){
173  var output = [];
174 
175  rows.forEach((row, i) => {
176  var config, children;
177 
178  output.push(row);
179 
180  if(row instanceof Row){
181 
182  config = row.modules.dataTree.children;
183 
184  if(!config.index && config.children !== false){
185  children = this.getChildren(row);
186 
187  children.forEach((child) => {
188  output.push(child);
189  });
190  }
191  }
192  });
193 
194  return output;
195 };
196 
197 
198 DataTree.prototype.getChildren = function(row){
199  var config = row.modules.dataTree,
200  children = [],
201  output = [];
202 
203  if(config.children !== false && config.open){
204  if(!Array.isArray(config.children)){
205  config.children = this.generateChildren(row);
206  }
207 
208  if(this.table.modExists("filter")){
209  children = this.table.modules.filter.filter(config.children);
210  }else{
211  children = config.children;
212  }
213 
214  if(this.table.modExists("sort")){
215  this.table.modules.sort.sort(children);
216  }
217 
218  children.forEach((child) => {
219  output.push(child);
220 
221  var subChildren = this.getChildren(child);
222 
223  subChildren.forEach((sub) => {
224  output.push(sub);
225  });
226  });
227  }
228 
229  return output;
230 };
231 
232 
233 DataTree.prototype.generateChildren = function(row){
234  var children = [];
235 
236  var childArray = row.getData()[this.field];
237 
238  if(!Array.isArray(childArray)){
239  childArray = [childArray];
240  }
241 
242  childArray.forEach((childData) => {
243  var childRow = new Row(childData || {}, this.table.rowManager);
244  childRow.modules.dataTree.index = row.modules.dataTree.index + 1;
245  childRow.modules.dataTree.parent = row;
246  if(childRow.modules.dataTree.children){
247  childRow.modules.dataTree.open = this.startOpen(childRow.getComponent(), childRow.modules.dataTree.index);
248  }
249  children.push(childRow);
250  });
251 
252  return children;
253 };
254 
255 
256 
257 DataTree.prototype.expandRow = function(row, silent){
258  var config = row.modules.dataTree;
259 
260  if(config.children !== false){
261  config.open = true;
262 
263  row.reinitialize();
264 
265  this.table.rowManager.refreshActiveData("tree", false, true);
266 
267  this.table.options.dataTreeRowExpanded(row.getComponent(), row.modules.dataTree.index);
268  }
269 };
270 
271 DataTree.prototype.collapseRow = function(row){
272  var config = row.modules.dataTree;
273 
274  if(config.children !== false){
275  config.open = false;
276 
277  row.reinitialize();
278 
279  this.table.rowManager.refreshActiveData("tree", false, true);
280 
281  this.table.options.dataTreeRowCollapsed(row.getComponent(), row.modules.dataTree.index);
282  }
283 };
284 
285 DataTree.prototype.toggleRow = function(row){
286  var config = row.modules.dataTree;
287 
288  if(config.children !== false){
289  if(config.open){
290  this.collapseRow(row);
291  }else{
292  this.expandRow(row);
293  }
294  }
295 };
296 
297 DataTree.prototype.getTreeParent = function(row){
298  return row.modules.dataTree.parent ? row.modules.dataTree.parent.getComponent() : false;
299 };
300 
301 DataTree.prototype.getTreeChildren = function(row){
302  var config = row.modules.dataTree,
303  output = [];
304 
305  if(config.children){
306 
307  if(!Array.isArray(config.children)){
308  config.children = this.generateChildren(row);
309  }
310 
311  config.children.forEach((childRow) => {
312  if(childRow instanceof Row){
313  output.push(childRow.getComponent());
314  }
315  });
316  }
317 
318  return output;
319 };
320 
321 
322 DataTree.prototype.checkForRestyle = function(cell){
323  if(!cell.row.cells.indexOf(cell)){
324  if(cell.row.modules.dataTree.children !== false){
325  cell.row.reinitialize();
326  }
327  }
328 };
329 
330 DataTree.prototype.getChildField = function(){
331  return this.field;
332 };
333 
334 DataTree.prototype.redrawNeeded = function(data){
335  return (this.field ? typeof data[this.field] !== "undefined" : false) || (this.elementField ? typeof data[this.elementField] !== "undefined" : false);
336 };
337 
338 Tabulator.prototype.registerModule("dataTree", DataTree);