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