otsdaq_utilities  v2_05_02_indev
group_rows.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 //public group object
4 var GroupComponent = function GroupComponent(group) {
5  this._group = group;
6  this.type = "GroupComponent";
7 };
8 
9 GroupComponent.prototype.getKey = function () {
10  return this._group.key;
11 };
12 
13 GroupComponent.prototype.getField = function () {
14  return this._group.field;
15 };
16 
17 GroupComponent.prototype.getElement = function () {
18  return this._group.element;
19 };
20 
21 GroupComponent.prototype.getRows = function () {
22  return this._group.getRows(true);
23 };
24 
25 GroupComponent.prototype.getSubGroups = function () {
26  return this._group.getSubGroups(true);
27 };
28 
29 GroupComponent.prototype.getParentGroup = function () {
30  return this._group.parent ? this._group.parent.getComponent() : false;
31 };
32 
33 GroupComponent.prototype.getVisibility = function () {
34  return this._group.visible;
35 };
36 
37 GroupComponent.prototype.show = function () {
38  this._group.show();
39 };
40 
41 GroupComponent.prototype.hide = function () {
42  this._group.hide();
43 };
44 
45 GroupComponent.prototype.toggle = function () {
46  this._group.toggleVisibility();
47 };
48 
49 GroupComponent.prototype._getSelf = function () {
50  return this._group;
51 };
52 
53 GroupComponent.prototype.getTable = function () {
54  return this._group.groupManager.table;
55 };
56 
60 
61 var Group = function Group(groupManager, parent, level, key, field, generator, oldGroup) {
62 
63  this.groupManager = groupManager;
64  this.parent = parent;
65  this.key = key;
66  this.level = level;
67  this.field = field;
68  this.hasSubGroups = level < groupManager.groupIDLookups.length - 1;
69  this.addRow = this.hasSubGroups ? this._addRowToGroup : this._addRow;
70  this.type = "group"; //type of element
71  this.old = oldGroup;
72  this.rows = [];
73  this.groups = [];
74  this.groupList = [];
75  this.generator = generator;
76  this.elementContents = false;
77  this.height = 0;
78  this.outerHeight = 0;
79  this.initialized = false;
80  this.calcs = {};
81  this.initialized = false;
82  this.modules = {};
83  this.arrowElement = false;
84 
85  this.visible = oldGroup ? oldGroup.visible : typeof groupManager.startOpen[level] !== "undefined" ? groupManager.startOpen[level] : groupManager.startOpen[0];
86 
87  this.createElements();
88  this.addBindings();
89 
90  this.createValueGroups();
91 };
92 
93 Group.prototype.wipe = function () {
94  if (this.groupList.length) {
95  this.groupList.forEach(function (group) {
96  group.wipe();
97  });
98  } else {
99  this.element = false;
100  this.arrowElement = false;
101  this.elementContents = false;
102  }
103 };
104 
105 Group.prototype.createElements = function () {
106  var arrow = document.createElement("div");
107  arrow.classList.add("tabulator-arrow");
108 
109  this.element = document.createElement("div");
110  this.element.classList.add("tabulator-row");
111  this.element.classList.add("tabulator-group");
112  this.element.classList.add("tabulator-group-level-" + this.level);
113  this.element.setAttribute("role", "rowgroup");
114 
115  this.arrowElement = document.createElement("div");
116  this.arrowElement.classList.add("tabulator-group-toggle");
117  this.arrowElement.appendChild(arrow);
118 
119  //setup movable rows
120  if (this.groupManager.table.options.movableRows !== false && this.groupManager.table.modExists("moveRow")) {
121  this.groupManager.table.modules.moveRow.initializeGroupHeader(this);
122  }
123 };
124 
125 Group.prototype.createValueGroups = function () {
126  var _this = this;
127 
128  var level = this.level + 1;
129  if (this.groupManager.allowedValues && this.groupManager.allowedValues[level]) {
130  this.groupManager.allowedValues[level].forEach(function (value) {
131  _this._createGroup(value, level);
132  });
133  }
134 };
135 
136 Group.prototype.addBindings = function () {
137  var self = this,
138  dblTap,
139  tapHold,
140  tap,
141  toggleElement;
142 
143  //handle group click events
144  if (self.groupManager.table.options.groupClick) {
145  self.element.addEventListener("click", function (e) {
146  self.groupManager.table.options.groupClick.call(self.groupManager.table, e, self.getComponent());
147  });
148  }
149 
150  if (self.groupManager.table.options.groupDblClick) {
151  self.element.addEventListener("dblclick", function (e) {
152  self.groupManager.table.options.groupDblClick.call(self.groupManager.table, e, self.getComponent());
153  });
154  }
155 
156  if (self.groupManager.table.options.groupContext) {
157  self.element.addEventListener("contextmenu", function (e) {
158  self.groupManager.table.options.groupContext.call(self.groupManager.table, e, self.getComponent());
159  });
160  }
161 
162  if (self.groupManager.table.options.groupTap) {
163 
164  tap = false;
165 
166  self.element.addEventListener("touchstart", function (e) {
167  tap = true;
168  }, { passive: true });
169 
170  self.element.addEventListener("touchend", function (e) {
171  if (tap) {
172  self.groupManager.table.options.groupTap(e, self.getComponent());
173  }
174 
175  tap = false;
176  });
177  }
178 
179  if (self.groupManager.table.options.groupDblTap) {
180 
181  dblTap = null;
182 
183  self.element.addEventListener("touchend", function (e) {
184 
185  if (dblTap) {
186  clearTimeout(dblTap);
187  dblTap = null;
188 
189  self.groupManager.table.options.groupDblTap(e, self.getComponent());
190  } else {
191 
192  dblTap = setTimeout(function () {
193  clearTimeout(dblTap);
194  dblTap = null;
195  }, 300);
196  }
197  });
198  }
199 
200  if (self.groupManager.table.options.groupTapHold) {
201 
202  tapHold = null;
203 
204  self.element.addEventListener("touchstart", function (e) {
205  clearTimeout(tapHold);
206 
207  tapHold = setTimeout(function () {
208  clearTimeout(tapHold);
209  tapHold = null;
210  tap = false;
211  self.groupManager.table.options.groupTapHold(e, self.getComponent());
212  }, 1000);
213  }, { passive: true });
214 
215  self.element.addEventListener("touchend", function (e) {
216  clearTimeout(tapHold);
217  tapHold = null;
218  });
219  }
220 
221  if (self.groupManager.table.options.groupToggleElement) {
222  toggleElement = self.groupManager.table.options.groupToggleElement == "arrow" ? self.arrowElement : self.element;
223 
224  toggleElement.addEventListener("click", function (e) {
225  e.stopPropagation();
226  e.stopImmediatePropagation();
227  self.toggleVisibility();
228  });
229  }
230 };
231 
232 Group.prototype._createGroup = function (groupID, level) {
233  var groupKey = level + "_" + groupID;
234  var group = new Group(this.groupManager, this, level, groupID, this.groupManager.groupIDLookups[level].field, this.groupManager.headerGenerator[level] || this.groupManager.headerGenerator[0], this.old ? this.old.groups[groupKey] : false);
235 
236  this.groups[groupKey] = group;
237  this.groupList.push(group);
238 };
239 
240 Group.prototype._addRowToGroup = function (row) {
241 
242  var level = this.level + 1;
243 
244  if (this.hasSubGroups) {
245  var groupID = this.groupManager.groupIDLookups[level].func(row.getData()),
246  groupKey = level + "_" + groupID;
247 
248  if (this.groupManager.allowedValues && this.groupManager.allowedValues[level]) {
249  if (this.groups[groupKey]) {
250  this.groups[groupKey].addRow(row);
251  }
252  } else {
253  if (!this.groups[groupKey]) {
254  this._createGroup(groupID, level);
255  }
256 
257  this.groups[groupKey].addRow(row);
258  }
259  }
260 };
261 
262 Group.prototype._addRow = function (row) {
263  this.rows.push(row);
264  row.modules.group = this;
265 };
266 
267 Group.prototype.insertRow = function (row, to, after) {
268  var data = this.conformRowData({});
269 
270  row.updateData(data);
271 
272  var toIndex = this.rows.indexOf(to);
273 
274  if (toIndex > -1) {
275  if (after) {
276  this.rows.splice(toIndex + 1, 0, row);
277  } else {
278  this.rows.splice(toIndex, 0, row);
279  }
280  } else {
281  if (after) {
282  this.rows.push(row);
283  } else {
284  this.rows.unshift(row);
285  }
286  }
287 
288  row.modules.group = this;
289 
290  this.generateGroupHeaderContents();
291 
292  if (this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table") {
293  this.groupManager.table.modules.columnCalcs.recalcGroup(this);
294  }
295 
296  this.groupManager.updateGroupRows(true);
297 };
298 
299 Group.prototype.scrollHeader = function (left) {
300  this.arrowElement.style.marginLeft = left;
301 
302  this.groupList.forEach(function (child) {
303  child.scrollHeader(left);
304  });
305 };
306 
307 Group.prototype.getRowIndex = function (row) {};
308 
309 //update row data to match grouping contraints
310 Group.prototype.conformRowData = function (data) {
311  if (this.field) {
312  data[this.field] = this.key;
313  } else {
314  console.warn("Data Conforming Error - Cannot conform row data to match new group as groupBy is a function");
315  }
316 
317  if (this.parent) {
318  data = this.parent.conformRowData(data);
319  }
320 
321  return data;
322 };
323 
324 Group.prototype.removeRow = function (row) {
325  var index = this.rows.indexOf(row);
326  var el = row.getElement();
327 
328  if (index > -1) {
329  this.rows.splice(index, 1);
330  }
331 
332  if (!this.groupManager.table.options.groupValues && !this.rows.length) {
333  if (this.parent) {
334  this.parent.removeGroup(this);
335  } else {
336  this.groupManager.removeGroup(this);
337  }
338 
339  this.groupManager.updateGroupRows(true);
340  } else {
341 
342  if (el.parentNode) {
343  el.parentNode.removeChild(el);
344  }
345 
346  this.generateGroupHeaderContents();
347 
348  if (this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table") {
349  this.groupManager.table.modules.columnCalcs.recalcGroup(this);
350  }
351  }
352 };
353 
354 Group.prototype.removeGroup = function (group) {
355  var groupKey = group.level + "_" + group.key,
356  index;
357 
358  if (this.groups[groupKey]) {
359  delete this.groups[groupKey];
360 
361  index = this.groupList.indexOf(group);
362 
363  if (index > -1) {
364  this.groupList.splice(index, 1);
365  }
366 
367  if (!this.groupList.length) {
368  if (this.parent) {
369  this.parent.removeGroup(this);
370  } else {
371  this.groupManager.removeGroup(this);
372  }
373  }
374  }
375 };
376 
377 Group.prototype.getHeadersAndRows = function (noCalc) {
378  var output = [];
379 
380  output.push(this);
381 
382  this._visSet();
383 
384  if (this.visible) {
385  if (this.groupList.length) {
386  this.groupList.forEach(function (group) {
387  output = output.concat(group.getHeadersAndRows(noCalc));
388  });
389  } else {
390  if (!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()) {
391  if (this.calcs.top) {
392  this.calcs.top.detachElement();
393  this.calcs.top.deleteCells();
394  }
395 
396  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
397  output.push(this.calcs.top);
398  }
399 
400  output = output.concat(this.rows);
401 
402  if (!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()) {
403  if (this.calcs.bottom) {
404  this.calcs.bottom.detachElement();
405  this.calcs.bottom.deleteCells();
406  }
407 
408  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
409  output.push(this.calcs.bottom);
410  }
411  }
412  } else {
413  if (!this.groupList.length && this.groupManager.table.options.columnCalcs != "table") {
414 
415  if (this.groupManager.table.modExists("columnCalcs")) {
416 
417  if (!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()) {
418  if (this.calcs.top) {
419  this.calcs.top.detachElement();
420  this.calcs.top.deleteCells();
421  }
422 
423  if (this.groupManager.table.options.groupClosedShowCalcs) {
424  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
425  output.push(this.calcs.top);
426  }
427  }
428 
429  if (!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()) {
430  if (this.calcs.bottom) {
431  this.calcs.bottom.detachElement();
432  this.calcs.bottom.deleteCells();
433  }
434 
435  if (this.groupManager.table.options.groupClosedShowCalcs) {
436  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
437  output.push(this.calcs.bottom);
438  }
439  }
440  }
441  }
442  }
443 
444  return output;
445 };
446 
447 Group.prototype.getData = function (visible, transform) {
448  var self = this,
449  output = [];
450 
451  this._visSet();
452 
453  if (!visible || visible && this.visible) {
454  this.rows.forEach(function (row) {
455  output.push(row.getData(transform || "data"));
456  });
457  }
458 
459  return output;
460 };
461 
462 // Group.prototype.getRows = function(){
463 // this._visSet();
464 
465 // return this.visible ? this.rows : [];
466 // };
467 
468 Group.prototype.getRowCount = function () {
469  var count = 0;
470 
471  if (this.groupList.length) {
472  this.groupList.forEach(function (group) {
473  count += group.getRowCount();
474  });
475  } else {
476  count = this.rows.length;
477  }
478  return count;
479 };
480 
481 Group.prototype.toggleVisibility = function () {
482  if (this.visible) {
483  this.hide();
484  } else {
485  this.show();
486  }
487 };
488 
489 Group.prototype.hide = function () {
490  this.visible = false;
491 
492  if (this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination) {
493 
494  this.element.classList.remove("tabulator-group-visible");
495 
496  if (this.groupList.length) {
497  this.groupList.forEach(function (group) {
498 
499  var rows = group.getHeadersAndRows();
500 
501  rows.forEach(function (row) {
502  row.detachElement();
503  });
504  });
505  } else {
506  this.rows.forEach(function (row) {
507  var rowEl = row.getElement();
508  rowEl.parentNode.removeChild(rowEl);
509  });
510  }
511 
512  this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
513 
514  this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
515  } else {
516  this.groupManager.updateGroupRows(true);
517  }
518 
519  this.groupManager.table.options.groupVisibilityChanged.call(this.table, this.getComponent(), false);
520 };
521 
522 Group.prototype.show = function () {
523  var self = this;
524 
525  self.visible = true;
526 
527  if (this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination) {
528 
529  this.element.classList.add("tabulator-group-visible");
530 
531  var prev = self.getElement();
532 
533  if (this.groupList.length) {
534  this.groupList.forEach(function (group) {
535  var rows = group.getHeadersAndRows();
536 
537  rows.forEach(function (row) {
538  var rowEl = row.getElement();
539  prev.parentNode.insertBefore(rowEl, prev.nextSibling);
540  row.initialize();
541  prev = rowEl;
542  });
543  });
544  } else {
545  self.rows.forEach(function (row) {
546  var rowEl = row.getElement();
547  prev.parentNode.insertBefore(rowEl, prev.nextSibling);
548  row.initialize();
549  prev = rowEl;
550  });
551  }
552 
553  this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
554 
555  this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
556  } else {
557  this.groupManager.updateGroupRows(true);
558  }
559 
560  this.groupManager.table.options.groupVisibilityChanged.call(this.table, this.getComponent(), true);
561 };
562 
563 Group.prototype._visSet = function () {
564  var data = [];
565 
566  if (typeof this.visible == "function") {
567 
568  this.rows.forEach(function (row) {
569  data.push(row.getData());
570  });
571 
572  this.visible = this.visible(this.key, this.getRowCount(), data, this.getComponent());
573  }
574 };
575 
576 Group.prototype.getRowGroup = function (row) {
577  var match = false;
578  if (this.groupList.length) {
579  this.groupList.forEach(function (group) {
580  var result = group.getRowGroup(row);
581 
582  if (result) {
583  match = result;
584  }
585  });
586  } else {
587  if (this.rows.find(function (item) {
588  return item === row;
589  })) {
590  match = this;
591  }
592  }
593 
594  return match;
595 };
596 
597 Group.prototype.getSubGroups = function (component) {
598  var output = [];
599 
600  this.groupList.forEach(function (child) {
601  output.push(component ? child.getComponent() : child);
602  });
603 
604  return output;
605 };
606 
607 Group.prototype.getRows = function (compoment) {
608  var output = [];
609 
610  this.rows.forEach(function (row) {
611  output.push(compoment ? row.getComponent() : row);
612  });
613 
614  return output;
615 };
616 
617 Group.prototype.generateGroupHeaderContents = function () {
618  var data = [];
619 
620  this.rows.forEach(function (row) {
621  data.push(row.getData());
622  });
623 
624  this.elementContents = this.generator(this.key, this.getRowCount(), data, this.getComponent());
625 
626  while (this.element.firstChild) {
627  this.element.removeChild(this.element.firstChild);
628  }if (typeof this.elementContents === "string") {
629  this.element.innerHTML = this.elementContents;
630  } else {
631  this.element.appendChild(this.elementContents);
632  }
633 
634  this.element.insertBefore(this.arrowElement, this.element.firstChild);
635 };
636 
638 
639 Group.prototype.getElement = function () {
640  this.addBindingsd = false;
641 
642  this._visSet();
643 
644  if (this.visible) {
645  this.element.classList.add("tabulator-group-visible");
646  } else {
647  this.element.classList.remove("tabulator-group-visible");
648  }
649 
650  for (var i = 0; i < this.element.childNodes.length; ++i) {
651  this.element.childNodes[i].parentNode.removeChild(this.element.childNodes[i]);
652  }
653 
654  this.generateGroupHeaderContents();
655 
656  // this.addBindings();
657 
658  return this.element;
659 };
660 
661 Group.prototype.detachElement = function () {
662  if (this.element && this.element.parentNode) {
663  this.element.parentNode.removeChild(this.element);
664  }
665 };
666 
667 //normalize the height of elements in the row
668 Group.prototype.normalizeHeight = function () {
669  this.setHeight(this.element.clientHeight);
670 };
671 
672 Group.prototype.initialize = function (force) {
673  if (!this.initialized || force) {
674  this.normalizeHeight();
675  this.initialized = true;
676  }
677 };
678 
679 Group.prototype.reinitialize = function () {
680  this.initialized = false;
681  this.height = 0;
682 
683  if (Tabulator.prototype.helpers.elVisible(this.element)) {
684  this.initialize(true);
685  }
686 };
687 
688 Group.prototype.setHeight = function (height) {
689  if (this.height != height) {
690  this.height = height;
691  this.outerHeight = this.element.offsetHeight;
692  }
693 };
694 
695 //return rows outer height
696 Group.prototype.getHeight = function () {
697  return this.outerHeight;
698 };
699 
700 Group.prototype.getGroup = function () {
701  return this;
702 };
703 
704 Group.prototype.reinitializeHeight = function () {};
705 Group.prototype.calcHeight = function () {};
706 Group.prototype.setCellHeight = function () {};
707 Group.prototype.clearCellHeight = function () {};
708 
710 Group.prototype.getComponent = function () {
711  return new GroupComponent(this);
712 };
713 
717 
718 var GroupRows = function GroupRows(table) {
719 
720  this.table = table; //hold Tabulator object
721 
722  this.groupIDLookups = false; //enable table grouping and set field to group by
723  this.startOpen = [function () {
724  return false;
725  }]; //starting state of group
726  this.headerGenerator = [function () {
727  return "";
728  }];
729  this.groupList = []; //ordered list of groups
730  this.allowedValues = false;
731  this.groups = {}; //hold row groups
732  this.displayIndex = 0; //index in display pipeline
733 };
734 
735 //initialize group configuration
736 GroupRows.prototype.initialize = function () {
737  var self = this,
738  groupBy = self.table.options.groupBy,
739  startOpen = self.table.options.groupStartOpen,
740  groupHeader = self.table.options.groupHeader;
741 
742  this.allowedValues = self.table.options.groupValues;
743 
744  if (Array.isArray(groupBy) && Array.isArray(groupHeader) && groupBy.length > groupHeader.length) {
745  console.warn("Error creating group headers, groupHeader array is shorter than groupBy array");
746  }
747 
748  self.headerGenerator = [function () {
749  return "";
750  }];
751  this.startOpen = [function () {
752  return false;
753  }]; //starting state of group
754 
755  self.table.modules.localize.bind("groups|item", function (langValue, lang) {
756  self.headerGenerator[0] = function (value, count, data) {
757  //header layout function
758  return (typeof value === "undefined" ? "" : value) + "<span>(" + count + " " + (count === 1 ? langValue : lang.groups.items) + ")</span>";
759  };
760  });
761 
762  this.groupIDLookups = [];
763 
764  if (Array.isArray(groupBy) || groupBy) {
765  if (this.table.modExists("columnCalcs") && this.table.options.columnCalcs != "table" && this.table.options.columnCalcs != "both") {
766  this.table.modules.columnCalcs.removeCalcs();
767  }
768  } else {
769  if (this.table.modExists("columnCalcs") && this.table.options.columnCalcs != "group") {
770 
771  var cols = this.table.columnManager.getRealColumns();
772 
773  cols.forEach(function (col) {
774  if (col.definition.topCalc) {
775  self.table.modules.columnCalcs.initializeTopRow();
776  }
777 
778  if (col.definition.bottomCalc) {
779  self.table.modules.columnCalcs.initializeBottomRow();
780  }
781  });
782  }
783  }
784 
785  if (!Array.isArray(groupBy)) {
786  groupBy = [groupBy];
787  }
788 
789  groupBy.forEach(function (group, i) {
790  var lookupFunc, column;
791 
792  if (typeof group == "function") {
793  lookupFunc = group;
794  } else {
795  column = self.table.columnManager.getColumnByField(group);
796 
797  if (column) {
798  lookupFunc = function lookupFunc(data) {
799  return column.getFieldValue(data);
800  };
801  } else {
802  lookupFunc = function lookupFunc(data) {
803  return data[group];
804  };
805  }
806  }
807 
808  self.groupIDLookups.push({
809  field: typeof group === "function" ? false : group,
810  func: lookupFunc,
811  values: self.allowedValues ? self.allowedValues[i] : false
812  });
813  });
814 
815  if (startOpen) {
816 
817  if (!Array.isArray(startOpen)) {
818  startOpen = [startOpen];
819  }
820 
821  startOpen.forEach(function (level) {
822  level = typeof level == "function" ? level : function () {
823  return true;
824  };
825  });
826 
827  self.startOpen = startOpen;
828  }
829 
830  if (groupHeader) {
831  self.headerGenerator = Array.isArray(groupHeader) ? groupHeader : [groupHeader];
832  }
833 
834  this.initialized = true;
835 };
836 
837 GroupRows.prototype.setDisplayIndex = function (index) {
838  this.displayIndex = index;
839 };
840 
841 GroupRows.prototype.getDisplayIndex = function () {
842  return this.displayIndex;
843 };
844 
845 //return appropriate rows with group headers
846 GroupRows.prototype.getRows = function (rows) {
847  if (this.groupIDLookups.length) {
848 
849  this.table.options.dataGrouping.call(this.table);
850 
851  this.generateGroups(rows);
852 
853  if (this.table.options.dataGrouped) {
854  this.table.options.dataGrouped.call(this.table, this.getGroups(true));
855  }
856 
857  return this.updateGroupRows();
858  } else {
859  return rows.slice(0);
860  }
861 };
862 
863 GroupRows.prototype.getGroups = function (compoment) {
864  var groupComponents = [];
865 
866  this.groupList.forEach(function (group) {
867  groupComponents.push(compoment ? group.getComponent() : group);
868  });
869 
870  return groupComponents;
871 };
872 
873 GroupRows.prototype.wipe = function () {
874  this.groupList.forEach(function (group) {
875  group.wipe();
876  });
877 };
878 
879 GroupRows.prototype.pullGroupListData = function (groupList) {
880  var self = this;
881  var groupListData = [];
882 
883  groupList.forEach(function (group) {
884  var groupHeader = {};
885  groupHeader.level = 0;
886  groupHeader.rowCount = 0;
887  groupHeader.headerContent = "";
888  var childData = [];
889 
890  if (group.hasSubGroups) {
891  childData = self.pullGroupListData(group.groupList);
892 
893  groupHeader.level = group.level;
894  groupHeader.rowCount = childData.length - group.groupList.length; // data length minus number of sub-headers
895  groupHeader.headerContent = group.generator(group.key, groupHeader.rowCount, group.rows, group);
896 
897  groupListData.push(groupHeader);
898  groupListData = groupListData.concat(childData);
899  } else {
900  groupHeader.level = group.level;
901  groupHeader.headerContent = group.generator(group.key, group.rows.length, group.rows, group);
902  groupHeader.rowCount = group.getRows().length;
903 
904  groupListData.push(groupHeader);
905 
906  group.getRows().forEach(function (row) {
907  groupListData.push(row.getData("data"));
908  });
909  }
910  });
911 
912  return groupListData;
913 };
914 
915 GroupRows.prototype.getGroupedData = function () {
916 
917  return this.pullGroupListData(this.groupList);
918 };
919 
920 GroupRows.prototype.getRowGroup = function (row) {
921  var match = false;
922 
923  this.groupList.forEach(function (group) {
924  var result = group.getRowGroup(row);
925 
926  if (result) {
927  match = result;
928  }
929  });
930 
931  return match;
932 };
933 
934 GroupRows.prototype.countGroups = function () {
935  return this.groupList.length;
936 };
937 
938 GroupRows.prototype.generateGroups = function (rows) {
939  var self = this,
940  oldGroups = self.groups;
941 
942  self.groups = {};
943  self.groupList = [];
944 
945  if (this.allowedValues && this.allowedValues[0]) {
946  this.allowedValues[0].forEach(function (value) {
947  self.createGroup(value, 0, oldGroups);
948  });
949 
950  rows.forEach(function (row) {
951  self.assignRowToExistingGroup(row, oldGroups);
952  });
953  } else {
954  rows.forEach(function (row) {
955  self.assignRowToGroup(row, oldGroups);
956  });
957  }
958 };
959 
960 GroupRows.prototype.createGroup = function (groupID, level, oldGroups) {
961  var groupKey = level + "_" + groupID,
962  group;
963 
964  oldGroups = oldGroups || [];
965 
966  group = new Group(this, false, level, groupID, this.groupIDLookups[0].field, this.headerGenerator[0], oldGroups[groupKey]);
967 
968  this.groups[groupKey] = group;
969  this.groupList.push(group);
970 };
971 
972 // GroupRows.prototype.assignRowToGroup = function(row, oldGroups){
973 // var groupID = this.groupIDLookups[0].func(row.getData()),
974 // groupKey = "0_" + groupID;
975 
976 // if(!this.groups[groupKey]){
977 // this.createGroup(groupID, 0, oldGroups);
978 // }
979 
980 // this.groups[groupKey].addRow(row);
981 // };
982 
983 GroupRows.prototype.assignRowToExistingGroup = function (row, oldGroups) {
984  var groupID = this.groupIDLookups[0].func(row.getData()),
985  groupKey = "0_" + groupID;
986 
987  if (this.groups[groupKey]) {
988  this.groups[groupKey].addRow(row);
989  }
990 };
991 
992 GroupRows.prototype.assignRowToGroup = function (row, oldGroups) {
993  var groupID = this.groupIDLookups[0].func(row.getData()),
994  newGroupNeeded = !this.groups["0_" + groupID];
995 
996  if (newGroupNeeded) {
997  this.createGroup(groupID, 0, oldGroups);
998  }
999 
1000  this.groups["0_" + groupID].addRow(row);
1001 
1002  return !newGroupNeeded;
1003 };
1004 
1005 GroupRows.prototype.updateGroupRows = function (force) {
1006  var self = this,
1007  output = [],
1008  oldRowCount;
1009 
1010  self.groupList.forEach(function (group) {
1011  output = output.concat(group.getHeadersAndRows());
1012  });
1013 
1014  //force update of table display
1015  if (force) {
1016 
1017  var displayIndex = self.table.rowManager.setDisplayRows(output, this.getDisplayIndex());
1018 
1019  if (displayIndex !== true) {
1020  this.setDisplayIndex(displayIndex);
1021  }
1022 
1023  self.table.rowManager.refreshActiveData("group", true, true);
1024  }
1025 
1026  return output;
1027 };
1028 
1029 GroupRows.prototype.scrollHeaders = function (left) {
1030  left = left + "px";
1031 
1032  this.groupList.forEach(function (group) {
1033  group.scrollHeader(left);
1034  });
1035 };
1036 
1037 GroupRows.prototype.removeGroup = function (group) {
1038  var groupKey = group.level + "_" + group.key,
1039  index;
1040 
1041  if (this.groups[groupKey]) {
1042  delete this.groups[groupKey];
1043 
1044  index = this.groupList.indexOf(group);
1045 
1046  if (index > -1) {
1047  this.groupList.splice(index, 1);
1048  }
1049  }
1050 };
1051 
1052 Tabulator.prototype.registerModule("groupRows", GroupRows);