otsdaq_utilities  v2_05_02_indev
tabulator.js
1 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2 
3 /* Tabulator v4.5.3 (c) Oliver Folkerd */
4 
5 ;(function (global, factory) {
6  if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined') {
7  module.exports = factory();
8  } else if (typeof define === 'function' && define.amd) {
9  define(factory);
10  } else {
11  global.Tabulator = factory();
12  }
13 })(this, function () {
14 
15  'use strict';
16 
17  // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
18 
19 
20  if (!Array.prototype.findIndex) {
21 
22  Object.defineProperty(Array.prototype, 'findIndex', {
23 
24  value: function value(predicate) {
25 
26  // 1. Let O be ? ToObject(this value).
27 
28 
29  if (this == null) {
30 
31  throw new TypeError('"this" is null or not defined');
32  }
33 
34  var o = Object(this);
35 
36  // 2. Let len be ? ToLength(? Get(O, "length")).
37 
38 
39  var len = o.length >>> 0;
40 
41  // 3. If IsCallable(predicate) is false, throw a TypeError exception.
42 
43 
44  if (typeof predicate !== 'function') {
45 
46  throw new TypeError('predicate must be a function');
47  }
48 
49  // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
50 
51 
52  var thisArg = arguments[1];
53 
54  // 5. Let k be 0.
55 
56 
57  var k = 0;
58 
59  // 6. Repeat, while k < len
60 
61 
62  while (k < len) {
63 
64  // a. Let Pk be ! ToString(k).
65 
66 
67  // b. Let kValue be ? Get(O, Pk).
68 
69 
70  // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
71 
72 
73  // d. If testResult is true, return k.
74 
75 
76  var kValue = o[k];
77 
78  if (predicate.call(thisArg, kValue, k, o)) {
79 
80  return k;
81  }
82 
83  // e. Increase k by 1.
84 
85 
86  k++;
87  }
88 
89  // 7. Return -1.
90 
91 
92  return -1;
93  }
94 
95  });
96  }
97 
98  // https://tc39.github.io/ecma262/#sec-array.prototype.find
99 
100 
101  if (!Array.prototype.find) {
102 
103  Object.defineProperty(Array.prototype, 'find', {
104 
105  value: function value(predicate) {
106 
107  // 1. Let O be ? ToObject(this value).
108 
109 
110  if (this == null) {
111 
112  throw new TypeError('"this" is null or not defined');
113  }
114 
115  var o = Object(this);
116 
117  // 2. Let len be ? ToLength(? Get(O, "length")).
118 
119 
120  var len = o.length >>> 0;
121 
122  // 3. If IsCallable(predicate) is false, throw a TypeError exception.
123 
124 
125  if (typeof predicate !== 'function') {
126 
127  throw new TypeError('predicate must be a function');
128  }
129 
130  // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
131 
132 
133  var thisArg = arguments[1];
134 
135  // 5. Let k be 0.
136 
137 
138  var k = 0;
139 
140  // 6. Repeat, while k < len
141 
142 
143  while (k < len) {
144 
145  // a. Let Pk be ! ToString(k).
146 
147 
148  // b. Let kValue be ? Get(O, Pk).
149 
150 
151  // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
152 
153 
154  // d. If testResult is true, return kValue.
155 
156 
157  var kValue = o[k];
158 
159  if (predicate.call(thisArg, kValue, k, o)) {
160 
161  return kValue;
162  }
163 
164  // e. Increase k by 1.
165 
166 
167  k++;
168  }
169 
170  // 7. Return undefined.
171 
172 
173  return undefined;
174  }
175 
176  });
177  }
178 
179  var ColumnManager = function ColumnManager(table) {
180 
181  this.table = table; //hold parent table
182 
183 
184  this.blockHozScrollEvent = false;
185 
186  this.headersElement = this.createHeadersElement();
187 
188  this.element = this.createHeaderElement(); //containing element
189 
190 
191  this.rowManager = null; //hold row manager object
192 
193 
194  this.columns = []; // column definition object
195 
196 
197  this.columnsByIndex = []; //columns by index
198 
199 
200  this.columnsByField = {}; //columns by field
201 
202 
203  this.scrollLeft = 0;
204 
205  this.element.insertBefore(this.headersElement, this.element.firstChild);
206  };
207 
209 
210 
211  ColumnManager.prototype.createHeadersElement = function () {
212 
213  var el = document.createElement("div");
214 
215  el.classList.add("tabulator-headers");
216 
217  return el;
218  };
219 
220  ColumnManager.prototype.createHeaderElement = function () {
221 
222  var el = document.createElement("div");
223 
224  el.classList.add("tabulator-header");
225 
226  if (!this.table.options.headerVisible) {
227 
228  el.classList.add("tabulator-header-hidden");
229  }
230 
231  return el;
232  };
233 
234  ColumnManager.prototype.initialize = function () {
235 
236  var self = this;
237 
238  //scroll body along with header
239 
240 
241  // self.element.addEventListener("scroll", function(e){
242 
243 
244  // if(!self.blockHozScrollEvent){
245 
246 
247  // self.table.rowManager.scrollHorizontal(self.element.scrollLeft);
248 
249 
250  // }
251 
252 
253  // });
254 
255  };
256 
257  //link to row manager
258 
259 
260  ColumnManager.prototype.setRowManager = function (manager) {
261 
262  this.rowManager = manager;
263  };
264 
265  //return containing element
266 
267 
268  ColumnManager.prototype.getElement = function () {
269 
270  return this.element;
271  };
272 
273  //return header containing element
274 
275 
276  ColumnManager.prototype.getHeadersElement = function () {
277 
278  return this.headersElement;
279  };
280 
281  // ColumnManager.prototype.tempScrollBlock = function(){
282 
283 
284  // clearTimeout(this.blockHozScrollEvent);
285 
286 
287  // this.blockHozScrollEvent = setTimeout(() => {this.blockHozScrollEvent = false;}, 50);
288 
289 
290  // }
291 
292 
293  //scroll horizontally to match table body
294 
295 
296  ColumnManager.prototype.scrollHorizontal = function (left) {
297 
298  var hozAdjust = 0,
299  scrollWidth = this.element.scrollWidth - this.table.element.clientWidth;
300 
301  // this.tempScrollBlock();
302 
303 
304  this.element.scrollLeft = left;
305 
306  //adjust for vertical scrollbar moving table when present
307 
308 
309  if (left > scrollWidth) {
310 
311  hozAdjust = left - scrollWidth;
312 
313  this.element.style.marginLeft = -hozAdjust + "px";
314  } else {
315 
316  this.element.style.marginLeft = 0;
317  }
318 
319  //keep frozen columns fixed in position
320 
321 
322  //this._calcFrozenColumnsPos(hozAdjust + 3);
323 
324 
325  this.scrollLeft = left;
326 
327  if (this.table.modExists("frozenColumns")) {
328 
329  this.table.modules.frozenColumns.scrollHorizontal();
330  }
331  };
332 
334 
335 
336  ColumnManager.prototype.generateColumnsFromRowData = function (data) {
337 
338  var cols = [],
339  row,
340  sorter;
341 
342  if (data && data.length) {
343 
344  row = data[0];
345 
346  for (var key in row) {
347 
348  var col = {
349 
350  field: key,
351 
352  title: key
353 
354  };
355 
356  var value = row[key];
357 
358  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
359 
360  case "undefined":
361 
362  sorter = "string";
363 
364  break;
365 
366  case "boolean":
367 
368  sorter = "boolean";
369 
370  break;
371 
372  case "object":
373 
374  if (Array.isArray(value)) {
375 
376  sorter = "array";
377  } else {
378 
379  sorter = "string";
380  }
381 
382  break;
383 
384  default:
385 
386  if (!isNaN(value) && value !== "") {
387 
388  sorter = "number";
389  } else {
390 
391  if (value.match(/((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+$/i)) {
392 
393  sorter = "alphanum";
394  } else {
395 
396  sorter = "string";
397  }
398  }
399 
400  break;
401 
402  }
403 
404  col.sorter = sorter;
405 
406  cols.push(col);
407  }
408 
409  this.table.options.columns = cols;
410 
411  this.setColumns(this.table.options.columns);
412  }
413  };
414 
415  ColumnManager.prototype.setColumns = function (cols, row) {
416 
417  var self = this;
418 
419  while (self.headersElement.firstChild) {
420  self.headersElement.removeChild(self.headersElement.firstChild);
421  }self.columns = [];
422 
423  self.columnsByIndex = [];
424 
425  self.columnsByField = {};
426 
427  //reset frozen columns
428 
429 
430  if (self.table.modExists("frozenColumns")) {
431 
432  self.table.modules.frozenColumns.reset();
433  }
434 
435  cols.forEach(function (def, i) {
436 
437  self._addColumn(def);
438  });
439 
440  self._reIndexColumns();
441 
442  if (self.table.options.responsiveLayout && self.table.modExists("responsiveLayout", true)) {
443 
444  self.table.modules.responsiveLayout.initialize();
445  }
446 
447  self.redraw(true);
448  };
449 
450  ColumnManager.prototype._addColumn = function (definition, before, nextToColumn) {
451 
452  var column = new Column(definition, this),
453  colEl = column.getElement(),
454  index = nextToColumn ? this.findColumnIndex(nextToColumn) : nextToColumn;
455 
456  if (nextToColumn && index > -1) {
457 
458  var parentIndex = this.columns.indexOf(nextToColumn.getTopColumn());
459 
460  var nextEl = nextToColumn.getElement();
461 
462  if (before) {
463 
464  this.columns.splice(parentIndex, 0, column);
465 
466  nextEl.parentNode.insertBefore(colEl, nextEl);
467  } else {
468 
469  this.columns.splice(parentIndex + 1, 0, column);
470 
471  nextEl.parentNode.insertBefore(colEl, nextEl.nextSibling);
472  }
473  } else {
474 
475  if (before) {
476 
477  this.columns.unshift(column);
478 
479  this.headersElement.insertBefore(column.getElement(), this.headersElement.firstChild);
480  } else {
481 
482  this.columns.push(column);
483 
484  this.headersElement.appendChild(column.getElement());
485  }
486 
487  column.columnRendered();
488  }
489 
490  return column;
491  };
492 
493  ColumnManager.prototype.registerColumnField = function (col) {
494 
495  if (col.definition.field) {
496 
497  this.columnsByField[col.definition.field] = col;
498  }
499  };
500 
501  ColumnManager.prototype.registerColumnPosition = function (col) {
502 
503  this.columnsByIndex.push(col);
504  };
505 
506  ColumnManager.prototype._reIndexColumns = function () {
507 
508  this.columnsByIndex = [];
509 
510  this.columns.forEach(function (column) {
511 
512  column.reRegisterPosition();
513  });
514  };
515 
516  //ensure column headers take up the correct amount of space in column groups
517 
518 
519  ColumnManager.prototype._verticalAlignHeaders = function () {
520 
521  var self = this,
522  minHeight = 0;
523 
524  self.columns.forEach(function (column) {
525 
526  var height;
527 
528  column.clearVerticalAlign();
529 
530  height = column.getHeight();
531 
532  if (height > minHeight) {
533 
534  minHeight = height;
535  }
536  });
537 
538  self.columns.forEach(function (column) {
539 
540  column.verticalAlign(self.table.options.columnHeaderVertAlign, minHeight);
541  });
542 
543  self.rowManager.adjustTableSize();
544  };
545 
547 
548 
549  ColumnManager.prototype.findColumn = function (subject) {
550 
551  var self = this;
552 
553  if ((typeof subject === 'undefined' ? 'undefined' : _typeof(subject)) == "object") {
554 
555  if (subject instanceof Column) {
556 
557  //subject is column element
558 
559 
560  return subject;
561  } else if (subject instanceof ColumnComponent) {
562 
563  //subject is public column component
564 
565 
566  return subject._getSelf() || false;
567  } else if (typeof HTMLElement !== "undefined" && subject instanceof HTMLElement) {
568 
569  //subject is a HTML element of the column header
570 
571 
572  var match = self.columns.find(function (column) {
573 
574  return column.element === subject;
575  });
576 
577  return match || false;
578  }
579  } else {
580 
581  //subject should be treated as the field name of the column
582 
583 
584  return this.columnsByField[subject] || false;
585  }
586 
587  //catch all for any other type of input
588 
589 
590  return false;
591  };
592 
593  ColumnManager.prototype.getColumnByField = function (field) {
594 
595  return this.columnsByField[field];
596  };
597 
598  ColumnManager.prototype.getColumnsByFieldRoot = function (root) {
599  var _this = this;
600 
601  var matches = [];
602 
603  Object.keys(this.columnsByField).forEach(function (field) {
604 
605  var fieldRoot = field.split(".")[0];
606 
607  if (fieldRoot === root) {
608 
609  matches.push(_this.columnsByField[field]);
610  }
611  });
612 
613  return matches;
614  };
615 
616  ColumnManager.prototype.getColumnByIndex = function (index) {
617 
618  return this.columnsByIndex[index];
619  };
620 
621  ColumnManager.prototype.getFirstVisibileColumn = function (index) {
622 
623  var index = this.columnsByIndex.findIndex(function (col) {
624 
625  return col.visible;
626  });
627 
628  return index > -1 ? this.columnsByIndex[index] : false;
629  };
630 
631  ColumnManager.prototype.getColumns = function () {
632 
633  return this.columns;
634  };
635 
636  ColumnManager.prototype.findColumnIndex = function (column) {
637 
638  return this.columnsByIndex.findIndex(function (col) {
639 
640  return column === col;
641  });
642  };
643 
644  //return all columns that are not groups
645 
646 
647  ColumnManager.prototype.getRealColumns = function () {
648 
649  return this.columnsByIndex;
650  };
651 
652  //travers across columns and call action
653 
654 
655  ColumnManager.prototype.traverse = function (callback) {
656 
657  var self = this;
658 
659  self.columnsByIndex.forEach(function (column, i) {
660 
661  callback(column, i);
662  });
663  };
664 
665  //get defintions of actual columns
666 
667 
668  ColumnManager.prototype.getDefinitions = function (active) {
669 
670  var self = this,
671  output = [];
672 
673  self.columnsByIndex.forEach(function (column) {
674 
675  if (!active || active && column.visible) {
676 
677  output.push(column.getDefinition());
678  }
679  });
680 
681  return output;
682  };
683 
684  //get full nested definition tree
685 
686 
687  ColumnManager.prototype.getDefinitionTree = function () {
688 
689  var self = this,
690  output = [];
691 
692  self.columns.forEach(function (column) {
693 
694  output.push(column.getDefinition(true));
695  });
696 
697  return output;
698  };
699 
700  ColumnManager.prototype.getComponents = function (structured) {
701 
702  var self = this,
703  output = [],
704  columns = structured ? self.columns : self.columnsByIndex;
705 
706  columns.forEach(function (column) {
707 
708  output.push(column.getComponent());
709  });
710 
711  return output;
712  };
713 
714  ColumnManager.prototype.getWidth = function () {
715 
716  var width = 0;
717 
718  this.columnsByIndex.forEach(function (column) {
719 
720  if (column.visible) {
721 
722  width += column.getWidth();
723  }
724  });
725 
726  return width;
727  };
728 
729  ColumnManager.prototype.moveColumn = function (from, to, after) {
730 
731  this.moveColumnActual(from, to, after);
732 
733  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
734 
735  this.table.modules.responsiveLayout.initialize();
736  }
737 
738  if (this.table.modExists("columnCalcs")) {
739 
740  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
741  }
742 
743  to.element.parentNode.insertBefore(from.element, to.element);
744 
745  if (after) {
746 
747  to.element.parentNode.insertBefore(to.element, from.element);
748  }
749 
750  this._verticalAlignHeaders();
751 
752  this.table.rowManager.reinitialize();
753  };
754 
755  ColumnManager.prototype.moveColumnActual = function (from, to, after) {
756 
757  this._moveColumnInArray(this.columns, from, to, after);
758 
759  this._moveColumnInArray(this.columnsByIndex, from, to, after, true);
760 
761  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
762 
763  this.table.modules.responsiveLayout.initialize();
764  }
765 
766  if (this.table.options.columnMoved) {
767 
768  this.table.options.columnMoved.call(this.table, from.getComponent(), this.table.columnManager.getComponents());
769  }
770 
771  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
772 
773  this.table.modules.persistence.save("columns");
774  }
775  };
776 
777  ColumnManager.prototype._moveColumnInArray = function (columns, from, to, after, updateRows) {
778 
779  var fromIndex = columns.indexOf(from),
780  toIndex;
781 
782  if (fromIndex > -1) {
783 
784  columns.splice(fromIndex, 1);
785 
786  toIndex = columns.indexOf(to);
787 
788  if (toIndex > -1) {
789 
790  if (after) {
791 
792  toIndex = toIndex + 1;
793  }
794  } else {
795 
796  toIndex = fromIndex;
797  }
798 
799  columns.splice(toIndex, 0, from);
800 
801  if (updateRows) {
802 
803  this.table.rowManager.rows.forEach(function (row) {
804 
805  if (row.cells.length) {
806 
807  var cell = row.cells.splice(fromIndex, 1)[0];
808 
809  row.cells.splice(toIndex, 0, cell);
810  }
811  });
812  }
813  }
814  };
815 
816  ColumnManager.prototype.scrollToColumn = function (column, position, ifVisible) {
817  var _this2 = this;
818 
819  var left = 0,
820  offset = 0,
821  adjust = 0,
822  colEl = column.getElement();
823 
824  return new Promise(function (resolve, reject) {
825 
826  if (typeof position === "undefined") {
827 
828  position = _this2.table.options.scrollToColumnPosition;
829  }
830 
831  if (typeof ifVisible === "undefined") {
832 
833  ifVisible = _this2.table.options.scrollToColumnIfVisible;
834  }
835 
836  if (column.visible) {
837 
838  //align to correct position
839 
840 
841  switch (position) {
842 
843  case "middle":
844 
845  case "center":
846 
847  adjust = -_this2.element.clientWidth / 2;
848 
849  break;
850 
851  case "right":
852 
853  adjust = colEl.clientWidth - _this2.headersElement.clientWidth;
854 
855  break;
856 
857  }
858 
859  //check column visibility
860 
861 
862  if (!ifVisible) {
863 
864  offset = colEl.offsetLeft;
865 
866  if (offset > 0 && offset + colEl.offsetWidth < _this2.element.clientWidth) {
867 
868  return false;
869  }
870  }
871 
872  //calculate scroll position
873 
874 
875  left = colEl.offsetLeft + _this2.element.scrollLeft + adjust;
876 
877  left = Math.max(Math.min(left, _this2.table.rowManager.element.scrollWidth - _this2.table.rowManager.element.clientWidth), 0);
878 
879  _this2.table.rowManager.scrollHorizontal(left);
880 
881  _this2.scrollHorizontal(left);
882 
883  resolve();
884  } else {
885 
886  console.warn("Scroll Error - Column not visible");
887 
888  reject("Scroll Error - Column not visible");
889  }
890  });
891  };
892 
894 
895 
896  ColumnManager.prototype.generateCells = function (row) {
897 
898  var self = this;
899 
900  var cells = [];
901 
902  self.columnsByIndex.forEach(function (column) {
903 
904  cells.push(column.generateCell(row));
905  });
906 
907  return cells;
908  };
909 
911 
912 
913  ColumnManager.prototype.getFlexBaseWidth = function () {
914 
915  var self = this,
916  totalWidth = self.table.element.clientWidth,
917  //table element width
918 
919 
920  fixedWidth = 0;
921 
922  //adjust for vertical scrollbar if present
923 
924 
925  if (self.rowManager.element.scrollHeight > self.rowManager.element.clientHeight) {
926 
927  totalWidth -= self.rowManager.element.offsetWidth - self.rowManager.element.clientWidth;
928  }
929 
930  this.columnsByIndex.forEach(function (column) {
931 
932  var width, minWidth, colWidth;
933 
934  if (column.visible) {
935 
936  width = column.definition.width || 0;
937 
938  minWidth = typeof column.minWidth == "undefined" ? self.table.options.columnMinWidth : parseInt(column.minWidth);
939 
940  if (typeof width == "string") {
941 
942  if (width.indexOf("%") > -1) {
943 
944  colWidth = totalWidth / 100 * parseInt(width);
945  } else {
946 
947  colWidth = parseInt(width);
948  }
949  } else {
950 
951  colWidth = width;
952  }
953 
954  fixedWidth += colWidth > minWidth ? colWidth : minWidth;
955  }
956  });
957 
958  return fixedWidth;
959  };
960 
961  ColumnManager.prototype.addColumn = function (definition, before, nextToColumn) {
962  var _this3 = this;
963 
964  return new Promise(function (resolve, reject) {
965 
966  var column = _this3._addColumn(definition, before, nextToColumn);
967 
968  _this3._reIndexColumns();
969 
970  if (_this3.table.options.responsiveLayout && _this3.table.modExists("responsiveLayout", true)) {
971 
972  _this3.table.modules.responsiveLayout.initialize();
973  }
974 
975  if (_this3.table.modExists("columnCalcs")) {
976 
977  _this3.table.modules.columnCalcs.recalc(_this3.table.rowManager.activeRows);
978  }
979 
980  _this3.redraw();
981 
982  if (_this3.table.modules.layout.getMode() != "fitColumns") {
983 
984  column.reinitializeWidth();
985  }
986 
987  _this3._verticalAlignHeaders();
988 
989  _this3.table.rowManager.reinitialize();
990 
991  resolve(column);
992  });
993  };
994 
995  //remove column from system
996 
997 
998  ColumnManager.prototype.deregisterColumn = function (column) {
999 
1000  var field = column.getField(),
1001  index;
1002 
1003  //remove from field list
1004 
1005 
1006  if (field) {
1007 
1008  delete this.columnsByField[field];
1009  }
1010 
1011  //remove from index list
1012 
1013 
1014  index = this.columnsByIndex.indexOf(column);
1015 
1016  if (index > -1) {
1017 
1018  this.columnsByIndex.splice(index, 1);
1019  }
1020 
1021  //remove from column list
1022 
1023 
1024  index = this.columns.indexOf(column);
1025 
1026  if (index > -1) {
1027 
1028  this.columns.splice(index, 1);
1029  }
1030 
1031  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
1032 
1033  this.table.modules.responsiveLayout.initialize();
1034  }
1035 
1036  this.redraw();
1037  };
1038 
1039  //redraw columns
1040 
1041 
1042  ColumnManager.prototype.redraw = function (force) {
1043 
1044  if (force) {
1045 
1046  if (Tabulator.prototype.helpers.elVisible(this.element)) {
1047 
1048  this._verticalAlignHeaders();
1049  }
1050 
1051  this.table.rowManager.resetScroll();
1052 
1053  this.table.rowManager.reinitialize();
1054  }
1055 
1056  if (["fitColumns", "fitDataStretch"].indexOf(this.table.modules.layout.getMode()) > -1) {
1057 
1058  this.table.modules.layout.layout();
1059  } else {
1060 
1061  if (force) {
1062 
1063  this.table.modules.layout.layout();
1064  } else {
1065 
1066  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
1067 
1068  this.table.modules.responsiveLayout.update();
1069  }
1070  }
1071  }
1072 
1073  if (this.table.modExists("frozenColumns")) {
1074 
1075  this.table.modules.frozenColumns.layout();
1076  }
1077 
1078  if (this.table.modExists("columnCalcs")) {
1079 
1080  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
1081  }
1082 
1083  if (force) {
1084 
1085  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
1086 
1087  this.table.modules.persistence.save("columns");
1088  }
1089 
1090  if (this.table.modExists("columnCalcs")) {
1091 
1092  this.table.modules.columnCalcs.redraw();
1093  }
1094  }
1095 
1096  this.table.footerManager.redraw();
1097  };
1098 
1099  //public column object
1100 
1101  var ColumnComponent = function ColumnComponent(column) {
1102 
1103  this._column = column;
1104 
1105  this.type = "ColumnComponent";
1106  };
1107 
1108  ColumnComponent.prototype.getElement = function () {
1109 
1110  return this._column.getElement();
1111  };
1112 
1113  ColumnComponent.prototype.getDefinition = function () {
1114 
1115  return this._column.getDefinition();
1116  };
1117 
1118  ColumnComponent.prototype.getField = function () {
1119 
1120  return this._column.getField();
1121  };
1122 
1123  ColumnComponent.prototype.getCells = function () {
1124 
1125  var cells = [];
1126 
1127  this._column.cells.forEach(function (cell) {
1128 
1129  cells.push(cell.getComponent());
1130  });
1131 
1132  return cells;
1133  };
1134 
1135  ColumnComponent.prototype.getVisibility = function () {
1136 
1137  return this._column.visible;
1138  };
1139 
1140  ColumnComponent.prototype.show = function () {
1141 
1142  if (this._column.isGroup) {
1143 
1144  this._column.columns.forEach(function (column) {
1145 
1146  column.show();
1147  });
1148  } else {
1149 
1150  this._column.show();
1151  }
1152  };
1153 
1154  ColumnComponent.prototype.hide = function () {
1155 
1156  if (this._column.isGroup) {
1157 
1158  this._column.columns.forEach(function (column) {
1159 
1160  column.hide();
1161  });
1162  } else {
1163 
1164  this._column.hide();
1165  }
1166  };
1167 
1168  ColumnComponent.prototype.toggle = function () {
1169 
1170  if (this._column.visible) {
1171 
1172  this.hide();
1173  } else {
1174 
1175  this.show();
1176  }
1177  };
1178 
1179  ColumnComponent.prototype.delete = function () {
1180 
1181  return this._column.delete();
1182  };
1183 
1184  ColumnComponent.prototype.getSubColumns = function () {
1185 
1186  var output = [];
1187 
1188  if (this._column.columns.length) {
1189 
1190  this._column.columns.forEach(function (column) {
1191 
1192  output.push(column.getComponent());
1193  });
1194  }
1195 
1196  return output;
1197  };
1198 
1199  ColumnComponent.prototype.getParentColumn = function () {
1200 
1201  return this._column.parent instanceof Column ? this._column.parent.getComponent() : false;
1202  };
1203 
1204  ColumnComponent.prototype._getSelf = function () {
1205 
1206  return this._column;
1207  };
1208 
1209  ColumnComponent.prototype.scrollTo = function () {
1210 
1211  return this._column.table.columnManager.scrollToColumn(this._column);
1212  };
1213 
1214  ColumnComponent.prototype.getTable = function () {
1215 
1216  return this._column.table;
1217  };
1218 
1219  ColumnComponent.prototype.headerFilterFocus = function () {
1220 
1221  if (this._column.table.modExists("filter", true)) {
1222 
1223  this._column.table.modules.filter.setHeaderFilterFocus(this._column);
1224  }
1225  };
1226 
1227  ColumnComponent.prototype.reloadHeaderFilter = function () {
1228 
1229  if (this._column.table.modExists("filter", true)) {
1230 
1231  this._column.table.modules.filter.reloadHeaderFilter(this._column);
1232  }
1233  };
1234 
1235  ColumnComponent.prototype.setHeaderFilterValue = function (value) {
1236 
1237  if (this._column.table.modExists("filter", true)) {
1238 
1239  this._column.table.modules.filter.setHeaderFilterValue(this._column, value);
1240  }
1241  };
1242 
1243  ColumnComponent.prototype.move = function (to, after) {
1244 
1245  var toColumn = this._column.table.columnManager.findColumn(to);
1246 
1247  if (toColumn) {
1248 
1249  this._column.table.columnManager.moveColumn(this._column, toColumn, after);
1250  } else {
1251 
1252  console.warn("Move Error - No matching column found:", toColumn);
1253  }
1254  };
1255 
1256  ColumnComponent.prototype.getNextColumn = function () {
1257 
1258  var nextCol = this._column.nextColumn();
1259 
1260  return nextCol ? nextCol.getComponent() : false;
1261  };
1262 
1263  ColumnComponent.prototype.getPrevColumn = function () {
1264 
1265  var prevCol = this._column.prevColumn();
1266 
1267  return prevCol ? prevCol.getComponent() : false;
1268  };
1269 
1270  ColumnComponent.prototype.updateDefinition = function (updates) {
1271 
1272  return this._column.updateDefinition(updates);
1273  };
1274 
1275  var Column = function Column(def, parent) {
1276 
1277  var self = this;
1278 
1279  this.table = parent.table;
1280 
1281  this.definition = def; //column definition
1282 
1283  this.parent = parent; //hold parent object
1284 
1285  this.type = "column"; //type of element
1286 
1287  this.columns = []; //child columns
1288 
1289  this.cells = []; //cells bound to this column
1290 
1291  this.element = this.createElement(); //column header element
1292 
1293  this.contentElement = false;
1294 
1295  this.groupElement = this.createGroupElement(); //column group holder element
1296 
1297  this.isGroup = false;
1298 
1299  this.tooltip = false; //hold column tooltip
1300 
1301  this.hozAlign = ""; //horizontal text alignment
1302 
1303 
1304  //multi dimensional filed handling
1305 
1306  this.field = "";
1307 
1308  this.fieldStructure = "";
1309 
1310  this.getFieldValue = "";
1311 
1312  this.setFieldValue = "";
1313 
1314  this.titleFormatterRendered = false;
1315 
1316  this.setField(this.definition.field);
1317 
1318  if (this.table.options.invalidOptionWarnings) {
1319 
1320  this.checkDefinition();
1321  }
1322 
1323  this.modules = {}; //hold module variables;
1324 
1325 
1326  this.cellEvents = {
1327 
1328  cellClick: false,
1329 
1330  cellDblClick: false,
1331 
1332  cellContext: false,
1333 
1334  cellTap: false,
1335 
1336  cellDblTap: false,
1337 
1338  cellTapHold: false,
1339 
1340  cellMouseEnter: false,
1341 
1342  cellMouseLeave: false,
1343 
1344  cellMouseOver: false,
1345 
1346  cellMouseOut: false,
1347 
1348  cellMouseMove: false
1349 
1350  };
1351 
1352  this.width = null; //column width
1353 
1354  this.widthStyled = ""; //column width prestyled to improve render efficiency
1355 
1356  this.minWidth = null; //column minimum width
1357 
1358  this.minWidthStyled = ""; //column minimum prestyled to improve render efficiency
1359 
1360  this.widthFixed = false; //user has specified a width for this column
1361 
1362 
1363  this.visible = true; //default visible state
1364 
1365 
1366  this._mapDepricatedFunctionality();
1367 
1368  //initialize column
1369 
1370  if (def.columns) {
1371 
1372  this.isGroup = true;
1373 
1374  def.columns.forEach(function (def, i) {
1375 
1376  var newCol = new Column(def, self);
1377 
1378  self.attachColumn(newCol);
1379  });
1380 
1381  self.checkColumnVisibility();
1382  } else {
1383 
1384  parent.registerColumnField(this);
1385  }
1386 
1387  if (def.rowHandle && this.table.options.movableRows !== false && this.table.modExists("moveRow")) {
1388 
1389  this.table.modules.moveRow.setHandle(true);
1390  }
1391 
1392  this._buildHeader();
1393 
1394  this.bindModuleColumns();
1395  };
1396 
1397  Column.prototype.createElement = function () {
1398 
1399  var el = document.createElement("div");
1400 
1401  el.classList.add("tabulator-col");
1402 
1403  el.setAttribute("role", "columnheader");
1404 
1405  el.setAttribute("aria-sort", "none");
1406 
1407  return el;
1408  };
1409 
1410  Column.prototype.createGroupElement = function () {
1411 
1412  var el = document.createElement("div");
1413 
1414  el.classList.add("tabulator-col-group-cols");
1415 
1416  return el;
1417  };
1418 
1419  Column.prototype.checkDefinition = function () {
1420  var _this4 = this;
1421 
1422  Object.keys(this.definition).forEach(function (key) {
1423 
1424  if (_this4.defaultOptionList.indexOf(key) === -1) {
1425 
1426  console.warn("Invalid column definition option in '" + (_this4.field || _this4.definition.title) + "' column:", key);
1427  }
1428  });
1429  };
1430 
1431  Column.prototype.setField = function (field) {
1432 
1433  this.field = field;
1434 
1435  this.fieldStructure = field ? this.table.options.nestedFieldSeparator ? field.split(this.table.options.nestedFieldSeparator) : [field] : [];
1436 
1437  this.getFieldValue = this.fieldStructure.length > 1 ? this._getNestedData : this._getFlatData;
1438 
1439  this.setFieldValue = this.fieldStructure.length > 1 ? this._setNesteData : this._setFlatData;
1440  };
1441 
1442  //register column position with column manager
1443 
1444  Column.prototype.registerColumnPosition = function (column) {
1445 
1446  this.parent.registerColumnPosition(column);
1447  };
1448 
1449  //register column position with column manager
1450 
1451  Column.prototype.registerColumnField = function (column) {
1452 
1453  this.parent.registerColumnField(column);
1454  };
1455 
1456  //trigger position registration
1457 
1458  Column.prototype.reRegisterPosition = function () {
1459 
1460  if (this.isGroup) {
1461 
1462  this.columns.forEach(function (column) {
1463 
1464  column.reRegisterPosition();
1465  });
1466  } else {
1467 
1468  this.registerColumnPosition(this);
1469  }
1470  };
1471 
1472  Column.prototype._mapDepricatedFunctionality = function () {
1473 
1474  if (typeof this.definition.hideInHtml !== "undefined") {
1475 
1476  this.definition.htmlOutput = !this.definition.hideInHtml;
1477 
1478  console.warn("hideInHtml column definition property is deprecated, you should now use htmlOutput");
1479  }
1480  };
1481 
1482  Column.prototype.setTooltip = function () {
1483 
1484  var self = this,
1485  def = self.definition;
1486 
1487  //set header tooltips
1488 
1489  var tooltip = def.headerTooltip || def.tooltip === false ? def.headerTooltip : self.table.options.tooltipsHeader;
1490 
1491  if (tooltip) {
1492 
1493  if (tooltip === true) {
1494 
1495  if (def.field) {
1496 
1497  self.table.modules.localize.bind("columns|" + def.field, function (value) {
1498 
1499  self.element.setAttribute("title", value || def.title);
1500  });
1501  } else {
1502 
1503  self.element.setAttribute("title", def.title);
1504  }
1505  } else {
1506 
1507  if (typeof tooltip == "function") {
1508 
1509  tooltip = tooltip(self.getComponent());
1510 
1511  if (tooltip === false) {
1512 
1513  tooltip = "";
1514  }
1515  }
1516 
1517  self.element.setAttribute("title", tooltip);
1518  }
1519  } else {
1520 
1521  self.element.setAttribute("title", "");
1522  }
1523  };
1524 
1525  //build header element
1526 
1527  Column.prototype._buildHeader = function () {
1528 
1529  var self = this,
1530  def = self.definition;
1531 
1532  while (self.element.firstChild) {
1533  self.element.removeChild(self.element.firstChild);
1534  }if (def.headerVertical) {
1535 
1536  self.element.classList.add("tabulator-col-vertical");
1537 
1538  if (def.headerVertical === "flip") {
1539 
1540  self.element.classList.add("tabulator-col-vertical-flip");
1541  }
1542  }
1543 
1544  self.contentElement = self._bindEvents();
1545 
1546  self.contentElement = self._buildColumnHeaderContent();
1547 
1548  self.element.appendChild(self.contentElement);
1549 
1550  if (self.isGroup) {
1551 
1552  self._buildGroupHeader();
1553  } else {
1554 
1555  self._buildColumnHeader();
1556  }
1557 
1558  self.setTooltip();
1559 
1560  //set resizable handles
1561 
1562  if (self.table.options.resizableColumns && self.table.modExists("resizeColumns")) {
1563 
1564  self.table.modules.resizeColumns.initializeColumn("header", self, self.element);
1565  }
1566 
1567  //set resizable handles
1568 
1569  if (def.headerFilter && self.table.modExists("filter") && self.table.modExists("edit")) {
1570 
1571  if (typeof def.headerFilterPlaceholder !== "undefined" && def.field) {
1572 
1573  self.table.modules.localize.setHeaderFilterColumnPlaceholder(def.field, def.headerFilterPlaceholder);
1574  }
1575 
1576  self.table.modules.filter.initializeColumn(self);
1577  }
1578 
1579  //set resizable handles
1580 
1581  if (self.table.modExists("frozenColumns")) {
1582 
1583  self.table.modules.frozenColumns.initializeColumn(self);
1584  }
1585 
1586  //set movable column
1587 
1588  if (self.table.options.movableColumns && !self.isGroup && self.table.modExists("moveColumn")) {
1589 
1590  self.table.modules.moveColumn.initializeColumn(self);
1591  }
1592 
1593  //set calcs column
1594 
1595  if ((def.topCalc || def.bottomCalc) && self.table.modExists("columnCalcs")) {
1596 
1597  self.table.modules.columnCalcs.initializeColumn(self);
1598  }
1599 
1600  //handle persistence
1601 
1602  if (self.table.modExists("persistence") && self.table.modules.persistence.config.columns) {
1603 
1604  self.table.modules.persistence.initializeColumn(self);
1605  }
1606 
1607  //update header tooltip on mouse enter
1608 
1609  self.element.addEventListener("mouseenter", function (e) {
1610 
1611  self.setTooltip();
1612  });
1613  };
1614 
1615  Column.prototype._bindEvents = function () {
1616 
1617  var self = this,
1618  def = self.definition,
1619  dblTap,
1620  tapHold,
1621  tap;
1622 
1623  //setup header click event bindings
1624 
1625  if (typeof def.headerClick == "function") {
1626 
1627  self.element.addEventListener("click", function (e) {
1628  def.headerClick(e, self.getComponent());
1629  });
1630  }
1631 
1632  if (typeof def.headerDblClick == "function") {
1633 
1634  self.element.addEventListener("dblclick", function (e) {
1635  def.headerDblClick(e, self.getComponent());
1636  });
1637  }
1638 
1639  if (typeof def.headerContext == "function") {
1640 
1641  self.element.addEventListener("contextmenu", function (e) {
1642  def.headerContext(e, self.getComponent());
1643  });
1644  }
1645 
1646  //setup header tap event bindings
1647 
1648  if (typeof def.headerTap == "function") {
1649 
1650  tap = false;
1651 
1652  self.element.addEventListener("touchstart", function (e) {
1653 
1654  tap = true;
1655  }, { passive: true });
1656 
1657  self.element.addEventListener("touchend", function (e) {
1658 
1659  if (tap) {
1660 
1661  def.headerTap(e, self.getComponent());
1662  }
1663 
1664  tap = false;
1665  });
1666  }
1667 
1668  if (typeof def.headerDblTap == "function") {
1669 
1670  dblTap = null;
1671 
1672  self.element.addEventListener("touchend", function (e) {
1673 
1674  if (dblTap) {
1675 
1676  clearTimeout(dblTap);
1677 
1678  dblTap = null;
1679 
1680  def.headerDblTap(e, self.getComponent());
1681  } else {
1682 
1683  dblTap = setTimeout(function () {
1684 
1685  clearTimeout(dblTap);
1686 
1687  dblTap = null;
1688  }, 300);
1689  }
1690  });
1691  }
1692 
1693  if (typeof def.headerTapHold == "function") {
1694 
1695  tapHold = null;
1696 
1697  self.element.addEventListener("touchstart", function (e) {
1698 
1699  clearTimeout(tapHold);
1700 
1701  tapHold = setTimeout(function () {
1702 
1703  clearTimeout(tapHold);
1704 
1705  tapHold = null;
1706 
1707  tap = false;
1708 
1709  def.headerTapHold(e, self.getComponent());
1710  }, 1000);
1711  }, { passive: true });
1712 
1713  self.element.addEventListener("touchend", function (e) {
1714 
1715  clearTimeout(tapHold);
1716 
1717  tapHold = null;
1718  });
1719  }
1720 
1721  //store column cell click event bindings
1722 
1723  if (typeof def.cellClick == "function") {
1724 
1725  self.cellEvents.cellClick = def.cellClick;
1726  }
1727 
1728  if (typeof def.cellDblClick == "function") {
1729 
1730  self.cellEvents.cellDblClick = def.cellDblClick;
1731  }
1732 
1733  if (typeof def.cellContext == "function") {
1734 
1735  self.cellEvents.cellContext = def.cellContext;
1736  }
1737 
1738  //store column mouse event bindings
1739 
1740  if (typeof def.cellMouseEnter == "function") {
1741 
1742  self.cellEvents.cellMouseEnter = def.cellMouseEnter;
1743  }
1744 
1745  if (typeof def.cellMouseLeave == "function") {
1746 
1747  self.cellEvents.cellMouseLeave = def.cellMouseLeave;
1748  }
1749 
1750  if (typeof def.cellMouseOver == "function") {
1751 
1752  self.cellEvents.cellMouseOver = def.cellMouseOver;
1753  }
1754 
1755  if (typeof def.cellMouseOut == "function") {
1756 
1757  self.cellEvents.cellMouseOut = def.cellMouseOut;
1758  }
1759 
1760  if (typeof def.cellMouseMove == "function") {
1761 
1762  self.cellEvents.cellMouseMove = def.cellMouseMove;
1763  }
1764 
1765  //setup column cell tap event bindings
1766 
1767  if (typeof def.cellTap == "function") {
1768 
1769  self.cellEvents.cellTap = def.cellTap;
1770  }
1771 
1772  if (typeof def.cellDblTap == "function") {
1773 
1774  self.cellEvents.cellDblTap = def.cellDblTap;
1775  }
1776 
1777  if (typeof def.cellTapHold == "function") {
1778 
1779  self.cellEvents.cellTapHold = def.cellTapHold;
1780  }
1781 
1782  //setup column cell edit callbacks
1783 
1784  if (typeof def.cellEdited == "function") {
1785 
1786  self.cellEvents.cellEdited = def.cellEdited;
1787  }
1788 
1789  if (typeof def.cellEditing == "function") {
1790 
1791  self.cellEvents.cellEditing = def.cellEditing;
1792  }
1793 
1794  if (typeof def.cellEditCancelled == "function") {
1795 
1796  self.cellEvents.cellEditCancelled = def.cellEditCancelled;
1797  }
1798  };
1799 
1800  //build header element for header
1801 
1802  Column.prototype._buildColumnHeader = function () {
1803 
1804  var self = this,
1805  def = self.definition,
1806  table = self.table,
1807  sortable;
1808 
1809  //set column sorter
1810 
1811  if (table.modExists("sort")) {
1812 
1813  table.modules.sort.initializeColumn(self, self.contentElement);
1814  }
1815 
1816  //set column formatter
1817 
1818  if (table.modExists("format")) {
1819 
1820  table.modules.format.initializeColumn(self);
1821  }
1822 
1823  //set column editor
1824 
1825  if (typeof def.editor != "undefined" && table.modExists("edit")) {
1826 
1827  table.modules.edit.initializeColumn(self);
1828  }
1829 
1830  //set colum validator
1831 
1832  if (typeof def.validator != "undefined" && table.modExists("validate")) {
1833 
1834  table.modules.validate.initializeColumn(self);
1835  }
1836 
1837  //set column mutator
1838 
1839  if (table.modExists("mutator")) {
1840 
1841  table.modules.mutator.initializeColumn(self);
1842  }
1843 
1844  //set column accessor
1845 
1846  if (table.modExists("accessor")) {
1847 
1848  table.modules.accessor.initializeColumn(self);
1849  }
1850 
1851  //set respoviveLayout
1852 
1853  if (_typeof(table.options.responsiveLayout) && table.modExists("responsiveLayout")) {
1854 
1855  table.modules.responsiveLayout.initializeColumn(self);
1856  }
1857 
1858  //set column visibility
1859 
1860  if (typeof def.visible != "undefined") {
1861 
1862  if (def.visible) {
1863 
1864  self.show(true);
1865  } else {
1866 
1867  self.hide(true);
1868  }
1869  }
1870 
1871  //asign additional css classes to column header
1872 
1873  if (def.cssClass) {
1874 
1875  var classeNames = def.cssClass.split(" ");
1876 
1877  classeNames.forEach(function (className) {
1878 
1879  self.element.classList.add(className);
1880  });
1881  }
1882 
1883  if (def.field) {
1884 
1885  this.element.setAttribute("tabulator-field", def.field);
1886  }
1887 
1888  //set min width if present
1889 
1890  self.setMinWidth(typeof def.minWidth == "undefined" ? self.table.options.columnMinWidth : parseInt(def.minWidth));
1891 
1892  self.reinitializeWidth();
1893 
1894  //set tooltip if present
1895 
1896  self.tooltip = self.definition.tooltip || self.definition.tooltip === false ? self.definition.tooltip : self.table.options.tooltips;
1897 
1898  //set orizontal text alignment
1899 
1900  self.hozAlign = typeof self.definition.align == "undefined" ? "" : self.definition.align;
1901  };
1902 
1903  Column.prototype._buildColumnHeaderContent = function () {
1904 
1905  var self = this,
1906  def = self.definition,
1907  table = self.table;
1908 
1909  var contentElement = document.createElement("div");
1910 
1911  contentElement.classList.add("tabulator-col-content");
1912 
1913  contentElement.appendChild(self._buildColumnHeaderTitle());
1914 
1915  return contentElement;
1916  };
1917 
1918  //build title element of column
1919 
1920  Column.prototype._buildColumnHeaderTitle = function () {
1921 
1922  var self = this,
1923  def = self.definition,
1924  table = self.table,
1925  title;
1926 
1927  var titleHolderElement = document.createElement("div");
1928 
1929  titleHolderElement.classList.add("tabulator-col-title");
1930 
1931  if (def.editableTitle) {
1932 
1933  var titleElement = document.createElement("input");
1934 
1935  titleElement.classList.add("tabulator-title-editor");
1936 
1937  titleElement.addEventListener("click", function (e) {
1938 
1939  e.stopPropagation();
1940 
1941  titleElement.focus();
1942  });
1943 
1944  titleElement.addEventListener("change", function () {
1945 
1946  def.title = titleElement.value;
1947 
1948  table.options.columnTitleChanged.call(self.table, self.getComponent());
1949  });
1950 
1951  titleHolderElement.appendChild(titleElement);
1952 
1953  if (def.field) {
1954 
1955  table.modules.localize.bind("columns|" + def.field, function (text) {
1956 
1957  titleElement.value = text || def.title || "&nbsp;";
1958  });
1959  } else {
1960 
1961  titleElement.value = def.title || "&nbsp;";
1962  }
1963  } else {
1964 
1965  if (def.field) {
1966 
1967  table.modules.localize.bind("columns|" + def.field, function (text) {
1968 
1969  self._formatColumnHeaderTitle(titleHolderElement, text || def.title || "&nbsp;");
1970  });
1971  } else {
1972 
1973  self._formatColumnHeaderTitle(titleHolderElement, def.title || "&nbsp;");
1974  }
1975  }
1976 
1977  return titleHolderElement;
1978  };
1979 
1980  Column.prototype._formatColumnHeaderTitle = function (el, title) {
1981  var _this5 = this;
1982 
1983  var formatter, contents, params, mockCell, onRendered;
1984 
1985  if (this.definition.titleFormatter && this.table.modExists("format")) {
1986 
1987  formatter = this.table.modules.format.getFormatter(this.definition.titleFormatter);
1988 
1989  onRendered = function onRendered(callback) {
1990 
1991  _this5.titleFormatterRendered = callback;
1992  };
1993 
1994  mockCell = {
1995 
1996  getValue: function getValue() {
1997 
1998  return title;
1999  },
2000 
2001  getElement: function getElement() {
2002 
2003  return el;
2004  }
2005 
2006  };
2007 
2008  params = this.definition.titleFormatterParams || {};
2009 
2010  params = typeof params === "function" ? params() : params;
2011 
2012  contents = formatter.call(this.table.modules.format, mockCell, params, onRendered);
2013 
2014  switch (typeof contents === 'undefined' ? 'undefined' : _typeof(contents)) {
2015 
2016  case "object":
2017 
2018  if (contents instanceof Node) {
2019 
2020  el.appendChild(contents);
2021  } else {
2022 
2023  el.innerHTML = "";
2024 
2025  console.warn("Format Error - Title formatter has returned a type of object, the only valid formatter object return is an instance of Node, the formatter returned:", contents);
2026  }
2027 
2028  break;
2029 
2030  case "undefined":
2031 
2032  case "null":
2033 
2034  el.innerHTML = "";
2035 
2036  break;
2037 
2038  default:
2039 
2040  el.innerHTML = contents;
2041 
2042  }
2043  } else {
2044 
2045  el.innerHTML = title;
2046  }
2047  };
2048 
2049  //build header element for column group
2050 
2051  Column.prototype._buildGroupHeader = function () {
2052  var _this6 = this;
2053 
2054  this.element.classList.add("tabulator-col-group");
2055 
2056  this.element.setAttribute("role", "columngroup");
2057 
2058  this.element.setAttribute("aria-title", this.definition.title);
2059 
2060  //asign additional css classes to column header
2061 
2062  if (this.definition.cssClass) {
2063 
2064  var classeNames = this.definition.cssClass.split(" ");
2065 
2066  classeNames.forEach(function (className) {
2067 
2068  _this6.element.classList.add(className);
2069  });
2070  }
2071 
2072  this.element.appendChild(this.groupElement);
2073  };
2074 
2075  //flat field lookup
2076 
2077  Column.prototype._getFlatData = function (data) {
2078 
2079  return data[this.field];
2080  };
2081 
2082  //nested field lookup
2083 
2084  Column.prototype._getNestedData = function (data) {
2085 
2086  var dataObj = data,
2087  structure = this.fieldStructure,
2088  length = structure.length,
2089  output;
2090 
2091  for (var i = 0; i < length; i++) {
2092 
2093  dataObj = dataObj[structure[i]];
2094 
2095  output = dataObj;
2096 
2097  if (!dataObj) {
2098 
2099  break;
2100  }
2101  }
2102 
2103  return output;
2104  };
2105 
2106  //flat field set
2107 
2108  Column.prototype._setFlatData = function (data, value) {
2109 
2110  if (this.field) {
2111 
2112  data[this.field] = value;
2113  }
2114  };
2115 
2116  //nested field set
2117 
2118  Column.prototype._setNesteData = function (data, value) {
2119 
2120  var dataObj = data,
2121  structure = this.fieldStructure,
2122  length = structure.length;
2123 
2124  for (var i = 0; i < length; i++) {
2125 
2126  if (i == length - 1) {
2127 
2128  dataObj[structure[i]] = value;
2129  } else {
2130 
2131  if (!dataObj[structure[i]]) {
2132 
2133  dataObj[structure[i]] = {};
2134  }
2135 
2136  dataObj = dataObj[structure[i]];
2137  }
2138  }
2139  };
2140 
2141  //attach column to this group
2142 
2143  Column.prototype.attachColumn = function (column) {
2144 
2145  var self = this;
2146 
2147  if (self.groupElement) {
2148 
2149  self.columns.push(column);
2150 
2151  self.groupElement.appendChild(column.getElement());
2152  } else {
2153 
2154  console.warn("Column Warning - Column being attached to another column instead of column group");
2155  }
2156  };
2157 
2158  //vertically align header in column
2159 
2160  Column.prototype.verticalAlign = function (alignment, height) {
2161 
2162  //calculate height of column header and group holder element
2163 
2164  var parentHeight = this.parent.isGroup ? this.parent.getGroupElement().clientHeight : height || this.parent.getHeadersElement().clientHeight;
2165 
2166  // var parentHeight = this.parent.isGroup ? this.parent.getGroupElement().clientHeight : this.parent.getHeadersElement().clientHeight;
2167 
2168 
2169  this.element.style.height = parentHeight + "px";
2170 
2171  if (this.isGroup) {
2172 
2173  this.groupElement.style.minHeight = parentHeight - this.contentElement.offsetHeight + "px";
2174  }
2175 
2176  //vertically align cell contents
2177 
2178  if (!this.isGroup && alignment !== "top") {
2179 
2180  if (alignment === "bottom") {
2181 
2182  this.element.style.paddingTop = this.element.clientHeight - this.contentElement.offsetHeight + "px";
2183  } else {
2184 
2185  this.element.style.paddingTop = (this.element.clientHeight - this.contentElement.offsetHeight) / 2 + "px";
2186  }
2187  }
2188 
2189  this.columns.forEach(function (column) {
2190 
2191  column.verticalAlign(alignment);
2192  });
2193  };
2194 
2195  //clear vertical alignmenet
2196 
2197  Column.prototype.clearVerticalAlign = function () {
2198 
2199  this.element.style.paddingTop = "";
2200 
2201  this.element.style.height = "";
2202 
2203  this.element.style.minHeight = "";
2204 
2205  this.groupElement.style.minHeight = "";
2206 
2207  this.columns.forEach(function (column) {
2208 
2209  column.clearVerticalAlign();
2210  });
2211  };
2212 
2213  Column.prototype.bindModuleColumns = function () {
2214 
2215  //check if rownum formatter is being used on a column
2216 
2217  if (this.definition.formatter == "rownum") {
2218 
2219  this.table.rowManager.rowNumColumn = this;
2220  }
2221  };
2222 
2224 
2225 
2226  //return column header element
2227 
2228  Column.prototype.getElement = function () {
2229 
2230  return this.element;
2231  };
2232 
2233  //return colunm group element
2234 
2235  Column.prototype.getGroupElement = function () {
2236 
2237  return this.groupElement;
2238  };
2239 
2240  //return field name
2241 
2242  Column.prototype.getField = function () {
2243 
2244  return this.field;
2245  };
2246 
2247  //return the first column in a group
2248 
2249  Column.prototype.getFirstColumn = function () {
2250 
2251  if (!this.isGroup) {
2252 
2253  return this;
2254  } else {
2255 
2256  if (this.columns.length) {
2257 
2258  return this.columns[0].getFirstColumn();
2259  } else {
2260 
2261  return false;
2262  }
2263  }
2264  };
2265 
2266  //return the last column in a group
2267 
2268  Column.prototype.getLastColumn = function () {
2269 
2270  if (!this.isGroup) {
2271 
2272  return this;
2273  } else {
2274 
2275  if (this.columns.length) {
2276 
2277  return this.columns[this.columns.length - 1].getLastColumn();
2278  } else {
2279 
2280  return false;
2281  }
2282  }
2283  };
2284 
2285  //return all columns in a group
2286 
2287  Column.prototype.getColumns = function () {
2288 
2289  return this.columns;
2290  };
2291 
2292  //return all columns in a group
2293 
2294  Column.prototype.getCells = function () {
2295 
2296  return this.cells;
2297  };
2298 
2299  //retreive the top column in a group of columns
2300 
2301  Column.prototype.getTopColumn = function () {
2302 
2303  if (this.parent.isGroup) {
2304 
2305  return this.parent.getTopColumn();
2306  } else {
2307 
2308  return this;
2309  }
2310  };
2311 
2312  //return column definition object
2313 
2314  Column.prototype.getDefinition = function (updateBranches) {
2315 
2316  var colDefs = [];
2317 
2318  if (this.isGroup && updateBranches) {
2319 
2320  this.columns.forEach(function (column) {
2321 
2322  colDefs.push(column.getDefinition(true));
2323  });
2324 
2325  this.definition.columns = colDefs;
2326  }
2327 
2328  return this.definition;
2329  };
2330 
2332 
2333 
2334  Column.prototype.checkColumnVisibility = function () {
2335 
2336  var visible = false;
2337 
2338  this.columns.forEach(function (column) {
2339 
2340  if (column.visible) {
2341 
2342  visible = true;
2343  }
2344  });
2345 
2346  if (visible) {
2347 
2348  this.show();
2349 
2350  this.parent.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), false);
2351  } else {
2352 
2353  this.hide();
2354  }
2355  };
2356 
2357  //show column
2358 
2359  Column.prototype.show = function (silent, responsiveToggle) {
2360 
2361  if (!this.visible) {
2362 
2363  this.visible = true;
2364 
2365  this.element.style.display = "";
2366 
2367  if (this.parent.isGroup) {
2368 
2369  this.parent.checkColumnVisibility();
2370  }
2371 
2372  this.cells.forEach(function (cell) {
2373 
2374  cell.show();
2375  });
2376 
2377  if (!this.isGroup && this.width === null) {
2378 
2379  this.reinitializeWidth();
2380  }
2381 
2382  this.table.columnManager._verticalAlignHeaders();
2383 
2384  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
2385 
2386  this.table.modules.persistence.save("columns");
2387  }
2388 
2389  if (!responsiveToggle && this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
2390 
2391  this.table.modules.responsiveLayout.updateColumnVisibility(this, this.visible);
2392  }
2393 
2394  if (!silent) {
2395 
2396  this.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), true);
2397  }
2398 
2399  if (this.parent.isGroup) {
2400 
2401  this.parent.matchChildWidths();
2402  }
2403  }
2404  };
2405 
2406  //hide column
2407 
2408  Column.prototype.hide = function (silent, responsiveToggle) {
2409 
2410  if (this.visible) {
2411 
2412  this.visible = false;
2413 
2414  this.element.style.display = "none";
2415 
2416  this.table.columnManager._verticalAlignHeaders();
2417 
2418  if (this.parent.isGroup) {
2419 
2420  this.parent.checkColumnVisibility();
2421  }
2422 
2423  this.cells.forEach(function (cell) {
2424 
2425  cell.hide();
2426  });
2427 
2428  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
2429 
2430  this.table.modules.persistence.save("columns");
2431  }
2432 
2433  if (!responsiveToggle && this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
2434 
2435  this.table.modules.responsiveLayout.updateColumnVisibility(this, this.visible);
2436  }
2437 
2438  if (!silent) {
2439 
2440  this.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), false);
2441  }
2442 
2443  if (this.parent.isGroup) {
2444 
2445  this.parent.matchChildWidths();
2446  }
2447  }
2448  };
2449 
2450  Column.prototype.matchChildWidths = function () {
2451 
2452  var childWidth = 0;
2453 
2454  if (this.contentElement && this.columns.length) {
2455 
2456  this.columns.forEach(function (column) {
2457 
2458  if (column.visible) {
2459 
2460  childWidth += column.getWidth();
2461  }
2462  });
2463 
2464  this.contentElement.style.maxWidth = childWidth - 1 + "px";
2465  }
2466  };
2467 
2468  Column.prototype.setWidth = function (width) {
2469 
2470  this.widthFixed = true;
2471 
2472  this.setWidthActual(width);
2473  };
2474 
2475  Column.prototype.setWidthActual = function (width) {
2476 
2477  if (isNaN(width)) {
2478 
2479  width = Math.floor(this.table.element.clientWidth / 100 * parseInt(width));
2480  }
2481 
2482  width = Math.max(this.minWidth, width);
2483 
2484  this.width = width;
2485 
2486  this.widthStyled = width ? width + "px" : "";
2487 
2488  this.element.style.width = this.widthStyled;
2489 
2490  if (!this.isGroup) {
2491 
2492  this.cells.forEach(function (cell) {
2493 
2494  cell.setWidth();
2495  });
2496  }
2497 
2498  if (this.parent.isGroup) {
2499 
2500  this.parent.matchChildWidths();
2501  }
2502 
2503  //set resizable handles
2504 
2505  if (this.table.modExists("frozenColumns")) {
2506 
2507  this.table.modules.frozenColumns.layout();
2508  }
2509  };
2510 
2511  Column.prototype.checkCellHeights = function () {
2512 
2513  var rows = [];
2514 
2515  this.cells.forEach(function (cell) {
2516 
2517  if (cell.row.heightInitialized) {
2518 
2519  if (cell.row.getElement().offsetParent !== null) {
2520 
2521  rows.push(cell.row);
2522 
2523  cell.row.clearCellHeight();
2524  } else {
2525 
2526  cell.row.heightInitialized = false;
2527  }
2528  }
2529  });
2530 
2531  rows.forEach(function (row) {
2532 
2533  row.calcHeight();
2534  });
2535 
2536  rows.forEach(function (row) {
2537 
2538  row.setCellHeight();
2539  });
2540  };
2541 
2542  Column.prototype.getWidth = function () {
2543 
2544  // return this.element.offsetWidth;
2545 
2546  return this.width;
2547  };
2548 
2549  Column.prototype.getHeight = function () {
2550 
2551  return this.element.offsetHeight;
2552  };
2553 
2554  Column.prototype.setMinWidth = function (minWidth) {
2555 
2556  this.minWidth = minWidth;
2557 
2558  this.minWidthStyled = minWidth ? minWidth + "px" : "";
2559 
2560  this.element.style.minWidth = this.minWidthStyled;
2561 
2562  this.cells.forEach(function (cell) {
2563 
2564  cell.setMinWidth();
2565  });
2566  };
2567 
2568  Column.prototype.delete = function () {
2569  var _this7 = this;
2570 
2571  return new Promise(function (resolve, reject) {
2572 
2573  if (_this7.isGroup) {
2574 
2575  _this7.columns.forEach(function (column) {
2576 
2577  column.delete();
2578  });
2579  }
2580 
2581  var cellCount = _this7.cells.length;
2582 
2583  for (var i = 0; i < cellCount; i++) {
2584 
2585  _this7.cells[0].delete();
2586  }
2587 
2588  _this7.element.parentNode.removeChild(_this7.element);
2589 
2590  _this7.table.columnManager.deregisterColumn(_this7);
2591 
2592  resolve();
2593  });
2594  };
2595 
2596  Column.prototype.columnRendered = function () {
2597 
2598  if (this.titleFormatterRendered) {
2599 
2600  this.titleFormatterRendered();
2601  }
2602  };
2603 
2605 
2606 
2607  //generate cell for this column
2608 
2609  Column.prototype.generateCell = function (row) {
2610 
2611  var self = this;
2612 
2613  var cell = new Cell(self, row);
2614 
2615  this.cells.push(cell);
2616 
2617  return cell;
2618  };
2619 
2620  Column.prototype.nextColumn = function () {
2621 
2622  var index = this.table.columnManager.findColumnIndex(this);
2623 
2624  return index > -1 ? this._nextVisibleColumn(index + 1) : false;
2625  };
2626 
2627  Column.prototype._nextVisibleColumn = function (index) {
2628 
2629  var column = this.table.columnManager.getColumnByIndex(index);
2630 
2631  return !column || column.visible ? column : this._nextVisibleColumn(index + 1);
2632  };
2633 
2634  Column.prototype.prevColumn = function () {
2635 
2636  var index = this.table.columnManager.findColumnIndex(this);
2637 
2638  return index > -1 ? this._prevVisibleColumn(index - 1) : false;
2639  };
2640 
2641  Column.prototype._prevVisibleColumn = function (index) {
2642 
2643  var column = this.table.columnManager.getColumnByIndex(index);
2644 
2645  return !column || column.visible ? column : this._prevVisibleColumn(index - 1);
2646  };
2647 
2648  Column.prototype.reinitializeWidth = function (force) {
2649 
2650  this.widthFixed = false;
2651 
2652  //set width if present
2653 
2654  if (typeof this.definition.width !== "undefined" && !force) {
2655 
2656  this.setWidth(this.definition.width);
2657  }
2658 
2659  //hide header filters to prevent them altering column width
2660 
2661  if (this.table.modExists("filter")) {
2662 
2663  this.table.modules.filter.hideHeaderFilterElements();
2664  }
2665 
2666  this.fitToData();
2667 
2668  //show header filters again after layout is complete
2669 
2670  if (this.table.modExists("filter")) {
2671 
2672  this.table.modules.filter.showHeaderFilterElements();
2673  }
2674  };
2675 
2676  //set column width to maximum cell width
2677 
2678  Column.prototype.fitToData = function () {
2679 
2680  var self = this;
2681 
2682  if (!this.widthFixed) {
2683 
2684  this.element.style.width = "";
2685 
2686  self.cells.forEach(function (cell) {
2687 
2688  cell.clearWidth();
2689  });
2690  }
2691 
2692  var maxWidth = this.element.offsetWidth;
2693 
2694  if (!self.width || !this.widthFixed) {
2695 
2696  self.cells.forEach(function (cell) {
2697 
2698  var width = cell.getWidth();
2699 
2700  if (width > maxWidth) {
2701 
2702  maxWidth = width;
2703  }
2704  });
2705 
2706  if (maxWidth) {
2707 
2708  self.setWidthActual(maxWidth + 1);
2709  }
2710  }
2711  };
2712 
2713  Column.prototype.updateDefinition = function (updates) {
2714  var _this8 = this;
2715 
2716  return new Promise(function (resolve, reject) {
2717 
2718  var definition;
2719 
2720  if (!_this8.isGroup) {
2721 
2722  definition = Object.assign({}, _this8.getDefinition());
2723 
2724  definition = Object.assign(definition, updates);
2725 
2726  _this8.table.columnManager.addColumn(definition, false, _this8).then(function (column) {
2727 
2728  if (definition.field == _this8.field) {
2729 
2730  _this8.field = false; //cleair field name to prevent deletion of duplicate column from arrays
2731  }
2732 
2733  _this8.delete().then(function () {
2734 
2735  resolve(column.getComponent());
2736  }).catch(function (err) {
2737 
2738  reject(err);
2739  });
2740  }).catch(function (err) {
2741 
2742  reject(err);
2743  });
2744  } else {
2745 
2746  console.warn("Column Update Error - The updateDefintion function is only available on columns, not column groups");
2747 
2748  reject("Column Update Error - The updateDefintion function is only available on columns, not column groups");
2749  }
2750  });
2751  };
2752 
2753  Column.prototype.deleteCell = function (cell) {
2754 
2755  var index = this.cells.indexOf(cell);
2756 
2757  if (index > -1) {
2758 
2759  this.cells.splice(index, 1);
2760  }
2761  };
2762 
2763  Column.prototype.defaultOptionList = ["title", "field", "columns", "visible", "align", "width", "minWidth", "widthGrow", "widthShrink", "resizable", "frozen", "responsive", "tooltip", "cssClass", "rowHandle", "hideInHtml", "print", "htmlOutput", "sorter", "sorterParams", "formatter", "formatterParams", "variableHeight", "editable", "editor", "editorParams", "validator", "mutator", "mutatorParams", "mutatorData", "mutatorDataParams", "mutatorEdit", "mutatorEditParams", "mutatorClipboard", "mutatorClipboardParams", "accessor", "accessorParams", "accessorData", "accessorDataParams", "accessorDownload", "accessorDownloadParams", "accessorClipboard", "accessorClipboardParams", "clipboard", "download", "downloadTitle", "topCalc", "topCalcParams", "topCalcFormatter", "topCalcFormatterParams", "bottomCalc", "bottomCalcParams", "bottomCalcFormatter", "bottomCalcFormatterParams", "cellClick", "cellDblClick", "cellContext", "cellTap", "cellDblTap", "cellTapHold", "cellMouseEnter", "cellMouseLeave", "cellMouseOver", "cellMouseOut", "cellMouseMove", "cellEditing", "cellEdited", "cellEditCancelled", "headerSort", "headerSortStartingDir", "headerSortTristate", "headerClick", "headerDblClick", "headerContext", "headerTap", "headerDblTap", "headerTapHold", "headerTooltip", "headerVertical", "editableTitle", "titleFormatter", "titleFormatterParams", "headerFilter", "headerFilterPlaceholder", "headerFilterParams", "headerFilterEmptyCheck", "headerFilterFunc", "headerFilterFuncParams", "headerFilterLiveFilter", "print"];
2764 
2766 
2767 
2769 
2770  Column.prototype.getComponent = function () {
2771 
2772  return new ColumnComponent(this);
2773  };
2774 
2775  var RowManager = function RowManager(table) {
2776 
2777  this.table = table;
2778 
2779  this.element = this.createHolderElement(); //containing element
2780 
2781  this.tableElement = this.createTableElement(); //table element
2782 
2783  this.columnManager = null; //hold column manager object
2784 
2785  this.height = 0; //hold height of table element
2786 
2787 
2788  this.firstRender = false; //handle first render
2789 
2790  this.renderMode = "classic"; //current rendering mode
2791 
2792 
2793  this.rows = []; //hold row data objects
2794 
2795  this.activeRows = []; //rows currently available to on display in the table
2796 
2797  this.activeRowsCount = 0; //count of active rows
2798 
2799 
2800  this.displayRows = []; //rows currently on display in the table
2801 
2802  this.displayRowsCount = 0; //count of display rows
2803 
2804 
2805  this.scrollTop = 0;
2806 
2807  this.scrollLeft = 0;
2808 
2809  this.vDomRowHeight = 20; //approximation of row heights for padding
2810 
2811 
2812  this.vDomTop = 0; //hold position for first rendered row in the virtual DOM
2813 
2814  this.vDomBottom = 0; //hold possition for last rendered row in the virtual DOM
2815 
2816 
2817  this.vDomScrollPosTop = 0; //last scroll position of the vDom top;
2818 
2819  this.vDomScrollPosBottom = 0; //last scroll position of the vDom bottom;
2820 
2821 
2822  this.vDomTopPad = 0; //hold value of padding for top of virtual DOM
2823 
2824  this.vDomBottomPad = 0; //hold value of padding for bottom of virtual DOM
2825 
2826 
2827  this.vDomMaxRenderChain = 90; //the maximum number of dom elements that can be rendered in 1 go
2828 
2829 
2830  this.vDomWindowBuffer = 0; //window row buffer before removing elements, to smooth scrolling
2831 
2832 
2833  this.vDomWindowMinTotalRows = 20; //minimum number of rows to be generated in virtual dom (prevent buffering issues on tables with tall rows)
2834 
2835  this.vDomWindowMinMarginRows = 5; //minimum number of rows to be generated in virtual dom margin
2836 
2837 
2838  this.vDomTopNewRows = []; //rows to normalize after appending to optimize render speed
2839 
2840  this.vDomBottomNewRows = []; //rows to normalize after appending to optimize render speed
2841 
2842 
2843  this.rowNumColumn = false; //hold column component for row number column
2844 
2845 
2846  this.redrawBlock = false; //prevent redraws to allow multiple data manipulations becore continuing
2847 
2848  this.redrawBlockRestoreConfig = false; //store latest redraw function calls for when redraw is needed
2849 
2850  this.redrawBlockRederInPosition = false; //store latest redraw function calls for when redraw is needed
2851  };
2852 
2854 
2855 
2856  RowManager.prototype.createHolderElement = function () {
2857 
2858  var el = document.createElement("div");
2859 
2860  el.classList.add("tabulator-tableHolder");
2861 
2862  el.setAttribute("tabindex", 0);
2863 
2864  return el;
2865  };
2866 
2867  RowManager.prototype.createTableElement = function () {
2868 
2869  var el = document.createElement("div");
2870 
2871  el.classList.add("tabulator-table");
2872 
2873  return el;
2874  };
2875 
2876  //return containing element
2877 
2878  RowManager.prototype.getElement = function () {
2879 
2880  return this.element;
2881  };
2882 
2883  //return table element
2884 
2885  RowManager.prototype.getTableElement = function () {
2886 
2887  return this.tableElement;
2888  };
2889 
2890  //return position of row in table
2891 
2892  RowManager.prototype.getRowPosition = function (row, active) {
2893 
2894  if (active) {
2895 
2896  return this.activeRows.indexOf(row);
2897  } else {
2898 
2899  return this.rows.indexOf(row);
2900  }
2901  };
2902 
2903  //link to column manager
2904 
2905  RowManager.prototype.setColumnManager = function (manager) {
2906 
2907  this.columnManager = manager;
2908  };
2909 
2910  RowManager.prototype.initialize = function () {
2911 
2912  var self = this;
2913 
2914  self.setRenderMode();
2915 
2916  //initialize manager
2917 
2918  self.element.appendChild(self.tableElement);
2919 
2920  self.firstRender = true;
2921 
2922  //scroll header along with table body
2923 
2924  self.element.addEventListener("scroll", function () {
2925 
2926  var left = self.element.scrollLeft;
2927 
2928  //handle horizontal scrolling
2929 
2930  if (self.scrollLeft != left) {
2931 
2932  self.columnManager.scrollHorizontal(left);
2933 
2934  if (self.table.options.groupBy) {
2935 
2936  self.table.modules.groupRows.scrollHeaders(left);
2937  }
2938 
2939  if (self.table.modExists("columnCalcs")) {
2940 
2941  self.table.modules.columnCalcs.scrollHorizontal(left);
2942  }
2943 
2944  self.table.options.scrollHorizontal(left);
2945  }
2946 
2947  self.scrollLeft = left;
2948  });
2949 
2950  //handle virtual dom scrolling
2951 
2952  if (this.renderMode === "virtual") {
2953 
2954  self.element.addEventListener("scroll", function () {
2955 
2956  var top = self.element.scrollTop;
2957 
2958  var dir = self.scrollTop > top;
2959 
2960  //handle verical scrolling
2961 
2962  if (self.scrollTop != top) {
2963 
2964  self.scrollTop = top;
2965 
2966  self.scrollVertical(dir);
2967 
2968  if (self.table.options.ajaxProgressiveLoad == "scroll") {
2969 
2970  self.table.modules.ajax.nextPage(self.element.scrollHeight - self.element.clientHeight - top);
2971  }
2972 
2973  self.table.options.scrollVertical(top);
2974  } else {
2975 
2976  self.scrollTop = top;
2977  }
2978  });
2979  }
2980  };
2981 
2983 
2984 
2985  RowManager.prototype.findRow = function (subject) {
2986 
2987  var self = this;
2988 
2989  if ((typeof subject === 'undefined' ? 'undefined' : _typeof(subject)) == "object") {
2990 
2991  if (subject instanceof Row) {
2992 
2993  //subject is row element
2994 
2995  return subject;
2996  } else if (subject instanceof RowComponent) {
2997 
2998  //subject is public row component
2999 
3000  return subject._getSelf() || false;
3001  } else if (typeof HTMLElement !== "undefined" && subject instanceof HTMLElement) {
3002 
3003  //subject is a HTML element of the row
3004 
3005  var match = self.rows.find(function (row) {
3006 
3007  return row.element === subject;
3008  });
3009 
3010  return match || false;
3011  }
3012  } else if (typeof subject == "undefined" || subject === null) {
3013 
3014  return false;
3015  } else {
3016 
3017  //subject should be treated as the index of the row
3018 
3019  var _match = self.rows.find(function (row) {
3020 
3021  return row.data[self.table.options.index] == subject;
3022  });
3023 
3024  return _match || false;
3025  }
3026 
3027  //catch all for any other type of input
3028 
3029 
3030  return false;
3031  };
3032 
3033  RowManager.prototype.getRowFromDataObject = function (data) {
3034 
3035  var match = this.rows.find(function (row) {
3036 
3037  return row.data === data;
3038  });
3039 
3040  return match || false;
3041  };
3042 
3043  RowManager.prototype.getRowFromPosition = function (position, active) {
3044 
3045  if (active) {
3046 
3047  return this.activeRows[position];
3048  } else {
3049 
3050  return this.rows[position];
3051  }
3052  };
3053 
3054  RowManager.prototype.scrollToRow = function (row, position, ifVisible) {
3055  var _this9 = this;
3056 
3057  var rowIndex = this.getDisplayRows().indexOf(row),
3058  rowEl = row.getElement(),
3059  rowTop,
3060  offset = 0;
3061 
3062  return new Promise(function (resolve, reject) {
3063 
3064  if (rowIndex > -1) {
3065 
3066  if (typeof position === "undefined") {
3067 
3068  position = _this9.table.options.scrollToRowPosition;
3069  }
3070 
3071  if (typeof ifVisible === "undefined") {
3072 
3073  ifVisible = _this9.table.options.scrollToRowIfVisible;
3074  }
3075 
3076  if (position === "nearest") {
3077 
3078  switch (_this9.renderMode) {
3079 
3080  case "classic":
3081 
3082  rowTop = Tabulator.prototype.helpers.elOffset(rowEl).top;
3083 
3084  position = Math.abs(_this9.element.scrollTop - rowTop) > Math.abs(_this9.element.scrollTop + _this9.element.clientHeight - rowTop) ? "bottom" : "top";
3085 
3086  break;
3087 
3088  case "virtual":
3089 
3090  position = Math.abs(_this9.vDomTop - rowIndex) > Math.abs(_this9.vDomBottom - rowIndex) ? "bottom" : "top";
3091 
3092  break;
3093 
3094  }
3095  }
3096 
3097  //check row visibility
3098 
3099  if (!ifVisible) {
3100 
3101  if (Tabulator.prototype.helpers.elVisible(rowEl)) {
3102 
3103  offset = Tabulator.prototype.helpers.elOffset(rowEl).top - Tabulator.prototype.helpers.elOffset(_this9.element).top;
3104 
3105  if (offset > 0 && offset < _this9.element.clientHeight - rowEl.offsetHeight) {
3106 
3107  return false;
3108  }
3109  }
3110  }
3111 
3112  //scroll to row
3113 
3114  switch (_this9.renderMode) {
3115 
3116  case "classic":
3117 
3118  _this9.element.scrollTop = Tabulator.prototype.helpers.elOffset(rowEl).top - Tabulator.prototype.helpers.elOffset(_this9.element).top + _this9.element.scrollTop;
3119 
3120  break;
3121 
3122  case "virtual":
3123 
3124  _this9._virtualRenderFill(rowIndex, true);
3125 
3126  break;
3127 
3128  }
3129 
3130  //align to correct position
3131 
3132  switch (position) {
3133 
3134  case "middle":
3135 
3136  case "center":
3137 
3138  if (_this9.element.scrollHeight - _this9.element.scrollTop == _this9.element.clientHeight) {
3139 
3140  _this9.element.scrollTop = _this9.element.scrollTop + (rowEl.offsetTop - _this9.element.scrollTop) - (_this9.element.scrollHeight - rowEl.offsetTop) / 2;
3141  } else {
3142 
3143  _this9.element.scrollTop = _this9.element.scrollTop - _this9.element.clientHeight / 2;
3144  }
3145 
3146  break;
3147 
3148  case "bottom":
3149 
3150  if (_this9.element.scrollHeight - _this9.element.scrollTop == _this9.element.clientHeight) {
3151 
3152  _this9.element.scrollTop = _this9.element.scrollTop - (_this9.element.scrollHeight - rowEl.offsetTop) + rowEl.offsetHeight;
3153  } else {
3154 
3155  _this9.element.scrollTop = _this9.element.scrollTop - _this9.element.clientHeight + rowEl.offsetHeight;
3156  }
3157 
3158  break;
3159 
3160  }
3161 
3162  resolve();
3163  } else {
3164 
3165  console.warn("Scroll Error - Row not visible");
3166 
3167  reject("Scroll Error - Row not visible");
3168  }
3169  });
3170  };
3171 
3173 
3174 
3175  RowManager.prototype.setData = function (data, renderInPosition) {
3176  var _this10 = this;
3177 
3178  var self = this;
3179 
3180  return new Promise(function (resolve, reject) {
3181 
3182  if (renderInPosition && _this10.getDisplayRows().length) {
3183 
3184  if (self.table.options.pagination) {
3185 
3186  self._setDataActual(data, true);
3187  } else {
3188 
3189  _this10.reRenderInPosition(function () {
3190 
3191  self._setDataActual(data);
3192  });
3193  }
3194  } else {
3195 
3196  if (_this10.table.options.autoColumns) {
3197 
3198  _this10.table.columnManager.generateColumnsFromRowData(data);
3199  }
3200 
3201  _this10.resetScroll();
3202 
3203  _this10._setDataActual(data);
3204  }
3205 
3206  resolve();
3207  });
3208  };
3209 
3210  RowManager.prototype._setDataActual = function (data, renderInPosition) {
3211 
3212  var self = this;
3213 
3214  self.table.options.dataLoading.call(this.table, data);
3215 
3216  this._wipeElements();
3217 
3218  if (this.table.options.history && this.table.modExists("history")) {
3219 
3220  this.table.modules.history.clear();
3221  }
3222 
3223  if (Array.isArray(data)) {
3224 
3225  if (this.table.modExists("selectRow")) {
3226 
3227  this.table.modules.selectRow.clearSelectionData();
3228  }
3229 
3230  if (this.table.options.reactiveData && this.table.modExists("reactiveData", true)) {
3231 
3232  this.table.modules.reactiveData.watchData(data);
3233  }
3234 
3235  data.forEach(function (def, i) {
3236 
3237  if (def && (typeof def === 'undefined' ? 'undefined' : _typeof(def)) === "object") {
3238 
3239  var row = new Row(def, self);
3240 
3241  self.rows.push(row);
3242  } else {
3243 
3244  console.warn("Data Loading Warning - Invalid row data detected and ignored, expecting object but received:", def);
3245  }
3246  });
3247 
3248  self.table.options.dataLoaded.call(this.table, data);
3249 
3250  self.refreshActiveData(false, false, renderInPosition);
3251  } else {
3252 
3253  console.error("Data Loading Error - Unable to process data due to invalid data type \nExpecting: array \nReceived: ", typeof data === 'undefined' ? 'undefined' : _typeof(data), "\nData: ", data);
3254  }
3255  };
3256 
3257  RowManager.prototype._wipeElements = function () {
3258 
3259  this.rows.forEach(function (row) {
3260 
3261  row.wipe();
3262  });
3263 
3264  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
3265 
3266  this.table.modules.groupRows.wipe();
3267  }
3268 
3269  this.rows = [];
3270  };
3271 
3272  RowManager.prototype.deleteRow = function (row, blockRedraw) {
3273 
3274  var allIndex = this.rows.indexOf(row),
3275  activeIndex = this.activeRows.indexOf(row);
3276 
3277  if (activeIndex > -1) {
3278 
3279  this.activeRows.splice(activeIndex, 1);
3280  }
3281 
3282  if (allIndex > -1) {
3283 
3284  this.rows.splice(allIndex, 1);
3285  }
3286 
3287  this.setActiveRows(this.activeRows);
3288 
3289  this.displayRowIterator(function (rows) {
3290 
3291  var displayIndex = rows.indexOf(row);
3292 
3293  if (displayIndex > -1) {
3294 
3295  rows.splice(displayIndex, 1);
3296  }
3297  });
3298 
3299  if (!blockRedraw) {
3300 
3301  this.reRenderInPosition();
3302  }
3303 
3304  this.table.options.rowDeleted.call(this.table, row.getComponent());
3305 
3306  this.table.options.dataEdited.call(this.table, this.getData());
3307 
3308  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
3309 
3310  this.table.modules.groupRows.updateGroupRows(true);
3311  } else if (this.table.options.pagination && this.table.modExists("page")) {
3312 
3313  this.refreshActiveData(false, false, true);
3314  } else {
3315 
3316  if (this.table.options.pagination && this.table.modExists("page")) {
3317 
3318  this.refreshActiveData("page");
3319  }
3320  }
3321  };
3322 
3323  RowManager.prototype.addRow = function (data, pos, index, blockRedraw) {
3324 
3325  var row = this.addRowActual(data, pos, index, blockRedraw);
3326 
3327  if (this.table.options.history && this.table.modExists("history")) {
3328 
3329  this.table.modules.history.action("rowAdd", row, { data: data, pos: pos, index: index });
3330  }
3331 
3332  return row;
3333  };
3334 
3335  //add multiple rows
3336 
3337  RowManager.prototype.addRows = function (data, pos, index) {
3338  var _this11 = this;
3339 
3340  var self = this,
3341  length = 0,
3342  rows = [];
3343 
3344  return new Promise(function (resolve, reject) {
3345 
3346  pos = _this11.findAddRowPos(pos);
3347 
3348  if (!Array.isArray(data)) {
3349 
3350  data = [data];
3351  }
3352 
3353  length = data.length - 1;
3354 
3355  if (typeof index == "undefined" && pos || typeof index !== "undefined" && !pos) {
3356 
3357  data.reverse();
3358  }
3359 
3360  data.forEach(function (item, i) {
3361 
3362  var row = self.addRow(item, pos, index, true);
3363 
3364  rows.push(row);
3365  });
3366 
3367  if (_this11.table.options.groupBy && _this11.table.modExists("groupRows")) {
3368 
3369  _this11.table.modules.groupRows.updateGroupRows(true);
3370  } else if (_this11.table.options.pagination && _this11.table.modExists("page")) {
3371 
3372  _this11.refreshActiveData(false, false, true);
3373  } else {
3374 
3375  _this11.reRenderInPosition();
3376  }
3377 
3378  //recalc column calculations if present
3379 
3380  if (_this11.table.modExists("columnCalcs")) {
3381 
3382  _this11.table.modules.columnCalcs.recalc(_this11.table.rowManager.activeRows);
3383  }
3384 
3385  resolve(rows);
3386  });
3387  };
3388 
3389  RowManager.prototype.findAddRowPos = function (pos) {
3390 
3391  if (typeof pos === "undefined") {
3392 
3393  pos = this.table.options.addRowPos;
3394  }
3395 
3396  if (pos === "pos") {
3397 
3398  pos = true;
3399  }
3400 
3401  if (pos === "bottom") {
3402 
3403  pos = false;
3404  }
3405 
3406  return pos;
3407  };
3408 
3409  RowManager.prototype.addRowActual = function (data, pos, index, blockRedraw) {
3410 
3411  var row = data instanceof Row ? data : new Row(data || {}, this),
3412  top = this.findAddRowPos(pos),
3413  dispRows;
3414 
3415  if (!index && this.table.options.pagination && this.table.options.paginationAddRow == "page") {
3416 
3417  dispRows = this.getDisplayRows();
3418 
3419  if (top) {
3420 
3421  if (dispRows.length) {
3422 
3423  index = dispRows[0];
3424  } else {
3425 
3426  if (this.activeRows.length) {
3427 
3428  index = this.activeRows[this.activeRows.length - 1];
3429 
3430  top = false;
3431  }
3432  }
3433  } else {
3434 
3435  if (dispRows.length) {
3436 
3437  index = dispRows[dispRows.length - 1];
3438 
3439  top = dispRows.length < this.table.modules.page.getPageSize() ? false : true;
3440  }
3441  }
3442  }
3443 
3444  if (index) {
3445 
3446  index = this.findRow(index);
3447  }
3448 
3449  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
3450 
3451  this.table.modules.groupRows.assignRowToGroup(row);
3452 
3453  var groupRows = row.getGroup().rows;
3454 
3455  if (groupRows.length > 1) {
3456 
3457  if (!index || index && groupRows.indexOf(index) == -1) {
3458 
3459  if (top) {
3460 
3461  if (groupRows[0] !== row) {
3462 
3463  index = groupRows[0];
3464 
3465  this._moveRowInArray(row.getGroup().rows, row, index, !top);
3466  }
3467  } else {
3468 
3469  if (groupRows[groupRows.length - 1] !== row) {
3470 
3471  index = groupRows[groupRows.length - 1];
3472 
3473  this._moveRowInArray(row.getGroup().rows, row, index, !top);
3474  }
3475  }
3476  } else {
3477 
3478  this._moveRowInArray(row.getGroup().rows, row, index, !top);
3479  }
3480  }
3481  }
3482 
3483  if (index) {
3484 
3485  var allIndex = this.rows.indexOf(index),
3486  activeIndex = this.activeRows.indexOf(index);
3487 
3488  this.displayRowIterator(function (rows) {
3489 
3490  var displayIndex = rows.indexOf(index);
3491 
3492  if (displayIndex > -1) {
3493 
3494  rows.splice(top ? displayIndex : displayIndex + 1, 0, row);
3495  }
3496  });
3497 
3498  if (activeIndex > -1) {
3499 
3500  this.activeRows.splice(top ? activeIndex : activeIndex + 1, 0, row);
3501  }
3502 
3503  if (allIndex > -1) {
3504 
3505  this.rows.splice(top ? allIndex : allIndex + 1, 0, row);
3506  }
3507  } else {
3508 
3509  if (top) {
3510 
3511  this.displayRowIterator(function (rows) {
3512 
3513  rows.unshift(row);
3514  });
3515 
3516  this.activeRows.unshift(row);
3517 
3518  this.rows.unshift(row);
3519  } else {
3520 
3521  this.displayRowIterator(function (rows) {
3522 
3523  rows.push(row);
3524  });
3525 
3526  this.activeRows.push(row);
3527 
3528  this.rows.push(row);
3529  }
3530  }
3531 
3532  this.setActiveRows(this.activeRows);
3533 
3534  this.table.options.rowAdded.call(this.table, row.getComponent());
3535 
3536  this.table.options.dataEdited.call(this.table, this.getData());
3537 
3538  if (!blockRedraw) {
3539 
3540  this.reRenderInPosition();
3541  }
3542 
3543  return row;
3544  };
3545 
3546  RowManager.prototype.moveRow = function (from, to, after) {
3547 
3548  if (this.table.options.history && this.table.modExists("history")) {
3549 
3550  this.table.modules.history.action("rowMove", from, { pos: this.getRowPosition(from), to: to, after: after });
3551  }
3552 
3553  this.moveRowActual(from, to, after);
3554 
3555  this.table.options.rowMoved.call(this.table, from.getComponent());
3556  };
3557 
3558  RowManager.prototype.moveRowActual = function (from, to, after) {
3559 
3560  var self = this;
3561 
3562  this._moveRowInArray(this.rows, from, to, after);
3563 
3564  this._moveRowInArray(this.activeRows, from, to, after);
3565 
3566  this.displayRowIterator(function (rows) {
3567 
3568  self._moveRowInArray(rows, from, to, after);
3569  });
3570 
3571  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
3572 
3573  var toGroup = to.getGroup();
3574 
3575  var fromGroup = from.getGroup();
3576 
3577  if (toGroup === fromGroup) {
3578 
3579  this._moveRowInArray(toGroup.rows, from, to, after);
3580  } else {
3581 
3582  if (fromGroup) {
3583 
3584  fromGroup.removeRow(from);
3585  }
3586 
3587  toGroup.insertRow(from, to, after);
3588  }
3589  }
3590  };
3591 
3592  RowManager.prototype._moveRowInArray = function (rows, from, to, after) {
3593 
3594  var fromIndex, toIndex, start, end;
3595 
3596  if (from !== to) {
3597 
3598  fromIndex = rows.indexOf(from);
3599 
3600  if (fromIndex > -1) {
3601 
3602  rows.splice(fromIndex, 1);
3603 
3604  toIndex = rows.indexOf(to);
3605 
3606  if (toIndex > -1) {
3607 
3608  if (after) {
3609 
3610  rows.splice(toIndex + 1, 0, from);
3611  } else {
3612 
3613  rows.splice(toIndex, 0, from);
3614  }
3615  } else {
3616 
3617  rows.splice(fromIndex, 0, from);
3618  }
3619  }
3620 
3621  //restyle rows
3622 
3623  if (rows === this.getDisplayRows()) {
3624 
3625  start = fromIndex < toIndex ? fromIndex : toIndex;
3626 
3627  end = toIndex > fromIndex ? toIndex : fromIndex + 1;
3628 
3629  for (var i = start; i <= end; i++) {
3630 
3631  if (rows[i]) {
3632 
3633  this.styleRow(rows[i], i);
3634  }
3635  }
3636  }
3637  }
3638  };
3639 
3640  RowManager.prototype.clearData = function () {
3641 
3642  this.setData([]);
3643  };
3644 
3645  RowManager.prototype.getRowIndex = function (row) {
3646 
3647  return this.findRowIndex(row, this.rows);
3648  };
3649 
3650  RowManager.prototype.getDisplayRowIndex = function (row) {
3651 
3652  var index = this.getDisplayRows().indexOf(row);
3653 
3654  return index > -1 ? index : false;
3655  };
3656 
3657  RowManager.prototype.nextDisplayRow = function (row, rowOnly) {
3658 
3659  var index = this.getDisplayRowIndex(row),
3660  nextRow = false;
3661 
3662  if (index !== false && index < this.displayRowsCount - 1) {
3663 
3664  nextRow = this.getDisplayRows()[index + 1];
3665  }
3666 
3667  if (nextRow && (!(nextRow instanceof Row) || nextRow.type != "row")) {
3668 
3669  return this.nextDisplayRow(nextRow, rowOnly);
3670  }
3671 
3672  return nextRow;
3673  };
3674 
3675  RowManager.prototype.prevDisplayRow = function (row, rowOnly) {
3676 
3677  var index = this.getDisplayRowIndex(row),
3678  prevRow = false;
3679 
3680  if (index) {
3681 
3682  prevRow = this.getDisplayRows()[index - 1];
3683  }
3684 
3685  if (prevRow && (!(prevRow instanceof Row) || prevRow.type != "row")) {
3686 
3687  return this.prevDisplayRow(prevRow, rowOnly);
3688  }
3689 
3690  return prevRow;
3691  };
3692 
3693  RowManager.prototype.findRowIndex = function (row, list) {
3694 
3695  var rowIndex;
3696 
3697  row = this.findRow(row);
3698 
3699  if (row) {
3700 
3701  rowIndex = list.indexOf(row);
3702 
3703  if (rowIndex > -1) {
3704 
3705  return rowIndex;
3706  }
3707  }
3708 
3709  return false;
3710  };
3711 
3712  RowManager.prototype.getData = function (active, transform) {
3713 
3714  var output = [],
3715  rows = this.getRows(active);
3716 
3717  rows.forEach(function (row) {
3718 
3719  output.push(row.getData(transform || "data"));
3720  });
3721 
3722  return output;
3723  };
3724 
3725  RowManager.prototype.getComponents = function (active) {
3726 
3727  var output = [],
3728  rows = this.getRows(active);
3729 
3730  rows.forEach(function (row) {
3731 
3732  output.push(row.getComponent());
3733  });
3734 
3735  return output;
3736  };
3737 
3738  RowManager.prototype.getDataCount = function (active) {
3739 
3740  var rows = this.getRows(active);
3741 
3742  return rows.length;
3743  };
3744 
3745  RowManager.prototype._genRemoteRequest = function () {
3746 
3747  var self = this,
3748  table = self.table,
3749  options = table.options,
3750  params = {};
3751 
3752  if (table.modExists("page")) {
3753 
3754  //set sort data if defined
3755 
3756  if (options.ajaxSorting) {
3757 
3758  var sorters = self.table.modules.sort.getSort();
3759 
3760  sorters.forEach(function (item) {
3761 
3762  delete item.column;
3763  });
3764 
3765  params[self.table.modules.page.paginationDataSentNames.sorters] = sorters;
3766  }
3767 
3768  //set filter data if defined
3769 
3770  if (options.ajaxFiltering) {
3771 
3772  var filters = self.table.modules.filter.getFilters(true, true);
3773 
3774  params[self.table.modules.page.paginationDataSentNames.filters] = filters;
3775  }
3776 
3777  self.table.modules.ajax.setParams(params, true);
3778  }
3779 
3780  table.modules.ajax.sendRequest().then(function (data) {
3781 
3782  self.setData(data);
3783  }).catch(function (e) {});
3784  };
3785 
3786  //choose the path to refresh data after a filter update
3787 
3788  RowManager.prototype.filterRefresh = function () {
3789 
3790  var table = this.table,
3791  options = table.options,
3792  left = this.scrollLeft;
3793 
3794  if (options.ajaxFiltering) {
3795 
3796  if (options.pagination == "remote" && table.modExists("page")) {
3797 
3798  table.modules.page.reset(true);
3799 
3800  table.modules.page.setPage(1).then(function () {}).catch(function () {});
3801  } else if (options.ajaxProgressiveLoad) {
3802 
3803  table.modules.ajax.loadData().then(function () {}).catch(function () {});
3804  } else {
3805 
3806  //assume data is url, make ajax call to url to get data
3807 
3808  this._genRemoteRequest();
3809  }
3810  } else {
3811 
3812  this.refreshActiveData("filter");
3813  }
3814 
3815  this.scrollHorizontal(left);
3816  };
3817 
3818  //choose the path to refresh data after a sorter update
3819 
3820  RowManager.prototype.sorterRefresh = function (loadOrignalData) {
3821 
3822  var table = this.table,
3823  options = this.table.options,
3824  left = this.scrollLeft;
3825 
3826  if (options.ajaxSorting) {
3827 
3828  if ((options.pagination == "remote" || options.progressiveLoad) && table.modExists("page")) {
3829 
3830  table.modules.page.reset(true);
3831 
3832  table.modules.page.setPage(1).then(function () {}).catch(function () {});
3833  } else if (options.ajaxProgressiveLoad) {
3834 
3835  table.modules.ajax.loadData().then(function () {}).catch(function () {});
3836  } else {
3837 
3838  //assume data is url, make ajax call to url to get data
3839 
3840  this._genRemoteRequest();
3841  }
3842  } else {
3843 
3844  this.refreshActiveData(loadOrignalData ? "filter" : "sort");
3845  }
3846 
3847  this.scrollHorizontal(left);
3848  };
3849 
3850  RowManager.prototype.scrollHorizontal = function (left) {
3851 
3852  this.scrollLeft = left;
3853 
3854  this.element.scrollLeft = left;
3855 
3856  if (this.table.options.groupBy) {
3857 
3858  this.table.modules.groupRows.scrollHeaders(left);
3859  }
3860 
3861  if (this.table.modExists("columnCalcs")) {
3862 
3863  this.table.modules.columnCalcs.scrollHorizontal(left);
3864  }
3865  };
3866 
3867  //set active data set
3868 
3869  RowManager.prototype.refreshActiveData = function (stage, skipStage, renderInPosition) {
3870  var _this12 = this;
3871 
3872  var self = this,
3873  table = this.table,
3874  cascadeOrder = ["all", "filter", "sort", "display", "freeze", "group", "tree", "page"],
3875  displayIndex;
3876 
3877  if (this.redrawBlock) {
3878 
3879  if (!this.redrawBlockRestoreConfig || cascadeOrder.indexOf(stage) < cascadeOrder.indexOf(this.redrawBlockRestoreConfig.stage)) {
3880 
3881  this.redrawBlockRestoreConfig = {
3882 
3883  stage: stage,
3884 
3885  skipStage: skipStage,
3886 
3887  renderInPosition: renderInPosition
3888 
3889  };
3890  }
3891 
3892  return;
3893  } else {
3894 
3895  if (self.table.modExists("edit")) {
3896 
3897  self.table.modules.edit.cancelEdit();
3898  }
3899 
3900  if (!stage) {
3901 
3902  stage = "all";
3903  }
3904 
3905  if (table.options.selectable && !table.options.selectablePersistence && table.modExists("selectRow")) {
3906 
3907  table.modules.selectRow.deselectRows();
3908  }
3909 
3910  //cascade through data refresh stages
3911 
3912  switch (stage) {
3913 
3914  case "all":
3915 
3916  case "filter":
3917 
3918  if (!skipStage) {
3919 
3920  if (table.modExists("filter")) {
3921 
3922  self.setActiveRows(table.modules.filter.filter(self.rows));
3923  } else {
3924 
3925  self.setActiveRows(self.rows.slice(0));
3926  }
3927  } else {
3928 
3929  skipStage = false;
3930  }
3931 
3932  case "sort":
3933 
3934  if (!skipStage) {
3935 
3936  if (table.modExists("sort")) {
3937 
3938  table.modules.sort.sort(this.activeRows);
3939  }
3940  } else {
3941 
3942  skipStage = false;
3943  }
3944 
3945  //regenerate row numbers for row number formatter if in use
3946 
3947  if (this.rowNumColumn) {
3948 
3949  this.activeRows.forEach(function (row) {
3950 
3951  var cell = row.getCell(_this12.rowNumColumn);
3952 
3953  if (cell) {
3954 
3955  cell._generateContents();
3956  }
3957  });
3958  }
3959 
3960  //generic stage to allow for pipeline trigger after the data manipulation stage
3961 
3962  case "display":
3963 
3964  this.resetDisplayRows();
3965 
3966  case "freeze":
3967 
3968  if (!skipStage) {
3969 
3970  if (this.table.modExists("frozenRows")) {
3971 
3972  if (table.modules.frozenRows.isFrozen()) {
3973 
3974  if (!table.modules.frozenRows.getDisplayIndex()) {
3975 
3976  table.modules.frozenRows.setDisplayIndex(this.getNextDisplayIndex());
3977  }
3978 
3979  displayIndex = table.modules.frozenRows.getDisplayIndex();
3980 
3981  displayIndex = self.setDisplayRows(table.modules.frozenRows.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
3982 
3983  if (displayIndex !== true) {
3984 
3985  table.modules.frozenRows.setDisplayIndex(displayIndex);
3986  }
3987  }
3988  }
3989  } else {
3990 
3991  skipStage = false;
3992  }
3993 
3994  case "group":
3995 
3996  if (!skipStage) {
3997 
3998  if (table.options.groupBy && table.modExists("groupRows")) {
3999 
4000  if (!table.modules.groupRows.getDisplayIndex()) {
4001 
4002  table.modules.groupRows.setDisplayIndex(this.getNextDisplayIndex());
4003  }
4004 
4005  displayIndex = table.modules.groupRows.getDisplayIndex();
4006 
4007  displayIndex = self.setDisplayRows(table.modules.groupRows.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
4008 
4009  if (displayIndex !== true) {
4010 
4011  table.modules.groupRows.setDisplayIndex(displayIndex);
4012  }
4013  }
4014  } else {
4015 
4016  skipStage = false;
4017  }
4018 
4019  case "tree":
4020 
4021  if (!skipStage) {
4022 
4023  if (table.options.dataTree && table.modExists("dataTree")) {
4024 
4025  if (!table.modules.dataTree.getDisplayIndex()) {
4026 
4027  table.modules.dataTree.setDisplayIndex(this.getNextDisplayIndex());
4028  }
4029 
4030  displayIndex = table.modules.dataTree.getDisplayIndex();
4031 
4032  displayIndex = self.setDisplayRows(table.modules.dataTree.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
4033 
4034  if (displayIndex !== true) {
4035 
4036  table.modules.dataTree.setDisplayIndex(displayIndex);
4037  }
4038  }
4039  } else {
4040 
4041  skipStage = false;
4042  }
4043 
4044  if (table.options.pagination && table.modExists("page") && !renderInPosition) {
4045 
4046  if (table.modules.page.getMode() == "local") {
4047 
4048  table.modules.page.reset();
4049  }
4050  }
4051 
4052  case "page":
4053 
4054  if (!skipStage) {
4055 
4056  if (table.options.pagination && table.modExists("page")) {
4057 
4058  if (!table.modules.page.getDisplayIndex()) {
4059 
4060  table.modules.page.setDisplayIndex(this.getNextDisplayIndex());
4061  }
4062 
4063  displayIndex = table.modules.page.getDisplayIndex();
4064 
4065  if (table.modules.page.getMode() == "local") {
4066 
4067  table.modules.page.setMaxRows(this.getDisplayRows(displayIndex - 1).length);
4068  }
4069 
4070  displayIndex = self.setDisplayRows(table.modules.page.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
4071 
4072  if (displayIndex !== true) {
4073 
4074  table.modules.page.setDisplayIndex(displayIndex);
4075  }
4076  }
4077  } else {
4078 
4079  skipStage = false;
4080  }
4081 
4082  }
4083 
4084  if (Tabulator.prototype.helpers.elVisible(self.element)) {
4085 
4086  if (renderInPosition) {
4087 
4088  self.reRenderInPosition();
4089  } else {
4090 
4091  self.renderTable();
4092 
4093  if (table.options.layoutColumnsOnNewData) {
4094 
4095  self.table.columnManager.redraw(true);
4096  }
4097  }
4098  }
4099 
4100  if (table.modExists("columnCalcs")) {
4101 
4102  table.modules.columnCalcs.recalc(this.activeRows);
4103  }
4104  }
4105  };
4106 
4107  RowManager.prototype.setActiveRows = function (activeRows) {
4108 
4109  this.activeRows = activeRows;
4110 
4111  this.activeRowsCount = this.activeRows.length;
4112  };
4113 
4114  //reset display rows array
4115 
4116  RowManager.prototype.resetDisplayRows = function () {
4117 
4118  this.displayRows = [];
4119 
4120  this.displayRows.push(this.activeRows.slice(0));
4121 
4122  this.displayRowsCount = this.displayRows[0].length;
4123 
4124  if (this.table.modExists("frozenRows")) {
4125 
4126  this.table.modules.frozenRows.setDisplayIndex(0);
4127  }
4128 
4129  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
4130 
4131  this.table.modules.groupRows.setDisplayIndex(0);
4132  }
4133 
4134  if (this.table.options.pagination && this.table.modExists("page")) {
4135 
4136  this.table.modules.page.setDisplayIndex(0);
4137  }
4138  };
4139 
4140  RowManager.prototype.getNextDisplayIndex = function () {
4141 
4142  return this.displayRows.length;
4143  };
4144 
4145  //set display row pipeline data
4146 
4147  RowManager.prototype.setDisplayRows = function (displayRows, index) {
4148 
4149  var output = true;
4150 
4151  if (index && typeof this.displayRows[index] != "undefined") {
4152 
4153  this.displayRows[index] = displayRows;
4154 
4155  output = true;
4156  } else {
4157 
4158  this.displayRows.push(displayRows);
4159 
4160  output = index = this.displayRows.length - 1;
4161  }
4162 
4163  if (index == this.displayRows.length - 1) {
4164 
4165  this.displayRowsCount = this.displayRows[this.displayRows.length - 1].length;
4166  }
4167 
4168  return output;
4169  };
4170 
4171  RowManager.prototype.getDisplayRows = function (index) {
4172 
4173  if (typeof index == "undefined") {
4174 
4175  return this.displayRows.length ? this.displayRows[this.displayRows.length - 1] : [];
4176  } else {
4177 
4178  return this.displayRows[index] || [];
4179  }
4180  };
4181 
4182  RowManager.prototype.getVisibleRows = function (viewable) {
4183 
4184  var topEdge = this.element.scrollTop,
4185  bottomEdge = this.element.clientHeight + topEdge,
4186  topFound = false,
4187  topRow = 0,
4188  bottomRow = 0,
4189  rows = this.getDisplayRows();
4190 
4191  if (viewable) {
4192 
4193  this.getDisplayRows();
4194 
4195  for (var i = this.vDomTop; i <= this.vDomBottom; i++) {
4196 
4197  if (rows[i]) {
4198 
4199  if (!topFound) {
4200 
4201  if (topEdge - rows[i].getElement().offsetTop >= 0) {
4202 
4203  topRow = i;
4204  } else {
4205 
4206  topFound = true;
4207 
4208  if (bottomEdge - rows[i].getElement().offsetTop >= 0) {
4209 
4210  bottomRow = i;
4211  } else {
4212 
4213  break;
4214  }
4215  }
4216  } else {
4217 
4218  if (bottomEdge - rows[i].getElement().offsetTop >= 0) {
4219 
4220  bottomRow = i;
4221  } else {
4222 
4223  break;
4224  }
4225  }
4226  }
4227  }
4228  } else {
4229 
4230  topRow = this.vDomTop;
4231 
4232  bottomRow = this.vDomBottom;
4233  }
4234 
4235  return rows.slice(topRow, bottomRow + 1);
4236  };
4237 
4238  //repeat action accross display rows
4239 
4240  RowManager.prototype.displayRowIterator = function (callback) {
4241 
4242  this.displayRows.forEach(callback);
4243 
4244  this.displayRowsCount = this.displayRows[this.displayRows.length - 1].length;
4245  };
4246 
4247  //return only actual rows (not group headers etc)
4248 
4249  RowManager.prototype.getRows = function (active) {
4250 
4251  var rows;
4252 
4253  switch (active) {
4254 
4255  case "active":
4256 
4257  rows = this.activeRows;
4258 
4259  break;
4260 
4261  case "visible":
4262 
4263  rows = this.getVisibleRows(true);
4264 
4265  break;
4266 
4267  default:
4268 
4269  rows = this.rows;
4270 
4271  }
4272 
4273  return rows;
4274  };
4275 
4277 
4278 
4279  //trigger rerender of table in current position
4280 
4281  RowManager.prototype.reRenderInPosition = function (callback) {
4282 
4283  if (this.getRenderMode() == "virtual") {
4284 
4285  if (this.redrawBlock) {
4286 
4287  if (callback) {
4288 
4289  callback();
4290  } else {
4291 
4292  this.redrawBlockRederInPosition = true;
4293  }
4294  } else {
4295 
4296  var scrollTop = this.element.scrollTop;
4297 
4298  var topRow = false;
4299 
4300  var topOffset = false;
4301 
4302  var left = this.scrollLeft;
4303 
4304  var rows = this.getDisplayRows();
4305 
4306  for (var i = this.vDomTop; i <= this.vDomBottom; i++) {
4307 
4308  if (rows[i]) {
4309 
4310  var diff = scrollTop - rows[i].getElement().offsetTop;
4311 
4312  if (topOffset === false || Math.abs(diff) < topOffset) {
4313 
4314  topOffset = diff;
4315 
4316  topRow = i;
4317  } else {
4318 
4319  break;
4320  }
4321  }
4322  }
4323 
4324  if (callback) {
4325 
4326  callback();
4327  }
4328 
4329  this._virtualRenderFill(topRow === false ? this.displayRowsCount - 1 : topRow, true, topOffset || 0);
4330 
4331  this.scrollHorizontal(left);
4332  }
4333  } else {
4334 
4335  this.renderTable();
4336 
4337  if (callback) {
4338 
4339  callback();
4340  }
4341  }
4342  };
4343 
4344  RowManager.prototype.setRenderMode = function () {
4345 
4346  if ((this.table.element.clientHeight || this.table.options.height) && this.table.options.virtualDom) {
4347 
4348  this.renderMode = "virtual";
4349  } else {
4350 
4351  this.renderMode = "classic";
4352  }
4353  };
4354 
4355  RowManager.prototype.getRenderMode = function () {
4356 
4357  return this.renderMode;
4358  };
4359 
4360  RowManager.prototype.renderTable = function () {
4361 
4362  var self = this;
4363 
4364  self.table.options.renderStarted.call(this.table);
4365 
4366  self.element.scrollTop = 0;
4367 
4368  switch (self.renderMode) {
4369 
4370  case "classic":
4371 
4372  self._simpleRender();
4373 
4374  break;
4375 
4376  case "virtual":
4377 
4378  self._virtualRenderFill();
4379 
4380  break;
4381 
4382  }
4383 
4384  if (self.firstRender) {
4385 
4386  if (self.displayRowsCount) {
4387 
4388  self.firstRender = false;
4389 
4390  self.table.modules.layout.layout();
4391  } else {
4392 
4393  self.renderEmptyScroll();
4394  }
4395  }
4396 
4397  if (self.table.modExists("frozenColumns")) {
4398 
4399  self.table.modules.frozenColumns.layout();
4400  }
4401 
4402  if (!self.displayRowsCount) {
4403 
4404  if (self.table.options.placeholder) {
4405 
4406  if (this.renderMode) {
4407 
4408  self.table.options.placeholder.setAttribute("tabulator-render-mode", this.renderMode);
4409  }
4410 
4411  self.getElement().appendChild(self.table.options.placeholder);
4412  }
4413  }
4414 
4415  self.table.options.renderComplete.call(this.table);
4416  };
4417 
4418  //simple render on heightless table
4419 
4420  RowManager.prototype._simpleRender = function () {
4421 
4422  this._clearVirtualDom();
4423 
4424  if (this.displayRowsCount) {
4425 
4426  this.checkClassicModeGroupHeaderWidth();
4427  } else {
4428 
4429  this.renderEmptyScroll();
4430  }
4431  };
4432 
4433  RowManager.prototype.checkClassicModeGroupHeaderWidth = function () {
4434 
4435  var self = this,
4436  element = this.tableElement,
4437  onlyGroupHeaders = true;
4438 
4439  self.getDisplayRows().forEach(function (row, index) {
4440 
4441  self.styleRow(row, index);
4442 
4443  element.appendChild(row.getElement());
4444 
4445  row.initialize(true);
4446 
4447  if (row.type !== "group") {
4448 
4449  onlyGroupHeaders = false;
4450  }
4451  });
4452 
4453  if (onlyGroupHeaders) {
4454 
4455  element.style.minWidth = self.table.columnManager.getWidth() + "px";
4456  } else {
4457 
4458  element.style.minWidth = "";
4459  }
4460  };
4461 
4462  //show scrollbars on empty table div
4463 
4464  RowManager.prototype.renderEmptyScroll = function () {
4465 
4466  this.tableElement.style.minWidth = this.table.columnManager.getWidth() + "px";
4467 
4468  this.tableElement.style.minHeight = "1px";
4469 
4470  this.tableElement.style.visibility = "hidden";
4471  };
4472 
4473  RowManager.prototype._clearVirtualDom = function () {
4474 
4475  var element = this.tableElement;
4476 
4477  if (this.table.options.placeholder && this.table.options.placeholder.parentNode) {
4478 
4479  this.table.options.placeholder.parentNode.removeChild(this.table.options.placeholder);
4480  }
4481 
4482  // element.children.detach();
4483 
4484  while (element.firstChild) {
4485  element.removeChild(element.firstChild);
4486  }element.style.paddingTop = "";
4487 
4488  element.style.paddingBottom = "";
4489 
4490  element.style.minWidth = "";
4491 
4492  element.style.minHeight = "";
4493 
4494  element.style.visibility = "";
4495 
4496  this.scrollTop = 0;
4497 
4498  this.scrollLeft = 0;
4499 
4500  this.vDomTop = 0;
4501 
4502  this.vDomBottom = 0;
4503 
4504  this.vDomTopPad = 0;
4505 
4506  this.vDomBottomPad = 0;
4507  };
4508 
4509  RowManager.prototype.styleRow = function (row, index) {
4510 
4511  var rowEl = row.getElement();
4512 
4513  if (index % 2) {
4514 
4515  rowEl.classList.add("tabulator-row-even");
4516 
4517  rowEl.classList.remove("tabulator-row-odd");
4518  } else {
4519 
4520  rowEl.classList.add("tabulator-row-odd");
4521 
4522  rowEl.classList.remove("tabulator-row-even");
4523  }
4524  };
4525 
4526  //full virtual render
4527 
4528  RowManager.prototype._virtualRenderFill = function (position, forceMove, offset) {
4529 
4530  var self = this,
4531  element = self.tableElement,
4532  holder = self.element,
4533  topPad = 0,
4534  rowsHeight = 0,
4535  topPadHeight = 0,
4536  i = 0,
4537  onlyGroupHeaders = true,
4538  rows = self.getDisplayRows();
4539 
4540  position = position || 0;
4541 
4542  offset = offset || 0;
4543 
4544  if (!position) {
4545 
4546  self._clearVirtualDom();
4547  } else {
4548 
4549  while (element.firstChild) {
4550  element.removeChild(element.firstChild);
4551  } //check if position is too close to bottom of table
4552 
4553  var heightOccupied = (self.displayRowsCount - position + 1) * self.vDomRowHeight;
4554 
4555  if (heightOccupied < self.height) {
4556 
4557  position -= Math.ceil((self.height - heightOccupied) / self.vDomRowHeight);
4558 
4559  if (position < 0) {
4560 
4561  position = 0;
4562  }
4563  }
4564 
4565  //calculate initial pad
4566 
4567  topPad = Math.min(Math.max(Math.floor(self.vDomWindowBuffer / self.vDomRowHeight), self.vDomWindowMinMarginRows), position);
4568 
4569  position -= topPad;
4570  }
4571 
4572  if (self.displayRowsCount && Tabulator.prototype.helpers.elVisible(self.element)) {
4573 
4574  self.vDomTop = position;
4575 
4576  self.vDomBottom = position - 1;
4577 
4578  while ((rowsHeight <= self.height + self.vDomWindowBuffer || i < self.vDomWindowMinTotalRows) && self.vDomBottom < self.displayRowsCount - 1) {
4579 
4580  var index = self.vDomBottom + 1,
4581  row = rows[index],
4582  rowHeight = 0;
4583 
4584  self.styleRow(row, index);
4585 
4586  element.appendChild(row.getElement());
4587 
4588  if (!row.initialized) {
4589 
4590  row.initialize(true);
4591  } else {
4592 
4593  if (!row.heightInitialized) {
4594 
4595  row.normalizeHeight(true);
4596  }
4597  }
4598 
4599  rowHeight = row.getHeight();
4600 
4601  if (i < topPad) {
4602 
4603  topPadHeight += rowHeight;
4604  } else {
4605 
4606  rowsHeight += rowHeight;
4607  }
4608 
4609  if (rowHeight > this.vDomWindowBuffer) {
4610 
4611  this.vDomWindowBuffer = rowHeight * 2;
4612  }
4613 
4614  if (row.type !== "group") {
4615 
4616  onlyGroupHeaders = false;
4617  }
4618 
4619  self.vDomBottom++;
4620 
4621  i++;
4622  }
4623 
4624  if (!position) {
4625 
4626  this.vDomTopPad = 0;
4627 
4628  //adjust rowheight to match average of rendered elements
4629 
4630  self.vDomRowHeight = Math.floor((rowsHeight + topPadHeight) / i);
4631 
4632  self.vDomBottomPad = self.vDomRowHeight * (self.displayRowsCount - self.vDomBottom - 1);
4633 
4634  self.vDomScrollHeight = topPadHeight + rowsHeight + self.vDomBottomPad - self.height;
4635  } else {
4636 
4637  self.vDomTopPad = !forceMove ? self.scrollTop - topPadHeight : self.vDomRowHeight * this.vDomTop + offset;
4638 
4639  self.vDomBottomPad = self.vDomBottom == self.displayRowsCount - 1 ? 0 : Math.max(self.vDomScrollHeight - self.vDomTopPad - rowsHeight - topPadHeight, 0);
4640  }
4641 
4642  element.style.paddingTop = self.vDomTopPad + "px";
4643 
4644  element.style.paddingBottom = self.vDomBottomPad + "px";
4645 
4646  if (forceMove) {
4647 
4648  this.scrollTop = self.vDomTopPad + topPadHeight + offset - (this.element.scrollWidth > this.element.clientWidth ? this.element.offsetHeight - this.element.clientHeight : 0);
4649  }
4650 
4651  this.scrollTop = Math.min(this.scrollTop, this.element.scrollHeight - this.height);
4652 
4653  //adjust for horizontal scrollbar if present (and not at top of table)
4654 
4655  if (this.element.scrollWidth > this.element.offsetWidth && forceMove) {
4656 
4657  this.scrollTop += this.element.offsetHeight - this.element.clientHeight;
4658  }
4659 
4660  this.vDomScrollPosTop = this.scrollTop;
4661 
4662  this.vDomScrollPosBottom = this.scrollTop;
4663 
4664  holder.scrollTop = this.scrollTop;
4665 
4666  element.style.minWidth = onlyGroupHeaders ? self.table.columnManager.getWidth() + "px" : "";
4667 
4668  if (self.table.options.groupBy) {
4669 
4670  if (self.table.modules.layout.getMode() != "fitDataFill" && self.displayRowsCount == self.table.modules.groupRows.countGroups()) {
4671 
4672  self.tableElement.style.minWidth = self.table.columnManager.getWidth();
4673  }
4674  }
4675  } else {
4676 
4677  this.renderEmptyScroll();
4678  }
4679  };
4680 
4681  //handle vertical scrolling
4682 
4683  RowManager.prototype.scrollVertical = function (dir) {
4684 
4685  var topDiff = this.scrollTop - this.vDomScrollPosTop;
4686 
4687  var bottomDiff = this.scrollTop - this.vDomScrollPosBottom;
4688 
4689  var margin = this.vDomWindowBuffer * 2;
4690 
4691  if (-topDiff > margin || bottomDiff > margin) {
4692 
4693  //if big scroll redraw table;
4694 
4695  var left = this.scrollLeft;
4696 
4697  this._virtualRenderFill(Math.floor(this.element.scrollTop / this.element.scrollHeight * this.displayRowsCount));
4698 
4699  this.scrollHorizontal(left);
4700  } else {
4701 
4702  if (dir) {
4703 
4704  //scrolling up
4705 
4706  if (topDiff < 0) {
4707 
4708  this._addTopRow(-topDiff);
4709  }
4710 
4711  if (bottomDiff < 0) {
4712 
4713  //hide bottom row if needed
4714 
4715  if (this.vDomScrollHeight - this.scrollTop > this.vDomWindowBuffer) {
4716 
4717  this._removeBottomRow(-bottomDiff);
4718  }
4719  }
4720  } else {
4721 
4722  //scrolling down
4723 
4724  if (topDiff >= 0) {
4725 
4726  //hide top row if needed
4727 
4728  if (this.scrollTop > this.vDomWindowBuffer) {
4729 
4730  this._removeTopRow(topDiff);
4731  }
4732  }
4733 
4734  if (bottomDiff >= 0) {
4735 
4736  this._addBottomRow(bottomDiff);
4737  }
4738  }
4739  }
4740  };
4741 
4742  RowManager.prototype._addTopRow = function (topDiff) {
4743  var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
4744 
4745 
4746  var table = this.tableElement,
4747  rows = this.getDisplayRows();
4748 
4749  if (this.vDomTop) {
4750 
4751  var index = this.vDomTop - 1,
4752  topRow = rows[index],
4753  topRowHeight = topRow.getHeight() || this.vDomRowHeight;
4754 
4755  //hide top row if needed
4756 
4757  if (topDiff >= topRowHeight) {
4758 
4759  this.styleRow(topRow, index);
4760 
4761  table.insertBefore(topRow.getElement(), table.firstChild);
4762 
4763  if (!topRow.initialized || !topRow.heightInitialized) {
4764 
4765  this.vDomTopNewRows.push(topRow);
4766 
4767  if (!topRow.heightInitialized) {
4768 
4769  topRow.clearCellHeight();
4770  }
4771  }
4772 
4773  topRow.initialize();
4774 
4775  this.vDomTopPad -= topRowHeight;
4776 
4777  if (this.vDomTopPad < 0) {
4778 
4779  this.vDomTopPad = index * this.vDomRowHeight;
4780  }
4781 
4782  if (!index) {
4783 
4784  this.vDomTopPad = 0;
4785  }
4786 
4787  table.style.paddingTop = this.vDomTopPad + "px";
4788 
4789  this.vDomScrollPosTop -= topRowHeight;
4790 
4791  this.vDomTop--;
4792  }
4793 
4794  topDiff = -(this.scrollTop - this.vDomScrollPosTop);
4795 
4796  if (topRow.getHeight() > this.vDomWindowBuffer) {
4797 
4798  this.vDomWindowBuffer = topRow.getHeight() * 2;
4799  }
4800 
4801  if (i < this.vDomMaxRenderChain && this.vDomTop && topDiff >= (rows[this.vDomTop - 1].getHeight() || this.vDomRowHeight)) {
4802 
4803  this._addTopRow(topDiff, i + 1);
4804  } else {
4805 
4806  this._quickNormalizeRowHeight(this.vDomTopNewRows);
4807  }
4808  }
4809  };
4810 
4811  RowManager.prototype._removeTopRow = function (topDiff) {
4812 
4813  var table = this.tableElement,
4814  topRow = this.getDisplayRows()[this.vDomTop],
4815  topRowHeight = topRow.getHeight() || this.vDomRowHeight;
4816 
4817  if (topDiff >= topRowHeight) {
4818 
4819  var rowEl = topRow.getElement();
4820 
4821  rowEl.parentNode.removeChild(rowEl);
4822 
4823  this.vDomTopPad += topRowHeight;
4824 
4825  table.style.paddingTop = this.vDomTopPad + "px";
4826 
4827  this.vDomScrollPosTop += this.vDomTop ? topRowHeight : topRowHeight + this.vDomWindowBuffer;
4828 
4829  this.vDomTop++;
4830 
4831  topDiff = this.scrollTop - this.vDomScrollPosTop;
4832 
4833  this._removeTopRow(topDiff);
4834  }
4835  };
4836 
4837  RowManager.prototype._addBottomRow = function (bottomDiff) {
4838  var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
4839 
4840 
4841  var table = this.tableElement,
4842  rows = this.getDisplayRows();
4843 
4844  if (this.vDomBottom < this.displayRowsCount - 1) {
4845 
4846  var index = this.vDomBottom + 1,
4847  bottomRow = rows[index],
4848  bottomRowHeight = bottomRow.getHeight() || this.vDomRowHeight;
4849 
4850  //hide bottom row if needed
4851 
4852  if (bottomDiff >= bottomRowHeight) {
4853 
4854  this.styleRow(bottomRow, index);
4855 
4856  table.appendChild(bottomRow.getElement());
4857 
4858  if (!bottomRow.initialized || !bottomRow.heightInitialized) {
4859 
4860  this.vDomBottomNewRows.push(bottomRow);
4861 
4862  if (!bottomRow.heightInitialized) {
4863 
4864  bottomRow.clearCellHeight();
4865  }
4866  }
4867 
4868  bottomRow.initialize();
4869 
4870  this.vDomBottomPad -= bottomRowHeight;
4871 
4872  if (this.vDomBottomPad < 0 || index == this.displayRowsCount - 1) {
4873 
4874  this.vDomBottomPad = 0;
4875  }
4876 
4877  table.style.paddingBottom = this.vDomBottomPad + "px";
4878 
4879  this.vDomScrollPosBottom += bottomRowHeight;
4880 
4881  this.vDomBottom++;
4882  }
4883 
4884  bottomDiff = this.scrollTop - this.vDomScrollPosBottom;
4885 
4886  if (bottomRow.getHeight() > this.vDomWindowBuffer) {
4887 
4888  this.vDomWindowBuffer = bottomRow.getHeight() * 2;
4889  }
4890 
4891  if (i < this.vDomMaxRenderChain && this.vDomBottom < this.displayRowsCount - 1 && bottomDiff >= (rows[this.vDomBottom + 1].getHeight() || this.vDomRowHeight)) {
4892 
4893  this._addBottomRow(bottomDiff, i + 1);
4894  } else {
4895 
4896  this._quickNormalizeRowHeight(this.vDomBottomNewRows);
4897  }
4898  }
4899  };
4900 
4901  RowManager.prototype._removeBottomRow = function (bottomDiff) {
4902 
4903  var table = this.tableElement,
4904  bottomRow = this.getDisplayRows()[this.vDomBottom],
4905  bottomRowHeight = bottomRow.getHeight() || this.vDomRowHeight;
4906 
4907  if (bottomDiff >= bottomRowHeight) {
4908 
4909  var rowEl = bottomRow.getElement();
4910 
4911  if (rowEl.parentNode) {
4912 
4913  rowEl.parentNode.removeChild(rowEl);
4914  }
4915 
4916  this.vDomBottomPad += bottomRowHeight;
4917 
4918  if (this.vDomBottomPad < 0) {
4919 
4920  this.vDomBottomPad = 0;
4921  }
4922 
4923  table.style.paddingBottom = this.vDomBottomPad + "px";
4924 
4925  this.vDomScrollPosBottom -= bottomRowHeight;
4926 
4927  this.vDomBottom--;
4928 
4929  bottomDiff = -(this.scrollTop - this.vDomScrollPosBottom);
4930 
4931  this._removeBottomRow(bottomDiff);
4932  }
4933  };
4934 
4935  RowManager.prototype._quickNormalizeRowHeight = function (rows) {
4936 
4937  rows.forEach(function (row) {
4938 
4939  row.calcHeight();
4940  });
4941 
4942  rows.forEach(function (row) {
4943 
4944  row.setCellHeight();
4945  });
4946 
4947  rows.length = 0;
4948  };
4949 
4950  //normalize height of active rows
4951 
4952  RowManager.prototype.normalizeHeight = function () {
4953 
4954  this.activeRows.forEach(function (row) {
4955 
4956  row.normalizeHeight();
4957  });
4958  };
4959 
4960  //adjust the height of the table holder to fit in the Tabulator element
4961 
4962  RowManager.prototype.adjustTableSize = function () {
4963 
4964  if (this.renderMode === "virtual") {
4965 
4966  this.height = this.element.clientHeight;
4967 
4968  this.vDomWindowBuffer = this.table.options.virtualDomBuffer || this.height;
4969 
4970  var otherHeight = this.columnManager.getElement().offsetHeight + (this.table.footerManager && !this.table.footerManager.external ? this.table.footerManager.getElement().offsetHeight : 0);
4971 
4972  this.element.style.minHeight = "calc(100% - " + otherHeight + "px)";
4973 
4974  this.element.style.height = "calc(100% - " + otherHeight + "px)";
4975 
4976  this.element.style.maxHeight = "calc(100% - " + otherHeight + "px)";
4977  }
4978  };
4979 
4980  //renitialize all rows
4981 
4982  RowManager.prototype.reinitialize = function () {
4983 
4984  this.rows.forEach(function (row) {
4985 
4986  row.reinitialize();
4987  });
4988  };
4989 
4990  //prevent table from being redrawn
4991 
4992  RowManager.prototype.blockRedraw = function () {
4993 
4994  this.redrawBlock = true;
4995 
4996  this.redrawBlockRestoreConfig = false;
4997  };
4998 
4999  //restore table redrawing
5000 
5001  RowManager.prototype.restoreRedraw = function () {
5002 
5003  this.redrawBlock = false;
5004 
5005  if (this.redrawBlockRestoreConfig) {
5006 
5007  this.refreshActiveData(this.redrawBlockRestoreConfig.stage, this.redrawBlockRestoreConfig.skipStage, this.redrawBlockRestoreConfig.renderInPosition);
5008 
5009  this.redrawBlockRestoreConfig = false;
5010  } else {
5011 
5012  if (this.redrawBlockRederInPosition) {
5013 
5014  this.reRenderInPosition();
5015  }
5016  }
5017 
5018  this.redrawBlockRederInPosition = false;
5019  };
5020 
5021  //redraw table
5022 
5023  RowManager.prototype.redraw = function (force) {
5024 
5025  var pos = 0,
5026  left = this.scrollLeft;
5027 
5028  this.adjustTableSize();
5029 
5030  this.table.tableWidth = this.table.element.clientWidth;
5031 
5032  if (!force) {
5033 
5034  if (this.renderMode == "classic") {
5035 
5036  if (this.table.options.groupBy) {
5037 
5038  this.refreshActiveData("group", false, false);
5039  } else {
5040 
5041  this._simpleRender();
5042  }
5043  } else {
5044 
5045  this.reRenderInPosition();
5046 
5047  this.scrollHorizontal(left);
5048  }
5049 
5050  if (!this.displayRowsCount) {
5051 
5052  if (this.table.options.placeholder) {
5053 
5054  this.getElement().appendChild(this.table.options.placeholder);
5055  }
5056  }
5057  } else {
5058 
5059  this.renderTable();
5060  }
5061  };
5062 
5063  RowManager.prototype.resetScroll = function () {
5064 
5065  this.element.scrollLeft = 0;
5066 
5067  this.element.scrollTop = 0;
5068 
5069  if (this.table.browser === "ie") {
5070 
5071  var event = document.createEvent("Event");
5072 
5073  event.initEvent("scroll", false, true);
5074 
5075  this.element.dispatchEvent(event);
5076  } else {
5077 
5078  this.element.dispatchEvent(new Event('scroll'));
5079  }
5080  };
5081 
5082  //public row object
5083 
5084  var RowComponent = function RowComponent(row) {
5085 
5086  this._row = row;
5087  };
5088 
5089  RowComponent.prototype.getData = function (transform) {
5090 
5091  return this._row.getData(transform);
5092  };
5093 
5094  RowComponent.prototype.getElement = function () {
5095 
5096  return this._row.getElement();
5097  };
5098 
5099  RowComponent.prototype.getCells = function () {
5100 
5101  var cells = [];
5102 
5103  this._row.getCells().forEach(function (cell) {
5104 
5105  cells.push(cell.getComponent());
5106  });
5107 
5108  return cells;
5109  };
5110 
5111  RowComponent.prototype.getCell = function (column) {
5112 
5113  var cell = this._row.getCell(column);
5114 
5115  return cell ? cell.getComponent() : false;
5116  };
5117 
5118  RowComponent.prototype.getIndex = function () {
5119 
5120  return this._row.getData("data")[this._row.table.options.index];
5121  };
5122 
5123  RowComponent.prototype.getPosition = function (active) {
5124 
5125  return this._row.table.rowManager.getRowPosition(this._row, active);
5126  };
5127 
5128  RowComponent.prototype.delete = function () {
5129 
5130  return this._row.delete();
5131  };
5132 
5133  RowComponent.prototype.scrollTo = function () {
5134 
5135  return this._row.table.rowManager.scrollToRow(this._row);
5136  };
5137 
5138  RowComponent.prototype.pageTo = function () {
5139 
5140  if (this._row.table.modExists("page", true)) {
5141 
5142  return this._row.table.modules.page.setPageToRow(this._row);
5143  }
5144  };
5145 
5146  RowComponent.prototype.move = function (to, after) {
5147 
5148  this._row.moveToRow(to, after);
5149  };
5150 
5151  RowComponent.prototype.update = function (data) {
5152 
5153  return this._row.updateData(data);
5154  };
5155 
5156  RowComponent.prototype.normalizeHeight = function () {
5157 
5158  this._row.normalizeHeight(true);
5159  };
5160 
5161  RowComponent.prototype.select = function () {
5162 
5163  this._row.table.modules.selectRow.selectRows(this._row);
5164  };
5165 
5166  RowComponent.prototype.deselect = function () {
5167 
5168  this._row.table.modules.selectRow.deselectRows(this._row);
5169  };
5170 
5171  RowComponent.prototype.toggleSelect = function () {
5172 
5173  this._row.table.modules.selectRow.toggleRow(this._row);
5174  };
5175 
5176  RowComponent.prototype.isSelected = function () {
5177 
5178  return this._row.table.modules.selectRow.isRowSelected(this._row);
5179  };
5180 
5181  RowComponent.prototype._getSelf = function () {
5182 
5183  return this._row;
5184  };
5185 
5186  RowComponent.prototype.freeze = function () {
5187 
5188  if (this._row.table.modExists("frozenRows", true)) {
5189 
5190  this._row.table.modules.frozenRows.freezeRow(this._row);
5191  }
5192  };
5193 
5194  RowComponent.prototype.unfreeze = function () {
5195 
5196  if (this._row.table.modExists("frozenRows", true)) {
5197 
5198  this._row.table.modules.frozenRows.unfreezeRow(this._row);
5199  }
5200  };
5201 
5202  RowComponent.prototype.treeCollapse = function () {
5203 
5204  if (this._row.table.modExists("dataTree", true)) {
5205 
5206  this._row.table.modules.dataTree.collapseRow(this._row);
5207  }
5208  };
5209 
5210  RowComponent.prototype.treeExpand = function () {
5211 
5212  if (this._row.table.modExists("dataTree", true)) {
5213 
5214  this._row.table.modules.dataTree.expandRow(this._row);
5215  }
5216  };
5217 
5218  RowComponent.prototype.treeToggle = function () {
5219 
5220  if (this._row.table.modExists("dataTree", true)) {
5221 
5222  this._row.table.modules.dataTree.toggleRow(this._row);
5223  }
5224  };
5225 
5226  RowComponent.prototype.getTreeParent = function () {
5227 
5228  if (this._row.table.modExists("dataTree", true)) {
5229 
5230  return this._row.table.modules.dataTree.getTreeParent(this._row);
5231  }
5232 
5233  return false;
5234  };
5235 
5236  RowComponent.prototype.getTreeChildren = function () {
5237 
5238  if (this._row.table.modExists("dataTree", true)) {
5239 
5240  return this._row.table.modules.dataTree.getTreeChildren(this._row);
5241  }
5242 
5243  return false;
5244  };
5245 
5246  RowComponent.prototype.reformat = function () {
5247 
5248  return this._row.reinitialize();
5249  };
5250 
5251  RowComponent.prototype.getGroup = function () {
5252 
5253  return this._row.getGroup().getComponent();
5254  };
5255 
5256  RowComponent.prototype.getTable = function () {
5257 
5258  return this._row.table;
5259  };
5260 
5261  RowComponent.prototype.getNextRow = function () {
5262 
5263  var row = this._row.nextRow();
5264 
5265  return row ? row.getComponent() : row;
5266  };
5267 
5268  RowComponent.prototype.getPrevRow = function () {
5269 
5270  var row = this._row.prevRow();
5271 
5272  return row ? row.getComponent() : row;
5273  };
5274 
5275  var Row = function Row(data, parent) {
5276  var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "row";
5277 
5278 
5279  this.table = parent.table;
5280 
5281  this.parent = parent;
5282 
5283  this.data = {};
5284 
5285  this.type = type; //type of element
5286 
5287  this.element = this.createElement();
5288 
5289  this.modules = {}; //hold module variables;
5290 
5291  this.cells = [];
5292 
5293  this.height = 0; //hold element height
5294 
5295  this.heightStyled = ""; //hold element height prestyled to improve render efficiency
5296 
5297  this.manualHeight = false; //user has manually set row height
5298 
5299  this.outerHeight = 0; //holde lements outer height
5300 
5301  this.initialized = false; //element has been rendered
5302 
5303  this.heightInitialized = false; //element has resized cells to fit
5304 
5305 
5306  this.setData(data);
5307 
5308  this.generateElement();
5309  };
5310 
5311  Row.prototype.createElement = function () {
5312 
5313  var el = document.createElement("div");
5314 
5315  el.classList.add("tabulator-row");
5316 
5317  el.setAttribute("role", "row");
5318 
5319  return el;
5320  };
5321 
5322  Row.prototype.getElement = function () {
5323 
5324  return this.element;
5325  };
5326 
5327  Row.prototype.detachElement = function () {
5328 
5329  if (this.element && this.element.parentNode) {
5330 
5331  this.element.parentNode.removeChild(this.element);
5332  }
5333  };
5334 
5335  Row.prototype.generateElement = function () {
5336 
5337  var self = this,
5338  dblTap,
5339  tapHold,
5340  tap;
5341 
5342  //set row selection characteristics
5343 
5344  if (self.table.options.selectable !== false && self.table.modExists("selectRow")) {
5345 
5346  self.table.modules.selectRow.initializeRow(this);
5347  }
5348 
5349  //setup movable rows
5350 
5351  if (self.table.options.movableRows !== false && self.table.modExists("moveRow")) {
5352 
5353  self.table.modules.moveRow.initializeRow(this);
5354  }
5355 
5356  //setup data tree
5357 
5358  if (self.table.options.dataTree !== false && self.table.modExists("dataTree")) {
5359 
5360  self.table.modules.dataTree.initializeRow(this);
5361  }
5362 
5363  //setup column colapse container
5364 
5365  if (self.table.options.responsiveLayout === "collapse" && self.table.modExists("responsiveLayout")) {
5366 
5367  self.table.modules.responsiveLayout.initializeRow(this);
5368  }
5369 
5370  //handle row click events
5371 
5372  if (self.table.options.rowClick) {
5373 
5374  self.element.addEventListener("click", function (e) {
5375 
5376  self.table.options.rowClick(e, self.getComponent());
5377  });
5378  }
5379 
5380  if (self.table.options.rowDblClick) {
5381 
5382  self.element.addEventListener("dblclick", function (e) {
5383 
5384  self.table.options.rowDblClick(e, self.getComponent());
5385  });
5386  }
5387 
5388  if (self.table.options.rowContext) {
5389 
5390  self.element.addEventListener("contextmenu", function (e) {
5391 
5392  self.table.options.rowContext(e, self.getComponent());
5393  });
5394  }
5395 
5396  //handle mouse events
5397 
5398  if (self.table.options.rowMouseEnter) {
5399 
5400  self.element.addEventListener("mouseenter", function (e) {
5401 
5402  self.table.options.rowMouseEnter(e, self.getComponent());
5403  });
5404  }
5405 
5406  if (self.table.options.rowMouseLeave) {
5407 
5408  self.element.addEventListener("mouseleave", function (e) {
5409 
5410  self.table.options.rowMouseLeave(e, self.getComponent());
5411  });
5412  }
5413 
5414  if (self.table.options.rowMouseOver) {
5415 
5416  self.element.addEventListener("mouseover", function (e) {
5417 
5418  self.table.options.rowMouseOver(e, self.getComponent());
5419  });
5420  }
5421 
5422  if (self.table.options.rowMouseOut) {
5423 
5424  self.element.addEventListener("mouseout", function (e) {
5425 
5426  self.table.options.rowMouseOut(e, self.getComponent());
5427  });
5428  }
5429 
5430  if (self.table.options.rowMouseMove) {
5431 
5432  self.element.addEventListener("mousemove", function (e) {
5433 
5434  self.table.options.rowMouseMove(e, self.getComponent());
5435  });
5436  }
5437 
5438  if (self.table.options.rowTap) {
5439 
5440  tap = false;
5441 
5442  self.element.addEventListener("touchstart", function (e) {
5443 
5444  tap = true;
5445  }, { passive: true });
5446 
5447  self.element.addEventListener("touchend", function (e) {
5448 
5449  if (tap) {
5450 
5451  self.table.options.rowTap(e, self.getComponent());
5452  }
5453 
5454  tap = false;
5455  });
5456  }
5457 
5458  if (self.table.options.rowDblTap) {
5459 
5460  dblTap = null;
5461 
5462  self.element.addEventListener("touchend", function (e) {
5463 
5464  if (dblTap) {
5465 
5466  clearTimeout(dblTap);
5467 
5468  dblTap = null;
5469 
5470  self.table.options.rowDblTap(e, self.getComponent());
5471  } else {
5472 
5473  dblTap = setTimeout(function () {
5474 
5475  clearTimeout(dblTap);
5476 
5477  dblTap = null;
5478  }, 300);
5479  }
5480  });
5481  }
5482 
5483  if (self.table.options.rowTapHold) {
5484 
5485  tapHold = null;
5486 
5487  self.element.addEventListener("touchstart", function (e) {
5488 
5489  clearTimeout(tapHold);
5490 
5491  tapHold = setTimeout(function () {
5492 
5493  clearTimeout(tapHold);
5494 
5495  tapHold = null;
5496 
5497  tap = false;
5498 
5499  self.table.options.rowTapHold(e, self.getComponent());
5500  }, 1000);
5501  }, { passive: true });
5502 
5503  self.element.addEventListener("touchend", function (e) {
5504 
5505  clearTimeout(tapHold);
5506 
5507  tapHold = null;
5508  });
5509  }
5510  };
5511 
5512  Row.prototype.generateCells = function () {
5513 
5514  this.cells = this.table.columnManager.generateCells(this);
5515  };
5516 
5517  //functions to setup on first render
5518 
5519  Row.prototype.initialize = function (force) {
5520 
5521  var self = this;
5522 
5523  if (!self.initialized || force) {
5524 
5525  self.deleteCells();
5526 
5527  while (self.element.firstChild) {
5528  self.element.removeChild(self.element.firstChild);
5529  } //handle frozen cells
5530 
5531  if (this.table.modExists("frozenColumns")) {
5532 
5533  this.table.modules.frozenColumns.layoutRow(this);
5534  }
5535 
5536  this.generateCells();
5537 
5538  self.cells.forEach(function (cell) {
5539 
5540  self.element.appendChild(cell.getElement());
5541 
5542  cell.cellRendered();
5543  });
5544 
5545  if (force) {
5546 
5547  self.normalizeHeight();
5548  }
5549 
5550  //setup movable rows
5551 
5552  if (self.table.options.dataTree && self.table.modExists("dataTree")) {
5553 
5554  self.table.modules.dataTree.layoutRow(this);
5555  }
5556 
5557  //setup column colapse container
5558 
5559  if (self.table.options.responsiveLayout === "collapse" && self.table.modExists("responsiveLayout")) {
5560 
5561  self.table.modules.responsiveLayout.layoutRow(this);
5562  }
5563 
5564  if (self.table.options.rowFormatter) {
5565 
5566  self.table.options.rowFormatter(self.getComponent());
5567  }
5568 
5569  //set resizable handles
5570 
5571  if (self.table.options.resizableRows && self.table.modExists("resizeRows")) {
5572 
5573  self.table.modules.resizeRows.initializeRow(self);
5574  }
5575 
5576  self.initialized = true;
5577  }
5578  };
5579 
5580  Row.prototype.reinitializeHeight = function () {
5581 
5582  this.heightInitialized = false;
5583 
5584  if (this.element.offsetParent !== null) {
5585 
5586  this.normalizeHeight(true);
5587  }
5588  };
5589 
5590  Row.prototype.reinitialize = function () {
5591 
5592  this.initialized = false;
5593 
5594  this.heightInitialized = false;
5595 
5596  if (!this.manualHeight) {
5597 
5598  this.height = 0;
5599 
5600  this.heightStyled = "";
5601  }
5602 
5603  if (this.element.offsetParent !== null) {
5604 
5605  this.initialize(true);
5606  }
5607  };
5608 
5609  //get heights when doing bulk row style calcs in virtual DOM
5610 
5611  Row.prototype.calcHeight = function (force) {
5612 
5613  var maxHeight = 0,
5614  minHeight = this.table.options.resizableRows ? this.element.clientHeight : 0;
5615 
5616  this.cells.forEach(function (cell) {
5617 
5618  var height = cell.getHeight();
5619 
5620  if (height > maxHeight) {
5621 
5622  maxHeight = height;
5623  }
5624  });
5625 
5626  if (force) {
5627 
5628  this.height = Math.max(maxHeight, minHeight);
5629  } else {
5630 
5631  this.height = this.manualHeight ? this.height : Math.max(maxHeight, minHeight);
5632  }
5633 
5634  this.heightStyled = this.height ? this.height + "px" : "";
5635 
5636  this.outerHeight = this.element.offsetHeight;
5637  };
5638 
5639  //set of cells
5640 
5641  Row.prototype.setCellHeight = function () {
5642 
5643  this.cells.forEach(function (cell) {
5644 
5645  cell.setHeight();
5646  });
5647 
5648  this.heightInitialized = true;
5649  };
5650 
5651  Row.prototype.clearCellHeight = function () {
5652 
5653  this.cells.forEach(function (cell) {
5654 
5655  cell.clearHeight();
5656  });
5657  };
5658 
5659  //normalize the height of elements in the row
5660 
5661  Row.prototype.normalizeHeight = function (force) {
5662 
5663  if (force) {
5664 
5665  this.clearCellHeight();
5666  }
5667 
5668  this.calcHeight(force);
5669 
5670  this.setCellHeight();
5671  };
5672 
5673  // Row.prototype.setHeight = function(height){
5674 
5675  // this.height = height;
5676 
5677 
5678  // this.setCellHeight();
5679 
5680  // };
5681 
5682 
5683  //set height of rows
5684 
5685  Row.prototype.setHeight = function (height, force) {
5686 
5687  if (this.height != height || force) {
5688 
5689  this.manualHeight = true;
5690 
5691  this.height = height;
5692 
5693  this.heightStyled = height ? height + "px" : "";
5694 
5695  this.setCellHeight();
5696 
5697  // this.outerHeight = this.element.outerHeight();
5698 
5699  this.outerHeight = this.element.offsetHeight;
5700  }
5701  };
5702 
5703  //return rows outer height
5704 
5705  Row.prototype.getHeight = function () {
5706 
5707  return this.outerHeight;
5708  };
5709 
5710  //return rows outer Width
5711 
5712  Row.prototype.getWidth = function () {
5713 
5714  return this.element.offsetWidth;
5715  };
5716 
5718 
5719 
5720  Row.prototype.deleteCell = function (cell) {
5721 
5722  var index = this.cells.indexOf(cell);
5723 
5724  if (index > -1) {
5725 
5726  this.cells.splice(index, 1);
5727  }
5728  };
5729 
5731 
5732 
5733  Row.prototype.setData = function (data) {
5734 
5735  if (this.table.modExists("mutator")) {
5736 
5737  data = this.table.modules.mutator.transformRow(data, "data", data);
5738  }
5739 
5740  this.data = data;
5741 
5742  if (this.table.options.reactiveData && this.table.modExists("reactiveData", true)) {
5743 
5744  this.table.modules.reactiveData.watchRow(this);
5745  }
5746  };
5747 
5748  //update the rows data
5749 
5750  Row.prototype.updateData = function (data) {
5751  var _this13 = this;
5752 
5753  var visible = Tabulator.prototype.helpers.elVisible(this.element),
5754  tempData = {};
5755 
5756  return new Promise(function (resolve, reject) {
5757 
5758  if (typeof data === "string") {
5759 
5760  data = JSON.parse(data);
5761  }
5762 
5763  if (_this13.table.options.reactiveData && _this13.table.modExists("reactiveData", true)) {
5764 
5765  _this13.table.modules.reactiveData.block();
5766  }
5767 
5768  //mutate incomming data if needed
5769 
5770  if (_this13.table.modExists("mutator")) {
5771 
5772  tempData = Object.assign(tempData, _this13.data);
5773 
5774  tempData = Object.assign(tempData, data);
5775 
5776  data = _this13.table.modules.mutator.transformRow(tempData, "data", data);
5777  }
5778 
5779  //set data
5780 
5781  for (var attrname in data) {
5782 
5783  _this13.data[attrname] = data[attrname];
5784  }
5785 
5786  if (_this13.table.options.reactiveData && _this13.table.modExists("reactiveData", true)) {
5787 
5788  _this13.table.modules.reactiveData.unblock();
5789  }
5790 
5791  //update affected cells only
5792 
5793  for (var attrname in data) {
5794 
5795  var columns = _this13.table.columnManager.getColumnsByFieldRoot(attrname);
5796 
5797  columns.forEach(function (column) {
5798 
5799  var cell = _this13.getCell(column.getField());
5800 
5801  if (cell) {
5802 
5803  var value = column.getFieldValue(data);
5804 
5805  if (cell.getValue() != value) {
5806 
5807  cell.setValueProcessData(value);
5808 
5809  if (visible) {
5810 
5811  cell.cellRendered();
5812  }
5813  }
5814  }
5815  });
5816  }
5817 
5818  //Partial reinitialization if visible
5819 
5820  if (visible) {
5821 
5822  _this13.normalizeHeight();
5823 
5824  if (_this13.table.options.rowFormatter) {
5825 
5826  _this13.table.options.rowFormatter(_this13.getComponent());
5827  }
5828  } else {
5829 
5830  _this13.initialized = false;
5831 
5832  _this13.height = 0;
5833 
5834  _this13.heightStyled = "";
5835  }
5836 
5837  if (_this13.table.options.dataTree !== false && _this13.table.modExists("dataTree") && _this13.table.modules.dataTree.redrawNeeded(data)) {
5838 
5839  _this13.table.modules.dataTree.initializeRow(_this13);
5840 
5841  _this13.table.modules.dataTree.layoutRow(_this13);
5842 
5843  _this13.table.rowManager.refreshActiveData("tree", false, true);
5844  }
5845 
5846  //this.reinitialize();
5847 
5848 
5849  _this13.table.options.rowUpdated.call(_this13.table, _this13.getComponent());
5850 
5851  resolve();
5852  });
5853  };
5854 
5855  Row.prototype.getData = function (transform) {
5856 
5857  var self = this;
5858 
5859  if (transform) {
5860 
5861  if (self.table.modExists("accessor")) {
5862 
5863  return self.table.modules.accessor.transformRow(self.data, transform);
5864  }
5865  } else {
5866 
5867  return this.data;
5868  }
5869  };
5870 
5871  Row.prototype.getCell = function (column) {
5872 
5873  var match = false;
5874 
5875  column = this.table.columnManager.findColumn(column);
5876 
5877  match = this.cells.find(function (cell) {
5878 
5879  return cell.column === column;
5880  });
5881 
5882  return match;
5883  };
5884 
5885  Row.prototype.getCellIndex = function (findCell) {
5886 
5887  return this.cells.findIndex(function (cell) {
5888 
5889  return cell === findCell;
5890  });
5891  };
5892 
5893  Row.prototype.findNextEditableCell = function (index) {
5894 
5895  var nextCell = false;
5896 
5897  if (index < this.cells.length - 1) {
5898 
5899  for (var i = index + 1; i < this.cells.length; i++) {
5900 
5901  var cell = this.cells[i];
5902 
5903  if (cell.column.modules.edit && Tabulator.prototype.helpers.elVisible(cell.getElement())) {
5904 
5905  var allowEdit = true;
5906 
5907  if (typeof cell.column.modules.edit.check == "function") {
5908 
5909  allowEdit = cell.column.modules.edit.check(cell.getComponent());
5910  }
5911 
5912  if (allowEdit) {
5913 
5914  nextCell = cell;
5915 
5916  break;
5917  }
5918  }
5919  }
5920  }
5921 
5922  return nextCell;
5923  };
5924 
5925  Row.prototype.findPrevEditableCell = function (index) {
5926 
5927  var prevCell = false;
5928 
5929  if (index > 0) {
5930 
5931  for (var i = index - 1; i >= 0; i--) {
5932 
5933  var cell = this.cells[i],
5934  allowEdit = true;
5935 
5936  if (cell.column.modules.edit && Tabulator.prototype.helpers.elVisible(cell.getElement())) {
5937 
5938  if (typeof cell.column.modules.edit.check == "function") {
5939 
5940  allowEdit = cell.column.modules.edit.check(cell.getComponent());
5941  }
5942 
5943  if (allowEdit) {
5944 
5945  prevCell = cell;
5946 
5947  break;
5948  }
5949  }
5950  }
5951  }
5952 
5953  return prevCell;
5954  };
5955 
5956  Row.prototype.getCells = function () {
5957 
5958  return this.cells;
5959  };
5960 
5961  Row.prototype.nextRow = function () {
5962 
5963  var row = this.table.rowManager.nextDisplayRow(this, true);
5964 
5965  return row || false;
5966  };
5967 
5968  Row.prototype.prevRow = function () {
5969 
5970  var row = this.table.rowManager.prevDisplayRow(this, true);
5971 
5972  return row || false;
5973  };
5974 
5975  Row.prototype.moveToRow = function (to, before) {
5976 
5977  var toRow = this.table.rowManager.findRow(to);
5978 
5979  if (toRow) {
5980 
5981  this.table.rowManager.moveRowActual(this, toRow, !before);
5982 
5983  this.table.rowManager.refreshActiveData("display", false, true);
5984  } else {
5985 
5986  console.warn("Move Error - No matching row found:", to);
5987  }
5988  };
5989 
5991 
5992 
5993  Row.prototype.delete = function () {
5994  var _this14 = this;
5995 
5996  return new Promise(function (resolve, reject) {
5997 
5998  var index, rows;
5999 
6000  if (_this14.table.options.history && _this14.table.modExists("history")) {
6001 
6002  if (_this14.table.options.groupBy && _this14.table.modExists("groupRows")) {
6003 
6004  rows = _this14.getGroup().rows;
6005 
6006  index = rows.indexOf(_this14);
6007 
6008  if (index) {
6009 
6010  index = rows[index - 1];
6011  }
6012  } else {
6013 
6014  index = _this14.table.rowManager.getRowIndex(_this14);
6015 
6016  if (index) {
6017 
6018  index = _this14.table.rowManager.rows[index - 1];
6019  }
6020  }
6021 
6022  _this14.table.modules.history.action("rowDelete", _this14, { data: _this14.getData(), pos: !index, index: index });
6023  }
6024 
6025  _this14.deleteActual();
6026 
6027  resolve();
6028  });
6029  };
6030 
6031  Row.prototype.deleteActual = function (blockRedraw) {
6032 
6033  var index = this.table.rowManager.getRowIndex(this);
6034 
6035  //deselect row if it is selected
6036 
6037  if (this.table.modExists("selectRow")) {
6038 
6039  this.table.modules.selectRow._deselectRow(this, true);
6040  }
6041 
6042  // if(this.table.options.dataTree && this.table.modExists("dataTree")){
6043 
6044  // this.table.modules.dataTree.collapseRow(this, true);
6045 
6046  // }
6047 
6048 
6049  //remove any reactive data watchers from row object
6050 
6051  if (this.table.options.reactiveData && this.table.modExists("reactiveData", true)) {}
6052 
6053  // this.table.modules.reactiveData.unwatchRow(this);
6054 
6055  //remove from group
6056 
6057  if (this.modules.group) {
6058 
6059  this.modules.group.removeRow(this);
6060  }
6061 
6062  this.table.rowManager.deleteRow(this, blockRedraw);
6063 
6064  this.deleteCells();
6065 
6066  this.initialized = false;
6067 
6068  this.heightInitialized = false;
6069 
6070  //recalc column calculations if present
6071 
6072  if (this.table.modExists("columnCalcs")) {
6073 
6074  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
6075 
6076  this.table.modules.columnCalcs.recalcRowGroup(this);
6077  } else {
6078 
6079  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
6080  }
6081  }
6082  };
6083 
6084  Row.prototype.deleteCells = function () {
6085 
6086  var cellCount = this.cells.length;
6087 
6088  for (var i = 0; i < cellCount; i++) {
6089 
6090  this.cells[0].delete();
6091  }
6092  };
6093 
6094  Row.prototype.wipe = function () {
6095 
6096  this.deleteCells();
6097 
6098  while (this.element.firstChild) {
6099  this.element.removeChild(this.element.firstChild);
6100  }this.element = false;
6101 
6102  this.modules = {};
6103 
6104  if (this.element.parentNode) {
6105 
6106  this.element.parentNode.removeChild(this.element);
6107  }
6108  };
6109 
6110  Row.prototype.getGroup = function () {
6111 
6112  return this.modules.group || false;
6113  };
6114 
6116 
6117  Row.prototype.getComponent = function () {
6118 
6119  return new RowComponent(this);
6120  };
6121 
6122  //public row object
6123 
6124  var CellComponent = function CellComponent(cell) {
6125 
6126  this._cell = cell;
6127  };
6128 
6129  CellComponent.prototype.getValue = function () {
6130 
6131  return this._cell.getValue();
6132  };
6133 
6134  CellComponent.prototype.getOldValue = function () {
6135 
6136  return this._cell.getOldValue();
6137  };
6138 
6139  CellComponent.prototype.getElement = function () {
6140 
6141  return this._cell.getElement();
6142  };
6143 
6144  CellComponent.prototype.getRow = function () {
6145 
6146  return this._cell.row.getComponent();
6147  };
6148 
6149  CellComponent.prototype.getData = function () {
6150 
6151  return this._cell.row.getData();
6152  };
6153 
6154  CellComponent.prototype.getField = function () {
6155 
6156  return this._cell.column.getField();
6157  };
6158 
6159  CellComponent.prototype.getColumn = function () {
6160 
6161  return this._cell.column.getComponent();
6162  };
6163 
6164  CellComponent.prototype.setValue = function (value, mutate) {
6165 
6166  if (typeof mutate == "undefined") {
6167 
6168  mutate = true;
6169  }
6170 
6171  this._cell.setValue(value, mutate);
6172  };
6173 
6174  CellComponent.prototype.restoreOldValue = function () {
6175 
6176  this._cell.setValueActual(this._cell.getOldValue());
6177  };
6178 
6179  CellComponent.prototype.edit = function (force) {
6180 
6181  return this._cell.edit(force);
6182  };
6183 
6184  CellComponent.prototype.cancelEdit = function () {
6185 
6186  this._cell.cancelEdit();
6187  };
6188 
6189  CellComponent.prototype.nav = function () {
6190 
6191  return this._cell.nav();
6192  };
6193 
6194  CellComponent.prototype.checkHeight = function () {
6195 
6196  this._cell.checkHeight();
6197  };
6198 
6199  CellComponent.prototype.getTable = function () {
6200 
6201  return this._cell.table;
6202  };
6203 
6204  CellComponent.prototype._getSelf = function () {
6205 
6206  return this._cell;
6207  };
6208 
6209  var Cell = function Cell(column, row) {
6210 
6211  this.table = column.table;
6212 
6213  this.column = column;
6214 
6215  this.row = row;
6216 
6217  this.element = null;
6218 
6219  this.value = null;
6220 
6221  this.oldValue = null;
6222 
6223  this.modules = {};
6224 
6225  this.height = null;
6226 
6227  this.width = null;
6228 
6229  this.minWidth = null;
6230 
6231  this.build();
6232  };
6233 
6235 
6236 
6237  //generate element
6238 
6239  Cell.prototype.build = function () {
6240 
6241  this.generateElement();
6242 
6243  this.setWidth();
6244 
6245  this._configureCell();
6246 
6247  this.setValueActual(this.column.getFieldValue(this.row.data));
6248  };
6249 
6250  Cell.prototype.generateElement = function () {
6251 
6252  this.element = document.createElement('div');
6253 
6254  this.element.className = "tabulator-cell";
6255 
6256  this.element.setAttribute("role", "gridcell");
6257 
6258  this.element = this.element;
6259  };
6260 
6261  Cell.prototype._configureCell = function () {
6262 
6263  var self = this,
6264  cellEvents = self.column.cellEvents,
6265  element = self.element,
6266  field = this.column.getField();
6267 
6268  //set text alignment
6269 
6270  element.style.textAlign = self.column.hozAlign;
6271 
6272  if (field) {
6273 
6274  element.setAttribute("tabulator-field", field);
6275  }
6276 
6277  //add class to cell if needed
6278 
6279  if (self.column.definition.cssClass) {
6280 
6281  var classNames = self.column.definition.cssClass.split(" ");
6282 
6283  classNames.forEach(function (className) {
6284 
6285  element.classList.add(className);
6286  });
6287  }
6288 
6289  //update tooltip on mouse enter
6290 
6291  if (this.table.options.tooltipGenerationMode === "hover") {
6292 
6293  element.addEventListener("mouseenter", function (e) {
6294 
6295  self._generateTooltip();
6296  });
6297  }
6298 
6299  self._bindClickEvents(cellEvents);
6300 
6301  self._bindTouchEvents(cellEvents);
6302 
6303  self._bindMouseEvents(cellEvents);
6304 
6305  if (self.column.modules.edit) {
6306 
6307  self.table.modules.edit.bindEditor(self);
6308  }
6309 
6310  if (self.column.definition.rowHandle && self.table.options.movableRows !== false && self.table.modExists("moveRow")) {
6311 
6312  self.table.modules.moveRow.initializeCell(self);
6313  }
6314 
6315  //hide cell if not visible
6316 
6317  if (!self.column.visible) {
6318 
6319  self.hide();
6320  }
6321  };
6322 
6323  Cell.prototype._bindClickEvents = function (cellEvents) {
6324 
6325  var self = this,
6326  element = self.element;
6327 
6328  //set event bindings
6329 
6330  if (cellEvents.cellClick || self.table.options.cellClick) {
6331 
6332  element.addEventListener("click", function (e) {
6333 
6334  var component = self.getComponent();
6335 
6336  if (cellEvents.cellClick) {
6337 
6338  cellEvents.cellClick.call(self.table, e, component);
6339  }
6340 
6341  if (self.table.options.cellClick) {
6342 
6343  self.table.options.cellClick.call(self.table, e, component);
6344  }
6345  });
6346  }
6347 
6348  if (cellEvents.cellDblClick || this.table.options.cellDblClick) {
6349 
6350  element.addEventListener("dblclick", function (e) {
6351 
6352  var component = self.getComponent();
6353 
6354  if (cellEvents.cellDblClick) {
6355 
6356  cellEvents.cellDblClick.call(self.table, e, component);
6357  }
6358 
6359  if (self.table.options.cellDblClick) {
6360 
6361  self.table.options.cellDblClick.call(self.table, e, component);
6362  }
6363  });
6364  } else {
6365 
6366  element.addEventListener("dblclick", function (e) {
6367 
6368  e.preventDefault();
6369 
6370  try {
6371 
6372  if (document.selection) {
6373  // IE
6374 
6375  var range = document.body.createTextRange();
6376 
6377  range.moveToElementText(self.element);
6378 
6379  range.select();
6380  } else if (window.getSelection) {
6381 
6382  var range = document.createRange();
6383 
6384  range.selectNode(self.element);
6385 
6386  window.getSelection().removeAllRanges();
6387 
6388  window.getSelection().addRange(range);
6389  }
6390  } catch (e) {}
6391  });
6392  }
6393 
6394  if (cellEvents.cellContext || this.table.options.cellContext) {
6395 
6396  element.addEventListener("contextmenu", function (e) {
6397 
6398  var component = self.getComponent();
6399 
6400  if (cellEvents.cellContext) {
6401 
6402  cellEvents.cellContext.call(self.table, e, component);
6403  }
6404 
6405  if (self.table.options.cellContext) {
6406 
6407  self.table.options.cellContext.call(self.table, e, component);
6408  }
6409  });
6410  }
6411  };
6412 
6413  Cell.prototype._bindMouseEvents = function (cellEvents) {
6414 
6415  var self = this,
6416  element = self.element;
6417 
6418  if (cellEvents.cellMouseEnter || self.table.options.cellMouseEnter) {
6419 
6420  element.addEventListener("mouseenter", function (e) {
6421 
6422  var component = self.getComponent();
6423 
6424  if (cellEvents.cellMouseEnter) {
6425 
6426  cellEvents.cellMouseEnter.call(self.table, e, component);
6427  }
6428 
6429  if (self.table.options.cellMouseEnter) {
6430 
6431  self.table.options.cellMouseEnter.call(self.table, e, component);
6432  }
6433  });
6434  }
6435 
6436  if (cellEvents.cellMouseLeave || self.table.options.cellMouseLeave) {
6437 
6438  element.addEventListener("mouseleave", function (e) {
6439 
6440  var component = self.getComponent();
6441 
6442  if (cellEvents.cellMouseLeave) {
6443 
6444  cellEvents.cellMouseLeave.call(self.table, e, component);
6445  }
6446 
6447  if (self.table.options.cellMouseLeave) {
6448 
6449  self.table.options.cellMouseLeave.call(self.table, e, component);
6450  }
6451  });
6452  }
6453 
6454  if (cellEvents.cellMouseOver || self.table.options.cellMouseOver) {
6455 
6456  element.addEventListener("mouseover", function (e) {
6457 
6458  var component = self.getComponent();
6459 
6460  if (cellEvents.cellMouseOver) {
6461 
6462  cellEvents.cellMouseOver.call(self.table, e, component);
6463  }
6464 
6465  if (self.table.options.cellMouseOver) {
6466 
6467  self.table.options.cellMouseOver.call(self.table, e, component);
6468  }
6469  });
6470  }
6471 
6472  if (cellEvents.cellMouseOut || self.table.options.cellMouseOut) {
6473 
6474  element.addEventListener("mouseout", function (e) {
6475 
6476  var component = self.getComponent();
6477 
6478  if (cellEvents.cellMouseOut) {
6479 
6480  cellEvents.cellMouseOut.call(self.table, e, component);
6481  }
6482 
6483  if (self.table.options.cellMouseOut) {
6484 
6485  self.table.options.cellMouseOut.call(self.table, e, component);
6486  }
6487  });
6488  }
6489 
6490  if (cellEvents.cellMouseMove || self.table.options.cellMouseMove) {
6491 
6492  element.addEventListener("mousemove", function (e) {
6493 
6494  var component = self.getComponent();
6495 
6496  if (cellEvents.cellMouseMove) {
6497 
6498  cellEvents.cellMouseMove.call(self.table, e, component);
6499  }
6500 
6501  if (self.table.options.cellMouseMove) {
6502 
6503  self.table.options.cellMouseMove.call(self.table, e, component);
6504  }
6505  });
6506  }
6507  };
6508 
6509  Cell.prototype._bindTouchEvents = function (cellEvents) {
6510 
6511  var self = this,
6512  element = self.element,
6513  dblTap,
6514  tapHold,
6515  tap;
6516 
6517  if (cellEvents.cellTap || this.table.options.cellTap) {
6518 
6519  tap = false;
6520 
6521  element.addEventListener("touchstart", function (e) {
6522 
6523  tap = true;
6524  }, { passive: true });
6525 
6526  element.addEventListener("touchend", function (e) {
6527 
6528  if (tap) {
6529 
6530  var component = self.getComponent();
6531 
6532  if (cellEvents.cellTap) {
6533 
6534  cellEvents.cellTap.call(self.table, e, component);
6535  }
6536 
6537  if (self.table.options.cellTap) {
6538 
6539  self.table.options.cellTap.call(self.table, e, component);
6540  }
6541  }
6542 
6543  tap = false;
6544  });
6545  }
6546 
6547  if (cellEvents.cellDblTap || this.table.options.cellDblTap) {
6548 
6549  dblTap = null;
6550 
6551  element.addEventListener("touchend", function (e) {
6552 
6553  if (dblTap) {
6554 
6555  clearTimeout(dblTap);
6556 
6557  dblTap = null;
6558 
6559  var component = self.getComponent();
6560 
6561  if (cellEvents.cellDblTap) {
6562 
6563  cellEvents.cellDblTap.call(self.table, e, component);
6564  }
6565 
6566  if (self.table.options.cellDblTap) {
6567 
6568  self.table.options.cellDblTap.call(self.table, e, component);
6569  }
6570  } else {
6571 
6572  dblTap = setTimeout(function () {
6573 
6574  clearTimeout(dblTap);
6575 
6576  dblTap = null;
6577  }, 300);
6578  }
6579  });
6580  }
6581 
6582  if (cellEvents.cellTapHold || this.table.options.cellTapHold) {
6583 
6584  tapHold = null;
6585 
6586  element.addEventListener("touchstart", function (e) {
6587 
6588  clearTimeout(tapHold);
6589 
6590  tapHold = setTimeout(function () {
6591 
6592  clearTimeout(tapHold);
6593 
6594  tapHold = null;
6595 
6596  tap = false;
6597 
6598  var component = self.getComponent();
6599 
6600  if (cellEvents.cellTapHold) {
6601 
6602  cellEvents.cellTapHold.call(self.table, e, component);
6603  }
6604 
6605  if (self.table.options.cellTapHold) {
6606 
6607  self.table.options.cellTapHold.call(self.table, e, component);
6608  }
6609  }, 1000);
6610  }, { passive: true });
6611 
6612  element.addEventListener("touchend", function (e) {
6613 
6614  clearTimeout(tapHold);
6615 
6616  tapHold = null;
6617  });
6618  }
6619  };
6620 
6621  //generate cell contents
6622 
6623  Cell.prototype._generateContents = function () {
6624 
6625  var val;
6626 
6627  if (this.table.modExists("format")) {
6628 
6629  val = this.table.modules.format.formatValue(this);
6630  } else {
6631 
6632  val = this.element.innerHTML = this.value;
6633  }
6634 
6635  switch (typeof val === 'undefined' ? 'undefined' : _typeof(val)) {
6636 
6637  case "object":
6638 
6639  if (val instanceof Node) {
6640 
6641  //clear previous cell contents
6642 
6643  while (this.element.firstChild) {
6644  this.element.removeChild(this.element.firstChild);
6645  }this.element.appendChild(val);
6646  } else {
6647 
6648  this.element.innerHTML = "";
6649 
6650  if (val != null) {
6651 
6652  console.warn("Format Error - Formatter has returned a type of object, the only valid formatter object return is an instance of Node, the formatter returned:", val);
6653  }
6654  }
6655 
6656  break;
6657 
6658  case "undefined":
6659 
6660  case "null":
6661 
6662  this.element.innerHTML = "";
6663 
6664  break;
6665 
6666  default:
6667 
6668  this.element.innerHTML = val;
6669 
6670  }
6671  };
6672 
6673  Cell.prototype.cellRendered = function () {
6674 
6675  if (this.table.modExists("format") && this.table.modules.format.cellRendered) {
6676 
6677  this.table.modules.format.cellRendered(this);
6678  }
6679  };
6680 
6681  //generate tooltip text
6682 
6683  Cell.prototype._generateTooltip = function () {
6684 
6685  var tooltip = this.column.tooltip;
6686 
6687  if (tooltip) {
6688 
6689  if (tooltip === true) {
6690 
6691  tooltip = this.value;
6692  } else if (typeof tooltip == "function") {
6693 
6694  tooltip = tooltip(this.getComponent());
6695 
6696  if (tooltip === false) {
6697 
6698  tooltip = "";
6699  }
6700  }
6701 
6702  if (typeof tooltip === "undefined") {
6703 
6704  tooltip = "";
6705  }
6706 
6707  this.element.setAttribute("title", tooltip);
6708  } else {
6709 
6710  this.element.setAttribute("title", "");
6711  }
6712  };
6713 
6715 
6716  Cell.prototype.getElement = function () {
6717 
6718  return this.element;
6719  };
6720 
6721  Cell.prototype.getValue = function () {
6722 
6723  return this.value;
6724  };
6725 
6726  Cell.prototype.getOldValue = function () {
6727 
6728  return this.oldValue;
6729  };
6730 
6732 
6733 
6734  Cell.prototype.setValue = function (value, mutate) {
6735 
6736  var changed = this.setValueProcessData(value, mutate),
6737  component;
6738 
6739  if (changed) {
6740 
6741  if (this.table.options.history && this.table.modExists("history")) {
6742 
6743  this.table.modules.history.action("cellEdit", this, { oldValue: this.oldValue, newValue: this.value });
6744  }
6745 
6746  component = this.getComponent();
6747 
6748  if (this.column.cellEvents.cellEdited) {
6749 
6750  this.column.cellEvents.cellEdited.call(this.table, component);
6751  }
6752 
6753  this.table.options.cellEdited.call(this.table, component);
6754 
6755  this.table.options.dataEdited.call(this.table, this.table.rowManager.getData());
6756  }
6757  };
6758 
6759  Cell.prototype.setValueProcessData = function (value, mutate) {
6760 
6761  var changed = false;
6762 
6763  if (this.value != value) {
6764 
6765  changed = true;
6766 
6767  if (mutate) {
6768 
6769  if (this.column.modules.mutate) {
6770 
6771  value = this.table.modules.mutator.transformCell(this, value);
6772  }
6773  }
6774  }
6775 
6776  this.setValueActual(value);
6777 
6778  if (changed && this.table.modExists("columnCalcs")) {
6779 
6780  if (this.column.definition.topCalc || this.column.definition.bottomCalc) {
6781 
6782  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
6783 
6784  if (this.table.options.columnCalcs == "table" || this.table.options.columnCalcs == "both") {
6785 
6786  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
6787  }
6788 
6789  if (this.table.options.columnCalcs != "table") {
6790 
6791  this.table.modules.columnCalcs.recalcRowGroup(this.row);
6792  }
6793  } else {
6794 
6795  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
6796  }
6797  }
6798  }
6799 
6800  return changed;
6801  };
6802 
6803  Cell.prototype.setValueActual = function (value) {
6804 
6805  this.oldValue = this.value;
6806 
6807  this.value = value;
6808 
6809  if (this.table.options.reactiveData && this.table.modExists("reactiveData")) {
6810 
6811  this.table.modules.reactiveData.block();
6812  }
6813 
6814  this.column.setFieldValue(this.row.data, value);
6815 
6816  if (this.table.options.reactiveData && this.table.modExists("reactiveData")) {
6817 
6818  this.table.modules.reactiveData.unblock();
6819  }
6820 
6821  this._generateContents();
6822 
6823  this._generateTooltip();
6824 
6825  //set resizable handles
6826 
6827  if (this.table.options.resizableColumns && this.table.modExists("resizeColumns")) {
6828 
6829  this.table.modules.resizeColumns.initializeColumn("cell", this.column, this.element);
6830  }
6831 
6832  //handle frozen cells
6833 
6834  if (this.table.modExists("frozenColumns")) {
6835 
6836  this.table.modules.frozenColumns.layoutElement(this.element, this.column);
6837  }
6838  };
6839 
6840  Cell.prototype.setWidth = function () {
6841 
6842  this.width = this.column.width;
6843 
6844  this.element.style.width = this.column.widthStyled;
6845  };
6846 
6847  Cell.prototype.clearWidth = function () {
6848 
6849  this.width = "";
6850 
6851  this.element.style.width = "";
6852  };
6853 
6854  Cell.prototype.getWidth = function () {
6855 
6856  return this.width || this.element.offsetWidth;
6857  };
6858 
6859  Cell.prototype.setMinWidth = function () {
6860 
6861  this.minWidth = this.column.minWidth;
6862 
6863  this.element.style.minWidth = this.column.minWidthStyled;
6864  };
6865 
6866  Cell.prototype.checkHeight = function () {
6867 
6868  // var height = this.element.css("height");
6869 
6870  this.row.reinitializeHeight();
6871  };
6872 
6873  Cell.prototype.clearHeight = function () {
6874 
6875  this.element.style.height = "";
6876 
6877  this.height = null;
6878  };
6879 
6880  Cell.prototype.setHeight = function () {
6881 
6882  this.height = this.row.height;
6883 
6884  this.element.style.height = this.row.heightStyled;
6885  };
6886 
6887  Cell.prototype.getHeight = function () {
6888 
6889  return this.height || this.element.offsetHeight;
6890  };
6891 
6892  Cell.prototype.show = function () {
6893 
6894  this.element.style.display = "";
6895  };
6896 
6897  Cell.prototype.hide = function () {
6898 
6899  this.element.style.display = "none";
6900  };
6901 
6902  Cell.prototype.edit = function (force) {
6903 
6904  if (this.table.modExists("edit", true)) {
6905 
6906  return this.table.modules.edit.editCell(this, force);
6907  }
6908  };
6909 
6910  Cell.prototype.cancelEdit = function () {
6911 
6912  if (this.table.modExists("edit", true)) {
6913 
6914  var editing = this.table.modules.edit.getCurrentCell();
6915 
6916  if (editing && editing._getSelf() === this) {
6917 
6918  this.table.modules.edit.cancelEdit();
6919  } else {
6920 
6921  console.warn("Cancel Editor Error - This cell is not currently being edited ");
6922  }
6923  }
6924  };
6925 
6926  Cell.prototype.delete = function () {
6927 
6928  if (!this.table.rowManager.redrawBlock) {
6929 
6930  this.element.parentNode.removeChild(this.element);
6931  }
6932 
6933  this.element = false;
6934 
6935  this.column.deleteCell(this);
6936 
6937  this.row.deleteCell(this);
6938 
6939  this.calcs = {};
6940  };
6941 
6943 
6944 
6945  Cell.prototype.nav = function () {
6946 
6947  var self = this,
6948  nextCell = false,
6949  index = this.row.getCellIndex(this);
6950 
6951  return {
6952 
6953  next: function next() {
6954 
6955  var nextCell = this.right(),
6956  nextRow;
6957 
6958  if (!nextCell) {
6959 
6960  nextRow = self.table.rowManager.nextDisplayRow(self.row, true);
6961 
6962  if (nextRow) {
6963 
6964  nextCell = nextRow.findNextEditableCell(-1);
6965 
6966  if (nextCell) {
6967 
6968  nextCell.edit();
6969 
6970  return true;
6971  }
6972  }
6973  } else {
6974 
6975  return true;
6976  }
6977 
6978  return false;
6979  },
6980 
6981  prev: function prev() {
6982 
6983  var nextCell = this.left(),
6984  prevRow;
6985 
6986  if (!nextCell) {
6987 
6988  prevRow = self.table.rowManager.prevDisplayRow(self.row, true);
6989 
6990  if (prevRow) {
6991 
6992  nextCell = prevRow.findPrevEditableCell(prevRow.cells.length);
6993 
6994  if (nextCell) {
6995 
6996  nextCell.edit();
6997 
6998  return true;
6999  }
7000  }
7001  } else {
7002 
7003  return true;
7004  }
7005 
7006  return false;
7007  },
7008 
7009  left: function left() {
7010 
7011  nextCell = self.row.findPrevEditableCell(index);
7012 
7013  if (nextCell) {
7014 
7015  nextCell.edit();
7016 
7017  return true;
7018  } else {
7019 
7020  return false;
7021  }
7022  },
7023 
7024  right: function right() {
7025 
7026  nextCell = self.row.findNextEditableCell(index);
7027 
7028  if (nextCell) {
7029 
7030  nextCell.edit();
7031 
7032  return true;
7033  } else {
7034 
7035  return false;
7036  }
7037  },
7038 
7039  up: function up() {
7040 
7041  var nextRow = self.table.rowManager.prevDisplayRow(self.row, true);
7042 
7043  if (nextRow) {
7044 
7045  nextRow.cells[index].edit();
7046  }
7047  },
7048 
7049  down: function down() {
7050 
7051  var nextRow = self.table.rowManager.nextDisplayRow(self.row, true);
7052 
7053  if (nextRow) {
7054 
7055  nextRow.cells[index].edit();
7056  }
7057  }
7058 
7059  };
7060  };
7061 
7062  Cell.prototype.getIndex = function () {
7063 
7064  this.row.getCellIndex(this);
7065  };
7066 
7068 
7069  Cell.prototype.getComponent = function () {
7070 
7071  return new CellComponent(this);
7072  };
7073 
7074  var FooterManager = function FooterManager(table) {
7075 
7076  this.table = table;
7077 
7078  this.active = false;
7079 
7080  this.element = this.createElement(); //containing element
7081 
7082  this.external = false;
7083 
7084  this.links = [];
7085 
7086  this._initialize();
7087  };
7088 
7089  FooterManager.prototype.createElement = function () {
7090 
7091  var el = document.createElement("div");
7092 
7093  el.classList.add("tabulator-footer");
7094 
7095  return el;
7096  };
7097 
7098  FooterManager.prototype._initialize = function (element) {
7099 
7100  if (this.table.options.footerElement) {
7101 
7102  switch (_typeof(this.table.options.footerElement)) {
7103 
7104  case "string":
7105 
7106  if (this.table.options.footerElement[0] === "<") {
7107 
7108  this.element.innerHTML = this.table.options.footerElement;
7109  } else {
7110 
7111  this.external = true;
7112 
7113  this.element = document.querySelector(this.table.options.footerElement);
7114  }
7115 
7116  break;
7117 
7118  default:
7119 
7120  this.element = this.table.options.footerElement;
7121 
7122  break;
7123 
7124  }
7125  }
7126  };
7127 
7128  FooterManager.prototype.getElement = function () {
7129 
7130  return this.element;
7131  };
7132 
7133  FooterManager.prototype.append = function (element, parent) {
7134 
7135  this.activate(parent);
7136 
7137  this.element.appendChild(element);
7138 
7139  this.table.rowManager.adjustTableSize();
7140  };
7141 
7142  FooterManager.prototype.prepend = function (element, parent) {
7143 
7144  this.activate(parent);
7145 
7146  this.element.insertBefore(element, this.element.firstChild);
7147 
7148  this.table.rowManager.adjustTableSize();
7149  };
7150 
7151  FooterManager.prototype.remove = function (element) {
7152 
7153  element.parentNode.removeChild(element);
7154 
7155  this.deactivate();
7156  };
7157 
7158  FooterManager.prototype.deactivate = function (force) {
7159 
7160  if (!this.element.firstChild || force) {
7161 
7162  if (!this.external) {
7163 
7164  this.element.parentNode.removeChild(this.element);
7165  }
7166 
7167  this.active = false;
7168  }
7169 
7170  // this.table.rowManager.adjustTableSize();
7171  };
7172 
7173  FooterManager.prototype.activate = function (parent) {
7174 
7175  if (!this.active) {
7176 
7177  this.active = true;
7178 
7179  if (!this.external) {
7180 
7181  this.table.element.appendChild(this.getElement());
7182 
7183  this.table.element.style.display = '';
7184  }
7185  }
7186 
7187  if (parent) {
7188 
7189  this.links.push(parent);
7190  }
7191  };
7192 
7193  FooterManager.prototype.redraw = function () {
7194 
7195  this.links.forEach(function (link) {
7196 
7197  link.footerRedraw();
7198  });
7199  };
7200 
7201  var Tabulator = function Tabulator(element, options) {
7202 
7203  this.options = {};
7204 
7205  this.columnManager = null; // hold Column Manager
7206 
7207  this.rowManager = null; //hold Row Manager
7208 
7209  this.footerManager = null; //holder Footer Manager
7210 
7211  this.browser = ""; //hold current browser type
7212 
7213  this.browserSlow = false; //handle reduced functionality for slower browsers
7214 
7215  this.browserMobile = false; //check if running on moble, prevent resize cancelling edit on keyboard appearence
7216 
7217 
7218  this.modules = {}; //hold all modules bound to this table
7219 
7220 
7221  this.initializeElement(element);
7222 
7223  this.initializeOptions(options || {});
7224 
7225  this._create();
7226 
7227  Tabulator.prototype.comms.register(this); //register table for inderdevice communication
7228  };
7229 
7230  //default setup options
7231 
7232  Tabulator.prototype.defaultOptions = {
7233 
7234  height: false, //height of tabulator
7235 
7236 
7237  layout: "fitData",
7238 
7239  layoutColumnsOnNewData: false, //update column widths on setData
7240 
7241 
7242  columnMinWidth: 40, //minimum global width for a column
7243 
7244  columnHeaderVertAlign: "top", //vertical alignment of column headers
7245 
7246  columnVertAlign: false, // DEPRECATED - Left to allow warning
7247 
7248 
7249  resizableColumns: true, //resizable columns
7250 
7251  resizableRows: false, //resizable rows
7252 
7253  autoResize: true, //auto resize table
7254 
7255 
7256  columns: [], //store for colum header info
7257 
7258 
7259  data: [], //default starting data
7260 
7261 
7262  autoColumns: false, //build columns from data row structure
7263 
7264 
7265  reactiveData: false, //enable data reactivity
7266 
7267 
7268  nestedFieldSeparator: ".", //seperatpr for nested data
7269 
7270 
7271  tooltips: false, //Tool tip value
7272 
7273  tooltipsHeader: false, //Tool tip for headers
7274 
7275  tooltipGenerationMode: "load", //when to generate tooltips
7276 
7277 
7278  initialSort: false, //initial sorting criteria
7279 
7280  initialFilter: false, //initial filtering criteria
7281 
7282  initialHeaderFilter: false, //initial header filtering criteria
7283 
7284 
7285  columnHeaderSortMulti: true, //multiple or single column sorting
7286 
7287 
7288  sortOrderReverse: false, //reverse internal sort ordering
7289 
7290 
7291  headerSort: true, //set default global header sort
7292 
7293  headerSortTristate: false, //set default tristate header sorting
7294 
7295 
7296  footerElement: false, //hold footer element
7297 
7298 
7299  index: "id", //filed for row index
7300 
7301 
7302  keybindings: [], //array for keybindings
7303 
7304 
7305  tabEndNewRow: false, //create new row when tab to end of table
7306 
7307 
7308  invalidOptionWarnings: true, //allow toggling of invalid option warnings
7309 
7310 
7311  clipboard: false, //enable clipboard
7312 
7313  clipboardCopyStyled: true, //formatted table data
7314 
7315  clipboardCopySelector: "active", //method of chosing which data is coppied to the clipboard
7316 
7317  clipboardCopyFormatter: "table", //convert data to a clipboard string
7318 
7319  clipboardPasteParser: "table", //convert pasted clipboard data to rows
7320 
7321  clipboardPasteAction: "insert", //how to insert pasted data into the table
7322 
7323  clipboardCopyConfig: false, //clipboard config
7324 
7325 
7326  clipboardCopied: function clipboardCopied() {}, //data has been copied to the clipboard
7327 
7328  clipboardPasted: function clipboardPasted() {}, //data has been pasted into the table
7329 
7330  clipboardPasteError: function clipboardPasteError() {}, //data has not successfully been pasted into the table
7331 
7332 
7333  downloadDataFormatter: false, //function to manipulate table data before it is downloaded
7334 
7335  downloadReady: function downloadReady(data, blob) {
7336  return blob;
7337  }, //function to manipulate download data
7338 
7339  downloadComplete: false, //function to manipulate download data
7340 
7341  downloadConfig: false, //download config
7342 
7343 
7344  dataTree: false, //enable data tree
7345 
7346  dataTreeElementColumn: false,
7347 
7348  dataTreeBranchElement: true, //show data tree branch element
7349 
7350  dataTreeChildIndent: 9, //data tree child indent in px
7351 
7352  dataTreeChildField: "_children", //data tre column field to look for child rows
7353 
7354  dataTreeCollapseElement: false, //data tree row collapse element
7355 
7356  dataTreeExpandElement: false, //data tree row expand element
7357 
7358  dataTreeStartExpanded: false,
7359 
7360  dataTreeRowExpanded: function dataTreeRowExpanded() {}, //row has been expanded
7361 
7362  dataTreeRowCollapsed: function dataTreeRowCollapsed() {}, //row has been collapsed
7363 
7364 
7365  printAsHtml: false, //enable print as html
7366 
7367  printFormatter: false, //printing page formatter
7368 
7369  printHeader: false, //page header contents
7370 
7371  printFooter: false, //page footer contents
7372 
7373  printCopyStyle: true, //enable print as html styling
7374 
7375  printVisibleRows: true, //restrict print to visible rows only
7376 
7377  printConfig: {}, //print config options
7378 
7379 
7380  addRowPos: "bottom", //position to insert blank rows, top|bottom
7381 
7382 
7383  selectable: "highlight", //highlight rows on hover
7384 
7385  selectableRangeMode: "drag", //highlight rows on hover
7386 
7387  selectableRollingSelection: true, //roll selection once maximum number of selectable rows is reached
7388 
7389  selectablePersistence: true, // maintain selection when table view is updated
7390 
7391  selectableCheck: function selectableCheck(data, row) {
7392  return true;
7393  }, //check wheather row is selectable
7394 
7395 
7396  headerFilterPlaceholder: false, //placeholder text to display in header filters
7397 
7398 
7399  headerVisible: true, //hide header
7400 
7401 
7402  history: false, //enable edit history
7403 
7404 
7405  locale: false, //current system language
7406 
7407  langs: {},
7408 
7409  virtualDom: true, //enable DOM virtualization
7410 
7411  virtualDomBuffer: 0, // set virtual DOM buffer size
7412 
7413 
7414  persistentLayout: false, //DEPRICATED - REMOVE in 5.0
7415 
7416  persistentSort: false, //DEPRICATED - REMOVE in 5.0
7417 
7418  persistentFilter: false, //DEPRICATED - REMOVE in 5.0
7419 
7420  persistenceID: "", //key for persistent storage
7421 
7422  persistenceMode: true, //mode for storing persistence information
7423 
7424  persistenceReaderFunc: false, //function for handling persistence data reading
7425 
7426  persistenceWriterFunc: false, //function for handling persistence data writing
7427 
7428 
7429  persistence: false,
7430 
7431  responsiveLayout: false, //responsive layout flags
7432 
7433  responsiveLayoutCollapseStartOpen: true, //start showing collapsed data
7434 
7435  responsiveLayoutCollapseUseFormatters: true, //responsive layout collapse formatter
7436 
7437  responsiveLayoutCollapseFormatter: false, //responsive layout collapse formatter
7438 
7439 
7440  pagination: false, //set pagination type
7441 
7442  paginationSize: false, //set number of rows to a page
7443 
7444  paginationInitialPage: 1, //initail page to show on load
7445 
7446  paginationButtonCount: 5, // set count of page button
7447 
7448  paginationSizeSelector: false, //add pagination size selector element
7449 
7450  paginationElement: false, //element to hold pagination numbers
7451 
7452  paginationDataSent: {}, //pagination data sent to the server
7453 
7454  paginationDataReceived: {}, //pagination data received from the server
7455 
7456  paginationAddRow: "page", //add rows on table or page
7457 
7458 
7459  ajaxURL: false, //url for ajax loading
7460 
7461  ajaxURLGenerator: false,
7462 
7463  ajaxParams: {}, //params for ajax loading
7464 
7465  ajaxConfig: "get", //ajax request type
7466 
7467  ajaxContentType: "form", //ajax request type
7468 
7469  ajaxRequestFunc: false, //promise function
7470 
7471  ajaxLoader: true, //show loader
7472 
7473  ajaxLoaderLoading: false, //loader element
7474 
7475  ajaxLoaderError: false, //loader element
7476 
7477  ajaxFiltering: false,
7478 
7479  ajaxSorting: false,
7480 
7481  ajaxProgressiveLoad: false, //progressive loading
7482 
7483  ajaxProgressiveLoadDelay: 0, //delay between requests
7484 
7485  ajaxProgressiveLoadScrollMargin: 0, //margin before scroll begins
7486 
7487 
7488  groupBy: false, //enable table grouping and set field to group by
7489 
7490  groupStartOpen: true, //starting state of group
7491 
7492  groupValues: false,
7493 
7494  groupHeader: false, //header generation function
7495 
7496 
7497  htmlOutputConfig: false, //html outypu config
7498 
7499 
7500  movableColumns: false, //enable movable columns
7501 
7502 
7503  movableRows: false, //enable movable rows
7504 
7505  movableRowsConnectedTables: false, //tables for movable rows to be connected to
7506 
7507  movableRowsSender: false,
7508 
7509  movableRowsReceiver: "insert",
7510 
7511  movableRowsSendingStart: function movableRowsSendingStart() {},
7512 
7513  movableRowsSent: function movableRowsSent() {},
7514 
7515  movableRowsSentFailed: function movableRowsSentFailed() {},
7516 
7517  movableRowsSendingStop: function movableRowsSendingStop() {},
7518 
7519  movableRowsReceivingStart: function movableRowsReceivingStart() {},
7520 
7521  movableRowsReceived: function movableRowsReceived() {},
7522 
7523  movableRowsReceivedFailed: function movableRowsReceivedFailed() {},
7524 
7525  movableRowsReceivingStop: function movableRowsReceivingStop() {},
7526 
7527  scrollToRowPosition: "top",
7528 
7529  scrollToRowIfVisible: true,
7530 
7531  scrollToColumnPosition: "left",
7532 
7533  scrollToColumnIfVisible: true,
7534 
7535  rowFormatter: false,
7536 
7537  placeholder: false,
7538 
7539  //table building callbacks
7540 
7541  tableBuilding: function tableBuilding() {},
7542 
7543  tableBuilt: function tableBuilt() {},
7544 
7545  //render callbacks
7546 
7547  renderStarted: function renderStarted() {},
7548 
7549  renderComplete: function renderComplete() {},
7550 
7551  //row callbacks
7552 
7553  rowClick: false,
7554 
7555  rowDblClick: false,
7556 
7557  rowContext: false,
7558 
7559  rowTap: false,
7560 
7561  rowDblTap: false,
7562 
7563  rowTapHold: false,
7564 
7565  rowMouseEnter: false,
7566 
7567  rowMouseLeave: false,
7568 
7569  rowMouseOver: false,
7570 
7571  rowMouseOut: false,
7572 
7573  rowMouseMove: false,
7574 
7575  rowAdded: function rowAdded() {},
7576 
7577  rowDeleted: function rowDeleted() {},
7578 
7579  rowMoved: function rowMoved() {},
7580 
7581  rowUpdated: function rowUpdated() {},
7582 
7583  rowSelectionChanged: function rowSelectionChanged() {},
7584 
7585  rowSelected: function rowSelected() {},
7586 
7587  rowDeselected: function rowDeselected() {},
7588 
7589  rowResized: function rowResized() {},
7590 
7591  //cell callbacks
7592 
7593  //row callbacks
7594 
7595  cellClick: false,
7596 
7597  cellDblClick: false,
7598 
7599  cellContext: false,
7600 
7601  cellTap: false,
7602 
7603  cellDblTap: false,
7604 
7605  cellTapHold: false,
7606 
7607  cellMouseEnter: false,
7608 
7609  cellMouseLeave: false,
7610 
7611  cellMouseOver: false,
7612 
7613  cellMouseOut: false,
7614 
7615  cellMouseMove: false,
7616 
7617  cellEditing: function cellEditing() {},
7618 
7619  cellEdited: function cellEdited() {},
7620 
7621  cellEditCancelled: function cellEditCancelled() {},
7622 
7623  //column callbacks
7624 
7625  columnMoved: false,
7626 
7627  columnResized: function columnResized() {},
7628 
7629  columnTitleChanged: function columnTitleChanged() {},
7630 
7631  columnVisibilityChanged: function columnVisibilityChanged() {},
7632 
7633  //HTML iport callbacks
7634 
7635  htmlImporting: function htmlImporting() {},
7636 
7637  htmlImported: function htmlImported() {},
7638 
7639  //data callbacks
7640 
7641  dataLoading: function dataLoading() {},
7642 
7643  dataLoaded: function dataLoaded() {},
7644 
7645  dataEdited: function dataEdited() {},
7646 
7647  //ajax callbacks
7648 
7649  ajaxRequesting: function ajaxRequesting() {},
7650 
7651  ajaxResponse: false,
7652 
7653  ajaxError: function ajaxError() {},
7654 
7655  //filtering callbacks
7656 
7657  dataFiltering: false,
7658 
7659  dataFiltered: false,
7660 
7661  //sorting callbacks
7662 
7663  dataSorting: function dataSorting() {},
7664 
7665  dataSorted: function dataSorted() {},
7666 
7667  //grouping callbacks
7668 
7669  groupToggleElement: "arrow",
7670 
7671  groupClosedShowCalcs: false,
7672 
7673  dataGrouping: function dataGrouping() {},
7674 
7675  dataGrouped: false,
7676 
7677  groupVisibilityChanged: function groupVisibilityChanged() {},
7678 
7679  groupClick: false,
7680 
7681  groupDblClick: false,
7682 
7683  groupContext: false,
7684 
7685  groupTap: false,
7686 
7687  groupDblTap: false,
7688 
7689  groupTapHold: false,
7690 
7691  columnCalcs: true,
7692 
7693  //pagination callbacks
7694 
7695  pageLoaded: function pageLoaded() {},
7696 
7697  //localization callbacks
7698 
7699  localized: function localized() {},
7700 
7701  //validation has failed
7702 
7703  validationFailed: function validationFailed() {},
7704 
7705  //history callbacks
7706 
7707  historyUndo: function historyUndo() {},
7708 
7709  historyRedo: function historyRedo() {},
7710 
7711  //scroll callbacks
7712 
7713  scrollHorizontal: function scrollHorizontal() {},
7714 
7715  scrollVertical: function scrollVertical() {}
7716 
7717  };
7718 
7719  Tabulator.prototype.initializeOptions = function (options) {
7720 
7721  //warn user if option is not available
7722 
7723  if (options.invalidOptionWarnings !== false) {
7724 
7725  for (var key in options) {
7726 
7727  if (typeof this.defaultOptions[key] === "undefined") {
7728 
7729  console.warn("Invalid table constructor option:", key);
7730  }
7731  }
7732  }
7733 
7734  //assign options to table
7735 
7736  for (var key in this.defaultOptions) {
7737 
7738  if (key in options) {
7739 
7740  this.options[key] = options[key];
7741  } else {
7742 
7743  if (Array.isArray(this.defaultOptions[key])) {
7744 
7745  this.options[key] = [];
7746  } else if (_typeof(this.defaultOptions[key]) === "object") {
7747 
7748  this.options[key] = {};
7749  } else {
7750 
7751  this.options[key] = this.defaultOptions[key];
7752  }
7753  }
7754  }
7755  };
7756 
7757  Tabulator.prototype.initializeElement = function (element) {
7758 
7759  if (typeof HTMLElement !== "undefined" && element instanceof HTMLElement) {
7760 
7761  this.element = element;
7762 
7763  return true;
7764  } else if (typeof element === "string") {
7765 
7766  this.element = document.querySelector(element);
7767 
7768  if (this.element) {
7769 
7770  return true;
7771  } else {
7772 
7773  console.error("Tabulator Creation Error - no element found matching selector: ", element);
7774 
7775  return false;
7776  }
7777  } else {
7778 
7779  console.error("Tabulator Creation Error - Invalid element provided:", element);
7780 
7781  return false;
7782  }
7783  };
7784 
7785  //convert depricated functionality to new functions
7786 
7787  Tabulator.prototype._mapDepricatedFunctionality = function () {
7788 
7789  //map depricated persistance setup options
7790 
7791  if (this.options.persistentLayout || this.options.persistentSort || this.options.persistentFilter) {
7792 
7793  if (!this.options.persistence) {
7794 
7795  this.options.persistence = {};
7796  }
7797  }
7798 
7799  if (this.options.persistentLayout) {
7800 
7801  console.warn("persistentLayout option is deprecated, you should now use the persistence option");
7802 
7803  if (this.options.persistence !== true && typeof this.options.persistence.columns === "undefined") {
7804 
7805  this.options.persistence.columns = true;
7806  }
7807  }
7808 
7809  if (this.options.persistentSort) {
7810 
7811  console.warn("persistentSort option is deprecated, you should now use the persistence option");
7812 
7813  if (this.options.persistence !== true && typeof this.options.persistence.sort === "undefined") {
7814 
7815  this.options.persistence.sort = true;
7816  }
7817  }
7818 
7819  if (this.options.persistentFilter) {
7820 
7821  console.warn("persistentFilter option is deprecated, you should now use the persistence option");
7822 
7823  if (this.options.persistence !== true && typeof this.options.persistence.filter === "undefined") {
7824 
7825  this.options.persistence.filter = true;
7826  }
7827  }
7828 
7829  if (this.options.columnVertAlign) {
7830 
7831  console.warn("columnVertAlign option is deprecated, you should now use the columnHeaderVertAlign option");
7832 
7833  this.options.columnHeaderVertAlign = this.options.columnVertAlign;
7834  }
7835  };
7836 
7837  Tabulator.prototype._clearSelection = function () {
7838 
7839  this.element.classList.add("tabulator-block-select");
7840 
7841  if (window.getSelection) {
7842 
7843  if (window.getSelection().empty) {
7844  // Chrome
7845 
7846  window.getSelection().empty();
7847  } else if (window.getSelection().removeAllRanges) {
7848  // Firefox
7849 
7850  window.getSelection().removeAllRanges();
7851  }
7852  } else if (document.selection) {
7853  // IE?
7854 
7855  document.selection.empty();
7856  }
7857 
7858  this.element.classList.remove("tabulator-block-select");
7859  };
7860 
7861  //concreate table
7862 
7863  Tabulator.prototype._create = function () {
7864 
7865  this._clearObjectPointers();
7866 
7867  this._mapDepricatedFunctionality();
7868 
7869  this.bindModules();
7870 
7871  if (this.element.tagName === "TABLE") {
7872 
7873  if (this.modExists("htmlTableImport", true)) {
7874 
7875  this.modules.htmlTableImport.parseTable();
7876  }
7877  }
7878 
7879  this.columnManager = new ColumnManager(this);
7880 
7881  this.rowManager = new RowManager(this);
7882 
7883  this.footerManager = new FooterManager(this);
7884 
7885  this.columnManager.setRowManager(this.rowManager);
7886 
7887  this.rowManager.setColumnManager(this.columnManager);
7888 
7889  this._buildElement();
7890 
7891  this._loadInitialData();
7892  };
7893 
7894  //clear pointers to objects in default config object
7895 
7896  Tabulator.prototype._clearObjectPointers = function () {
7897 
7898  this.options.columns = this.options.columns.slice(0);
7899 
7900  if (!this.options.reactiveData) {
7901 
7902  this.options.data = this.options.data.slice(0);
7903  }
7904  };
7905 
7906  //build tabulator element
7907 
7908  Tabulator.prototype._buildElement = function () {
7909  var _this15 = this;
7910 
7911  var element = this.element,
7912  mod = this.modules,
7913  options = this.options;
7914 
7915  options.tableBuilding.call(this);
7916 
7917  element.classList.add("tabulator");
7918 
7919  element.setAttribute("role", "grid");
7920 
7921  //empty element
7922 
7923  while (element.firstChild) {
7924  element.removeChild(element.firstChild);
7925  } //set table height
7926 
7927  if (options.height) {
7928 
7929  options.height = isNaN(options.height) ? options.height : options.height + "px";
7930 
7931  element.style.height = options.height;
7932  }
7933 
7934  this.columnManager.initialize();
7935 
7936  this.rowManager.initialize();
7937 
7938  this._detectBrowser();
7939 
7940  if (this.modExists("layout", true)) {
7941 
7942  mod.layout.initialize(options.layout);
7943  }
7944 
7945  //set localization
7946 
7947  if (options.headerFilterPlaceholder !== false) {
7948 
7949  mod.localize.setHeaderFilterPlaceholder(options.headerFilterPlaceholder);
7950  }
7951 
7952  for (var locale in options.langs) {
7953 
7954  mod.localize.installLang(locale, options.langs[locale]);
7955  }
7956 
7957  mod.localize.setLocale(options.locale);
7958 
7959  //configure placeholder element
7960 
7961  if (typeof options.placeholder == "string") {
7962 
7963  var el = document.createElement("div");
7964 
7965  el.classList.add("tabulator-placeholder");
7966 
7967  var span = document.createElement("span");
7968 
7969  span.innerHTML = options.placeholder;
7970 
7971  el.appendChild(span);
7972 
7973  options.placeholder = el;
7974  }
7975 
7976  //build table elements
7977 
7978  element.appendChild(this.columnManager.getElement());
7979 
7980  element.appendChild(this.rowManager.getElement());
7981 
7982  if (options.footerElement) {
7983 
7984  this.footerManager.activate();
7985  }
7986 
7987  if (options.persistence && this.modExists("persistence", true)) {
7988 
7989  mod.persistence.initialize();
7990  }
7991 
7992  if (options.persistence && this.modExists("persistence", true) && mod.persistence.config.columns) {
7993 
7994  options.columns = mod.persistence.load("columns", options.columns);
7995  }
7996 
7997  if (options.movableRows && this.modExists("moveRow")) {
7998 
7999  mod.moveRow.initialize();
8000  }
8001 
8002  if (options.autoColumns && this.options.data) {
8003 
8004  this.columnManager.generateColumnsFromRowData(this.options.data);
8005  }
8006 
8007  if (this.modExists("columnCalcs")) {
8008 
8009  mod.columnCalcs.initialize();
8010  }
8011 
8012  this.columnManager.setColumns(options.columns);
8013 
8014  if (options.dataTree && this.modExists("dataTree", true)) {
8015 
8016  mod.dataTree.initialize();
8017  }
8018 
8019  if (this.modExists("frozenRows")) {
8020 
8021  this.modules.frozenRows.initialize();
8022  }
8023 
8024  if ((options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort || options.initialSort) && this.modExists("sort", true)) {
8025 
8026  var sorters = [];
8027 
8028  if (options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort) {
8029 
8030  sorters = mod.persistence.load("sort");
8031 
8032  if (sorters === false && options.initialSort) {
8033 
8034  sorters = options.initialSort;
8035  }
8036  } else if (options.initialSort) {
8037 
8038  sorters = options.initialSort;
8039  }
8040 
8041  mod.sort.setSort(sorters);
8042  }
8043 
8044  if ((options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter || options.initialFilter) && this.modExists("filter", true)) {
8045 
8046  var filters = [];
8047 
8048  if (options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter) {
8049 
8050  filters = mod.persistence.load("filter");
8051 
8052  if (filters === false && options.initialFilter) {
8053 
8054  filters = options.initialFilter;
8055  }
8056  } else if (options.initialFilter) {
8057 
8058  filters = options.initialFilter;
8059  }
8060 
8061  mod.filter.setFilter(filters);
8062  }
8063 
8064  if (options.initialHeaderFilter && this.modExists("filter", true)) {
8065 
8066  options.initialHeaderFilter.forEach(function (item) {
8067 
8068  var column = _this15.columnManager.findColumn(item.field);
8069 
8070  if (column) {
8071 
8072  mod.filter.setHeaderFilterValue(column, item.value);
8073  } else {
8074 
8075  console.warn("Column Filter Error - No matching column found:", item.field);
8076 
8077  return false;
8078  }
8079  });
8080  }
8081 
8082  if (this.modExists("ajax")) {
8083 
8084  mod.ajax.initialize();
8085  }
8086 
8087  if (options.pagination && this.modExists("page", true)) {
8088 
8089  mod.page.initialize();
8090  }
8091 
8092  if (options.groupBy && this.modExists("groupRows", true)) {
8093 
8094  mod.groupRows.initialize();
8095  }
8096 
8097  if (this.modExists("keybindings")) {
8098 
8099  mod.keybindings.initialize();
8100  }
8101 
8102  if (this.modExists("selectRow")) {
8103 
8104  mod.selectRow.clearSelectionData(true);
8105  }
8106 
8107  if (options.autoResize && this.modExists("resizeTable")) {
8108 
8109  mod.resizeTable.initialize();
8110  }
8111 
8112  if (this.modExists("clipboard")) {
8113 
8114  mod.clipboard.initialize();
8115  }
8116 
8117  if (options.printAsHtml && this.modExists("print")) {
8118 
8119  mod.print.initialize();
8120  }
8121 
8122  options.tableBuilt.call(this);
8123  };
8124 
8125  Tabulator.prototype._loadInitialData = function () {
8126 
8127  var self = this;
8128 
8129  if (self.options.pagination && self.modExists("page")) {
8130 
8131  self.modules.page.reset(true);
8132 
8133  if (self.options.pagination == "local") {
8134 
8135  if (self.options.data.length) {
8136 
8137  self.rowManager.setData(self.options.data);
8138  } else {
8139 
8140  if ((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")) {
8141 
8142  self.modules.ajax.loadData().then(function () {}).catch(function () {
8143 
8144  if (self.options.paginationInitialPage) {
8145 
8146  self.modules.page.setPage(self.options.paginationInitialPage);
8147  }
8148  });
8149 
8150  return;
8151  } else {
8152 
8153  self.rowManager.setData(self.options.data);
8154  }
8155  }
8156 
8157  if (self.options.paginationInitialPage) {
8158 
8159  self.modules.page.setPage(self.options.paginationInitialPage);
8160  }
8161  } else {
8162 
8163  if (self.options.ajaxURL) {
8164 
8165  self.modules.page.setPage(self.options.paginationInitialPage).then(function () {}).catch(function () {});
8166  } else {
8167 
8168  self.rowManager.setData([]);
8169  }
8170  }
8171  } else {
8172 
8173  if (self.options.data.length) {
8174 
8175  self.rowManager.setData(self.options.data);
8176  } else {
8177 
8178  if ((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")) {
8179 
8180  self.modules.ajax.loadData().then(function () {}).catch(function () {});
8181  } else {
8182 
8183  self.rowManager.setData(self.options.data);
8184  }
8185  }
8186  }
8187  };
8188 
8189  //deconstructor
8190 
8191  Tabulator.prototype.destroy = function () {
8192 
8193  var element = this.element;
8194 
8195  Tabulator.prototype.comms.deregister(this); //deregister table from inderdevice communication
8196 
8197 
8198  if (this.options.reactiveData && this.modExists("reactiveData", true)) {
8199 
8200  this.modules.reactiveData.unwatchData();
8201  }
8202 
8203  //clear row data
8204 
8205  this.rowManager.rows.forEach(function (row) {
8206 
8207  row.wipe();
8208  });
8209 
8210  this.rowManager.rows = [];
8211 
8212  this.rowManager.activeRows = [];
8213 
8214  this.rowManager.displayRows = [];
8215 
8216  //clear event bindings
8217 
8218  if (this.options.autoResize && this.modExists("resizeTable")) {
8219 
8220  this.modules.resizeTable.clearBindings();
8221  }
8222 
8223  if (this.modExists("keybindings")) {
8224 
8225  this.modules.keybindings.clearBindings();
8226  }
8227 
8228  //clear DOM
8229 
8230  while (element.firstChild) {
8231  element.removeChild(element.firstChild);
8232  }element.classList.remove("tabulator");
8233  };
8234 
8235  Tabulator.prototype._detectBrowser = function () {
8236 
8237  var ua = navigator.userAgent || navigator.vendor || window.opera;
8238 
8239  if (ua.indexOf("Trident") > -1) {
8240 
8241  this.browser = "ie";
8242 
8243  this.browserSlow = true;
8244  } else if (ua.indexOf("Edge") > -1) {
8245 
8246  this.browser = "edge";
8247 
8248  this.browserSlow = true;
8249  } else if (ua.indexOf("Firefox") > -1) {
8250 
8251  this.browser = "firefox";
8252 
8253  this.browserSlow = false;
8254  } else {
8255 
8256  this.browser = "other";
8257 
8258  this.browserSlow = false;
8259  }
8260 
8261  this.browserMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(ua) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(ua.substr(0, 4));
8262  };
8263 
8265 
8266 
8267  //block table redrawing
8268 
8269  Tabulator.prototype.blockRedraw = function () {
8270 
8271  return this.rowManager.blockRedraw();
8272  };
8273 
8274  //restore table redrawing
8275 
8276  Tabulator.prototype.restoreRedraw = function () {
8277 
8278  return this.rowManager.restoreRedraw();
8279  };
8280 
8281  //local data from local file
8282 
8283  Tabulator.prototype.setDataFromLocalFile = function (extensions) {
8284  var _this16 = this;
8285 
8286  return new Promise(function (resolve, reject) {
8287 
8288  var input = document.createElement("input");
8289 
8290  input.type = "file";
8291 
8292  input.accept = extensions || ".json,application/json";
8293 
8294  input.addEventListener("change", function (e) {
8295 
8296  var file = input.files[0],
8297  reader = new FileReader(),
8298  data;
8299 
8300  reader.readAsText(file);
8301 
8302  reader.onload = function (e) {
8303 
8304  try {
8305 
8306  data = JSON.parse(reader.result);
8307  } catch (e) {
8308 
8309  console.warn("File Load Error - File contents is invalid JSON", e);
8310 
8311  reject(e);
8312 
8313  return;
8314  }
8315 
8316  _this16._setData(data).then(function (data) {
8317 
8318  resolve(data);
8319  }).catch(function (err) {
8320 
8321  resolve(err);
8322  });
8323  };
8324 
8325  reader.onerror = function (e) {
8326 
8327  console.warn("File Load Error - Unable to read file");
8328 
8329  reject();
8330  };
8331  });
8332 
8333  input.click();
8334  });
8335  };
8336 
8337  //load data
8338 
8339  Tabulator.prototype.setData = function (data, params, config) {
8340 
8341  if (this.modExists("ajax")) {
8342 
8343  this.modules.ajax.blockActiveRequest();
8344  }
8345 
8346  return this._setData(data, params, config);
8347  };
8348 
8349  Tabulator.prototype._setData = function (data, params, config, inPosition) {
8350 
8351  var self = this;
8352 
8353  if (typeof data === "string") {
8354 
8355  if (data.indexOf("{") == 0 || data.indexOf("[") == 0) {
8356 
8357  //data is a json encoded string
8358 
8359  return self.rowManager.setData(JSON.parse(data), inPosition);
8360  } else {
8361 
8362  if (self.modExists("ajax", true)) {
8363 
8364  if (params) {
8365 
8366  self.modules.ajax.setParams(params);
8367  }
8368 
8369  if (config) {
8370 
8371  self.modules.ajax.setConfig(config);
8372  }
8373 
8374  self.modules.ajax.setUrl(data);
8375 
8376  if (self.options.pagination == "remote" && self.modExists("page", true)) {
8377 
8378  self.modules.page.reset(true);
8379 
8380  return self.modules.page.setPage(1);
8381  } else {
8382 
8383  //assume data is url, make ajax call to url to get data
8384 
8385  return self.modules.ajax.loadData(inPosition);
8386  }
8387  }
8388  }
8389  } else {
8390 
8391  if (data) {
8392 
8393  //asume data is already an object
8394 
8395  return self.rowManager.setData(data, inPosition);
8396  } else {
8397 
8398  //no data provided, check if ajaxURL is present;
8399 
8400  if (self.modExists("ajax") && (self.modules.ajax.getUrl || self.options.ajaxURLGenerator)) {
8401 
8402  if (self.options.pagination == "remote" && self.modExists("page", true)) {
8403 
8404  self.modules.page.reset(true);
8405 
8406  return self.modules.page.setPage(1);
8407  } else {
8408 
8409  return self.modules.ajax.loadData(inPosition);
8410  }
8411  } else {
8412 
8413  //empty data
8414 
8415  return self.rowManager.setData([], inPosition);
8416  }
8417  }
8418  }
8419  };
8420 
8421  //clear data
8422 
8423  Tabulator.prototype.clearData = function () {
8424 
8425  if (this.modExists("ajax")) {
8426 
8427  this.modules.ajax.blockActiveRequest();
8428  }
8429 
8430  this.rowManager.clearData();
8431  };
8432 
8433  //get table data array
8434 
8435  Tabulator.prototype.getData = function (active) {
8436 
8437  if (active === true) {
8438 
8439  console.warn("passing a boolean to the getData function is deprecated, you should now pass the string 'active'");
8440 
8441  active = "active";
8442  }
8443 
8444  return this.rowManager.getData(active);
8445  };
8446 
8447  //get table data array count
8448 
8449  Tabulator.prototype.getDataCount = function (active) {
8450 
8451  if (active === true) {
8452 
8453  console.warn("passing a boolean to the getDataCount function is deprecated, you should now pass the string 'active'");
8454 
8455  active = "active";
8456  }
8457 
8458  return this.rowManager.getDataCount(active);
8459  };
8460 
8461  //search for specific row components
8462 
8463  Tabulator.prototype.searchRows = function (field, type, value) {
8464 
8465  if (this.modExists("filter", true)) {
8466 
8467  return this.modules.filter.search("rows", field, type, value);
8468  }
8469  };
8470 
8471  //search for specific data
8472 
8473  Tabulator.prototype.searchData = function (field, type, value) {
8474 
8475  if (this.modExists("filter", true)) {
8476 
8477  return this.modules.filter.search("data", field, type, value);
8478  }
8479  };
8480 
8481  //get table html
8482 
8483  Tabulator.prototype.getHtml = function (visible, style, config) {
8484 
8485  if (this.modExists("htmlTableExport", true)) {
8486 
8487  return this.modules.htmlTableExport.getHtml(visible, style, config);
8488  }
8489  };
8490 
8491  //get print html
8492 
8493  Tabulator.prototype.print = function (visible, style, config) {
8494 
8495  if (this.modExists("print", true)) {
8496 
8497  return this.modules.print.printFullscreen(visible, style, config);
8498  }
8499  };
8500 
8501  //retrieve Ajax URL
8502 
8503  Tabulator.prototype.getAjaxUrl = function () {
8504 
8505  if (this.modExists("ajax", true)) {
8506 
8507  return this.modules.ajax.getUrl();
8508  }
8509  };
8510 
8511  //replace data, keeping table in position with same sort
8512 
8513  Tabulator.prototype.replaceData = function (data, params, config) {
8514 
8515  if (this.modExists("ajax")) {
8516 
8517  this.modules.ajax.blockActiveRequest();
8518  }
8519 
8520  return this._setData(data, params, config, true);
8521  };
8522 
8523  //update table data
8524 
8525  Tabulator.prototype.updateData = function (data) {
8526  var _this17 = this;
8527 
8528  var self = this;
8529 
8530  var responses = 0;
8531 
8532  return new Promise(function (resolve, reject) {
8533 
8534  if (_this17.modExists("ajax")) {
8535 
8536  _this17.modules.ajax.blockActiveRequest();
8537  }
8538 
8539  if (typeof data === "string") {
8540 
8541  data = JSON.parse(data);
8542  }
8543 
8544  if (data) {
8545 
8546  data.forEach(function (item) {
8547 
8548  var row = self.rowManager.findRow(item[self.options.index]);
8549 
8550  if (row) {
8551 
8552  responses++;
8553 
8554  row.updateData(item).then(function () {
8555 
8556  responses--;
8557 
8558  if (!responses) {
8559 
8560  resolve();
8561  }
8562  });
8563  }
8564  });
8565  } else {
8566 
8567  console.warn("Update Error - No data provided");
8568 
8569  reject("Update Error - No data provided");
8570  }
8571  });
8572  };
8573 
8574  Tabulator.prototype.addData = function (data, pos, index) {
8575  var _this18 = this;
8576 
8577  return new Promise(function (resolve, reject) {
8578 
8579  if (_this18.modExists("ajax")) {
8580 
8581  _this18.modules.ajax.blockActiveRequest();
8582  }
8583 
8584  if (typeof data === "string") {
8585 
8586  data = JSON.parse(data);
8587  }
8588 
8589  if (data) {
8590 
8591  _this18.rowManager.addRows(data, pos, index).then(function (rows) {
8592 
8593  var output = [];
8594 
8595  rows.forEach(function (row) {
8596 
8597  output.push(row.getComponent());
8598  });
8599 
8600  resolve(output);
8601  });
8602  } else {
8603 
8604  console.warn("Update Error - No data provided");
8605 
8606  reject("Update Error - No data provided");
8607  }
8608  });
8609  };
8610 
8611  //update table data
8612 
8613  Tabulator.prototype.updateOrAddData = function (data) {
8614  var _this19 = this;
8615 
8616  var self = this,
8617  rows = [],
8618  responses = 0;
8619 
8620  return new Promise(function (resolve, reject) {
8621 
8622  if (_this19.modExists("ajax")) {
8623 
8624  _this19.modules.ajax.blockActiveRequest();
8625  }
8626 
8627  if (typeof data === "string") {
8628 
8629  data = JSON.parse(data);
8630  }
8631 
8632  if (data) {
8633 
8634  data.forEach(function (item) {
8635 
8636  var row = self.rowManager.findRow(item[self.options.index]);
8637 
8638  responses++;
8639 
8640  if (row) {
8641 
8642  row.updateData(item).then(function () {
8643 
8644  responses--;
8645 
8646  rows.push(row.getComponent());
8647 
8648  if (!responses) {
8649 
8650  resolve(rows);
8651  }
8652  });
8653  } else {
8654 
8655  self.rowManager.addRows(item).then(function (newRows) {
8656 
8657  responses--;
8658 
8659  rows.push(newRows[0].getComponent());
8660 
8661  if (!responses) {
8662 
8663  resolve(rows);
8664  }
8665  });
8666  }
8667  });
8668  } else {
8669 
8670  console.warn("Update Error - No data provided");
8671 
8672  reject("Update Error - No data provided");
8673  }
8674  });
8675  };
8676 
8677  //get row object
8678 
8679  Tabulator.prototype.getRow = function (index) {
8680 
8681  var row = this.rowManager.findRow(index);
8682 
8683  if (row) {
8684 
8685  return row.getComponent();
8686  } else {
8687 
8688  console.warn("Find Error - No matching row found:", index);
8689 
8690  return false;
8691  }
8692  };
8693 
8694  //get row object
8695 
8696  Tabulator.prototype.getRowFromPosition = function (position, active) {
8697 
8698  var row = this.rowManager.getRowFromPosition(position, active);
8699 
8700  if (row) {
8701 
8702  return row.getComponent();
8703  } else {
8704 
8705  console.warn("Find Error - No matching row found:", position);
8706 
8707  return false;
8708  }
8709  };
8710 
8711  //delete row from table
8712 
8713  Tabulator.prototype.deleteRow = function (index) {
8714  var _this20 = this;
8715 
8716  return new Promise(function (resolve, reject) {
8717 
8718  var count = 0,
8719  successCount = 0,
8720  self = _this20;
8721 
8722  function doneCheck() {
8723 
8724  count++;
8725 
8726  if (count == index.length) {
8727 
8728  if (successCount) {
8729 
8730  self.rowManager.reRenderInPosition();
8731 
8732  resolve();
8733  }
8734  }
8735  }
8736 
8737  if (!Array.isArray(index)) {
8738 
8739  index = [index];
8740  }
8741 
8742  index.forEach(function (item) {
8743 
8744  var row = _this20.rowManager.findRow(item, true);
8745 
8746  if (row) {
8747 
8748  row.delete().then(function () {
8749 
8750  successCount++;
8751 
8752  doneCheck();
8753  }).catch(function (err) {
8754 
8755  doneCheck();
8756 
8757  reject(err);
8758  });
8759  } else {
8760 
8761  console.warn("Delete Error - No matching row found:", item);
8762 
8763  reject("Delete Error - No matching row found");
8764 
8765  doneCheck();
8766  }
8767  });
8768  });
8769  };
8770 
8771  //add row to table
8772 
8773  Tabulator.prototype.addRow = function (data, pos, index) {
8774  var _this21 = this;
8775 
8776  return new Promise(function (resolve, reject) {
8777 
8778  if (typeof data === "string") {
8779 
8780  data = JSON.parse(data);
8781  }
8782 
8783  _this21.rowManager.addRows(data, pos, index).then(function (rows) {
8784 
8785  //recalc column calculations if present
8786 
8787  if (_this21.modExists("columnCalcs")) {
8788 
8789  _this21.modules.columnCalcs.recalc(_this21.rowManager.activeRows);
8790  }
8791 
8792  resolve(rows[0].getComponent());
8793  });
8794  });
8795  };
8796 
8797  //update a row if it exitsts otherwise create it
8798 
8799  Tabulator.prototype.updateOrAddRow = function (index, data) {
8800  var _this22 = this;
8801 
8802  return new Promise(function (resolve, reject) {
8803 
8804  var row = _this22.rowManager.findRow(index);
8805 
8806  if (typeof data === "string") {
8807 
8808  data = JSON.parse(data);
8809  }
8810 
8811  if (row) {
8812 
8813  row.updateData(data).then(function () {
8814 
8815  //recalc column calculations if present
8816 
8817  if (_this22.modExists("columnCalcs")) {
8818 
8819  _this22.modules.columnCalcs.recalc(_this22.rowManager.activeRows);
8820  }
8821 
8822  resolve(row.getComponent());
8823  }).catch(function (err) {
8824 
8825  reject(err);
8826  });
8827  } else {
8828 
8829  row = _this22.rowManager.addRows(data).then(function (rows) {
8830 
8831  //recalc column calculations if present
8832 
8833  if (_this22.modExists("columnCalcs")) {
8834 
8835  _this22.modules.columnCalcs.recalc(_this22.rowManager.activeRows);
8836  }
8837 
8838  resolve(rows[0].getComponent());
8839  }).catch(function (err) {
8840 
8841  reject(err);
8842  });
8843  }
8844  });
8845  };
8846 
8847  //update row data
8848 
8849  Tabulator.prototype.updateRow = function (index, data) {
8850  var _this23 = this;
8851 
8852  return new Promise(function (resolve, reject) {
8853 
8854  var row = _this23.rowManager.findRow(index);
8855 
8856  if (typeof data === "string") {
8857 
8858  data = JSON.parse(data);
8859  }
8860 
8861  if (row) {
8862 
8863  row.updateData(data).then(function () {
8864 
8865  resolve(row.getComponent());
8866  }).catch(function (err) {
8867 
8868  reject(err);
8869  });
8870  } else {
8871 
8872  console.warn("Update Error - No matching row found:", index);
8873 
8874  reject("Update Error - No matching row found");
8875  }
8876  });
8877  };
8878 
8879  //scroll to row in DOM
8880 
8881  Tabulator.prototype.scrollToRow = function (index, position, ifVisible) {
8882  var _this24 = this;
8883 
8884  return new Promise(function (resolve, reject) {
8885 
8886  var row = _this24.rowManager.findRow(index);
8887 
8888  if (row) {
8889 
8890  _this24.rowManager.scrollToRow(row, position, ifVisible).then(function () {
8891 
8892  resolve();
8893  }).catch(function (err) {
8894 
8895  reject(err);
8896  });
8897  } else {
8898 
8899  console.warn("Scroll Error - No matching row found:", index);
8900 
8901  reject("Scroll Error - No matching row found");
8902  }
8903  });
8904  };
8905 
8906  Tabulator.prototype.moveRow = function (from, to, after) {
8907 
8908  var fromRow = this.rowManager.findRow(from);
8909 
8910  if (fromRow) {
8911 
8912  fromRow.moveToRow(to, after);
8913  } else {
8914 
8915  console.warn("Move Error - No matching row found:", from);
8916  }
8917  };
8918 
8919  Tabulator.prototype.getRows = function (active) {
8920 
8921  if (active === true) {
8922 
8923  console.warn("passing a boolean to the getRows function is deprecated, you should now pass the string 'active'");
8924 
8925  active = "active";
8926  }
8927 
8928  return this.rowManager.getComponents(active);
8929  };
8930 
8931  //get position of row in table
8932 
8933  Tabulator.prototype.getRowPosition = function (index, active) {
8934 
8935  var row = this.rowManager.findRow(index);
8936 
8937  if (row) {
8938 
8939  return this.rowManager.getRowPosition(row, active);
8940  } else {
8941 
8942  console.warn("Position Error - No matching row found:", index);
8943 
8944  return false;
8945  }
8946  };
8947 
8948  //copy table data to clipboard
8949 
8950  Tabulator.prototype.copyToClipboard = function (selector, selectorParams, formatter, formatterParams) {
8951 
8952  if (this.modExists("clipboard", true)) {
8953 
8954  this.modules.clipboard.copy(selector, selectorParams, formatter, formatterParams);
8955  }
8956  };
8957 
8959 
8960 
8961  Tabulator.prototype.setColumns = function (definition) {
8962 
8963  this.columnManager.setColumns(definition);
8964  };
8965 
8966  Tabulator.prototype.getColumns = function (structured) {
8967 
8968  return this.columnManager.getComponents(structured);
8969  };
8970 
8971  Tabulator.prototype.getColumn = function (field) {
8972 
8973  var col = this.columnManager.findColumn(field);
8974 
8975  if (col) {
8976 
8977  return col.getComponent();
8978  } else {
8979 
8980  console.warn("Find Error - No matching column found:", field);
8981 
8982  return false;
8983  }
8984  };
8985 
8986  Tabulator.prototype.getColumnDefinitions = function () {
8987 
8988  return this.columnManager.getDefinitionTree();
8989  };
8990 
8991  Tabulator.prototype.getColumnLayout = function () {
8992 
8993  if (this.modExists("persistence", true)) {
8994 
8995  return this.modules.persistence.parseColumns(this.columnManager.getColumns());
8996  }
8997  };
8998 
8999  Tabulator.prototype.setColumnLayout = function (layout) {
9000 
9001  if (this.modExists("persistence", true)) {
9002 
9003  this.columnManager.setColumns(this.modules.persistence.mergeDefinition(this.options.columns, layout));
9004 
9005  return true;
9006  }
9007 
9008  return false;
9009  };
9010 
9011  Tabulator.prototype.showColumn = function (field) {
9012 
9013  var column = this.columnManager.findColumn(field);
9014 
9015  if (column) {
9016 
9017  column.show();
9018 
9019  if (this.options.responsiveLayout && this.modExists("responsiveLayout", true)) {
9020 
9021  this.modules.responsiveLayout.update();
9022  }
9023  } else {
9024 
9025  console.warn("Column Show Error - No matching column found:", field);
9026 
9027  return false;
9028  }
9029  };
9030 
9031  Tabulator.prototype.hideColumn = function (field) {
9032 
9033  var column = this.columnManager.findColumn(field);
9034 
9035  if (column) {
9036 
9037  column.hide();
9038 
9039  if (this.options.responsiveLayout && this.modExists("responsiveLayout", true)) {
9040 
9041  this.modules.responsiveLayout.update();
9042  }
9043  } else {
9044 
9045  console.warn("Column Hide Error - No matching column found:", field);
9046 
9047  return false;
9048  }
9049  };
9050 
9051  Tabulator.prototype.toggleColumn = function (field) {
9052 
9053  var column = this.columnManager.findColumn(field);
9054 
9055  if (column) {
9056 
9057  if (column.visible) {
9058 
9059  column.hide();
9060  } else {
9061 
9062  column.show();
9063  }
9064  } else {
9065 
9066  console.warn("Column Visibility Toggle Error - No matching column found:", field);
9067 
9068  return false;
9069  }
9070  };
9071 
9072  Tabulator.prototype.addColumn = function (definition, before, field) {
9073  var _this25 = this;
9074 
9075  return new Promise(function (resolve, reject) {
9076 
9077  var column = _this25.columnManager.findColumn(field);
9078 
9079  _this25.columnManager.addColumn(definition, before, column).then(function (column) {
9080 
9081  resolve(column.getComponent());
9082  }).catch(function (err) {
9083 
9084  reject(err);
9085  });
9086  });
9087  };
9088 
9089  Tabulator.prototype.deleteColumn = function (field) {
9090  var _this26 = this;
9091 
9092  return new Promise(function (resolve, reject) {
9093 
9094  var column = _this26.columnManager.findColumn(field);
9095 
9096  if (column) {
9097 
9098  column.delete().then(function () {
9099 
9100  resolve();
9101  }).catch(function (err) {
9102 
9103  reject(err);
9104  });
9105  } else {
9106 
9107  console.warn("Column Delete Error - No matching column found:", field);
9108 
9109  reject();
9110  }
9111  });
9112  };
9113 
9114  Tabulator.prototype.updateColumnDefinition = function (field, definition) {
9115  var _this27 = this;
9116 
9117  return new Promise(function (resolve, reject) {
9118 
9119  var column = _this27.columnManager.findColumn(field);
9120 
9121  if (column) {
9122 
9123  column.updateDefinition().then(function (col) {
9124 
9125  resolve(col);
9126  }).catch(function (err) {
9127 
9128  reject(err);
9129  });
9130  } else {
9131 
9132  console.warn("Column Update Error - No matching column found:", field);
9133 
9134  reject();
9135  }
9136  });
9137  };
9138 
9139  Tabulator.prototype.moveColumn = function (from, to, after) {
9140 
9141  var fromColumn = this.columnManager.findColumn(from);
9142 
9143  var toColumn = this.columnManager.findColumn(to);
9144 
9145  if (fromColumn) {
9146 
9147  if (toColumn) {
9148 
9149  this.columnManager.moveColumn(fromColumn, toColumn, after);
9150  } else {
9151 
9152  console.warn("Move Error - No matching column found:", toColumn);
9153  }
9154  } else {
9155 
9156  console.warn("Move Error - No matching column found:", from);
9157  }
9158  };
9159 
9160  //scroll to column in DOM
9161 
9162  Tabulator.prototype.scrollToColumn = function (field, position, ifVisible) {
9163  var _this28 = this;
9164 
9165  return new Promise(function (resolve, reject) {
9166 
9167  var column = _this28.columnManager.findColumn(field);
9168 
9169  if (column) {
9170 
9171  _this28.columnManager.scrollToColumn(column, position, ifVisible).then(function () {
9172 
9173  resolve();
9174  }).catch(function (err) {
9175 
9176  reject(err);
9177  });
9178  } else {
9179 
9180  console.warn("Scroll Error - No matching column found:", field);
9181 
9182  reject("Scroll Error - No matching column found");
9183  }
9184  });
9185  };
9186 
9188 
9189  Tabulator.prototype.setLocale = function (locale) {
9190 
9191  this.modules.localize.setLocale(locale);
9192  };
9193 
9194  Tabulator.prototype.getLocale = function () {
9195 
9196  return this.modules.localize.getLocale();
9197  };
9198 
9199  Tabulator.prototype.getLang = function (locale) {
9200 
9201  return this.modules.localize.getLang(locale);
9202  };
9203 
9205 
9206 
9207  //redraw list without updating data
9208 
9209  Tabulator.prototype.redraw = function (force) {
9210 
9211  this.columnManager.redraw(force);
9212 
9213  this.rowManager.redraw(force);
9214  };
9215 
9216  Tabulator.prototype.setHeight = function (height) {
9217 
9218  if (this.rowManager.renderMode !== "classic") {
9219 
9220  this.options.height = isNaN(height) ? height : height + "px";
9221 
9222  this.element.style.height = this.options.height;
9223 
9224  this.rowManager.redraw();
9225  } else {
9226 
9227  console.warn("setHeight function is not available in classic render mode");
9228  }
9229  };
9230 
9232 
9233 
9234  //trigger sort
9235 
9236  Tabulator.prototype.setSort = function (sortList, dir) {
9237 
9238  if (this.modExists("sort", true)) {
9239 
9240  this.modules.sort.setSort(sortList, dir);
9241 
9242  this.rowManager.sorterRefresh();
9243  }
9244  };
9245 
9246  Tabulator.prototype.getSorters = function () {
9247 
9248  if (this.modExists("sort", true)) {
9249 
9250  return this.modules.sort.getSort();
9251  }
9252  };
9253 
9254  Tabulator.prototype.clearSort = function () {
9255 
9256  if (this.modExists("sort", true)) {
9257 
9258  this.modules.sort.clear();
9259 
9260  this.rowManager.sorterRefresh();
9261  }
9262  };
9263 
9265 
9266 
9267  //set standard filters
9268 
9269  Tabulator.prototype.setFilter = function (field, type, value) {
9270 
9271  if (this.modExists("filter", true)) {
9272 
9273  this.modules.filter.setFilter(field, type, value);
9274 
9275  this.rowManager.filterRefresh();
9276  }
9277  };
9278 
9279  //add filter to array
9280 
9281  Tabulator.prototype.addFilter = function (field, type, value) {
9282 
9283  if (this.modExists("filter", true)) {
9284 
9285  this.modules.filter.addFilter(field, type, value);
9286 
9287  this.rowManager.filterRefresh();
9288  }
9289  };
9290 
9291  //get all filters
9292 
9293  Tabulator.prototype.getFilters = function (all) {
9294 
9295  if (this.modExists("filter", true)) {
9296 
9297  return this.modules.filter.getFilters(all);
9298  }
9299  };
9300 
9301  Tabulator.prototype.setHeaderFilterFocus = function (field) {
9302 
9303  if (this.modExists("filter", true)) {
9304 
9305  var column = this.columnManager.findColumn(field);
9306 
9307  if (column) {
9308 
9309  this.modules.filter.setHeaderFilterFocus(column);
9310  } else {
9311 
9312  console.warn("Column Filter Focus Error - No matching column found:", field);
9313 
9314  return false;
9315  }
9316  }
9317  };
9318 
9319  Tabulator.prototype.setHeaderFilterValue = function (field, value) {
9320 
9321  if (this.modExists("filter", true)) {
9322 
9323  var column = this.columnManager.findColumn(field);
9324 
9325  if (column) {
9326 
9327  this.modules.filter.setHeaderFilterValue(column, value);
9328  } else {
9329 
9330  console.warn("Column Filter Error - No matching column found:", field);
9331 
9332  return false;
9333  }
9334  }
9335  };
9336 
9337  Tabulator.prototype.getHeaderFilters = function () {
9338 
9339  if (this.modExists("filter", true)) {
9340 
9341  return this.modules.filter.getHeaderFilters();
9342  }
9343  };
9344 
9345  //remove filter from array
9346 
9347  Tabulator.prototype.removeFilter = function (field, type, value) {
9348 
9349  if (this.modExists("filter", true)) {
9350 
9351  this.modules.filter.removeFilter(field, type, value);
9352 
9353  this.rowManager.filterRefresh();
9354  }
9355  };
9356 
9357  //clear filters
9358 
9359  Tabulator.prototype.clearFilter = function (all) {
9360 
9361  if (this.modExists("filter", true)) {
9362 
9363  this.modules.filter.clearFilter(all);
9364 
9365  this.rowManager.filterRefresh();
9366  }
9367  };
9368 
9369  //clear header filters
9370 
9371  Tabulator.prototype.clearHeaderFilter = function () {
9372 
9373  if (this.modExists("filter", true)) {
9374 
9375  this.modules.filter.clearHeaderFilter();
9376 
9377  this.rowManager.filterRefresh();
9378  }
9379  };
9380 
9382 
9383  Tabulator.prototype.selectRow = function (rows) {
9384 
9385  if (this.modExists("selectRow", true)) {
9386 
9387  if (rows === true) {
9388 
9389  console.warn("passing a boolean to the selectRowselectRow function is deprecated, you should now pass the string 'active'");
9390 
9391  rows = "active";
9392  }
9393 
9394  this.modules.selectRow.selectRows(rows);
9395  }
9396  };
9397 
9398  Tabulator.prototype.deselectRow = function (rows) {
9399 
9400  if (this.modExists("selectRow", true)) {
9401 
9402  this.modules.selectRow.deselectRows(rows);
9403  }
9404  };
9405 
9406  Tabulator.prototype.toggleSelectRow = function (row) {
9407 
9408  if (this.modExists("selectRow", true)) {
9409 
9410  this.modules.selectRow.toggleRow(row);
9411  }
9412  };
9413 
9414  Tabulator.prototype.getSelectedRows = function () {
9415 
9416  if (this.modExists("selectRow", true)) {
9417 
9418  return this.modules.selectRow.getSelectedRows();
9419  }
9420  };
9421 
9422  Tabulator.prototype.getSelectedData = function () {
9423 
9424  if (this.modExists("selectRow", true)) {
9425 
9426  return this.modules.selectRow.getSelectedData();
9427  }
9428  };
9429 
9431 
9432 
9433  Tabulator.prototype.setMaxPage = function (max) {
9434 
9435  if (this.options.pagination && this.modExists("page")) {
9436 
9437  this.modules.page.setMaxPage(max);
9438  } else {
9439 
9440  return false;
9441  }
9442  };
9443 
9444  Tabulator.prototype.setPage = function (page) {
9445 
9446  if (this.options.pagination && this.modExists("page")) {
9447 
9448  return this.modules.page.setPage(page);
9449  } else {
9450 
9451  return new Promise(function (resolve, reject) {
9452  reject();
9453  });
9454  }
9455  };
9456 
9457  Tabulator.prototype.setPageToRow = function (row) {
9458  var _this29 = this;
9459 
9460  return new Promise(function (resolve, reject) {
9461 
9462  if (_this29.options.pagination && _this29.modExists("page")) {
9463 
9464  row = _this29.rowManager.findRow(row);
9465 
9466  if (row) {
9467 
9468  _this29.modules.page.setPageToRow(row).then(function () {
9469 
9470  resolve();
9471  }).catch(function () {
9472 
9473  reject();
9474  });
9475  } else {
9476 
9477  reject();
9478  }
9479  } else {
9480 
9481  reject();
9482  }
9483  });
9484  };
9485 
9486  Tabulator.prototype.setPageSize = function (size) {
9487 
9488  if (this.options.pagination && this.modExists("page")) {
9489 
9490  this.modules.page.setPageSize(size);
9491 
9492  this.modules.page.setPage(1).then(function () {}).catch(function () {});
9493  } else {
9494 
9495  return false;
9496  }
9497  };
9498 
9499  Tabulator.prototype.getPageSize = function () {
9500 
9501  if (this.options.pagination && this.modExists("page", true)) {
9502 
9503  return this.modules.page.getPageSize();
9504  }
9505  };
9506 
9507  Tabulator.prototype.previousPage = function () {
9508 
9509  if (this.options.pagination && this.modExists("page")) {
9510 
9511  this.modules.page.previousPage();
9512  } else {
9513 
9514  return false;
9515  }
9516  };
9517 
9518  Tabulator.prototype.nextPage = function () {
9519 
9520  if (this.options.pagination && this.modExists("page")) {
9521 
9522  this.modules.page.nextPage();
9523  } else {
9524 
9525  return false;
9526  }
9527  };
9528 
9529  Tabulator.prototype.getPage = function () {
9530 
9531  if (this.options.pagination && this.modExists("page")) {
9532 
9533  return this.modules.page.getPage();
9534  } else {
9535 
9536  return false;
9537  }
9538  };
9539 
9540  Tabulator.prototype.getPageMax = function () {
9541 
9542  if (this.options.pagination && this.modExists("page")) {
9543 
9544  return this.modules.page.getPageMax();
9545  } else {
9546 
9547  return false;
9548  }
9549  };
9550 
9552 
9553 
9554  Tabulator.prototype.setGroupBy = function (groups) {
9555 
9556  if (this.modExists("groupRows", true)) {
9557 
9558  this.options.groupBy = groups;
9559 
9560  this.modules.groupRows.initialize();
9561 
9562  this.rowManager.refreshActiveData("display");
9563 
9564  if (this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group) {
9565 
9566  this.modules.persistence.save("group");
9567  }
9568  } else {
9569 
9570  return false;
9571  }
9572  };
9573 
9574  Tabulator.prototype.setGroupStartOpen = function (values) {
9575 
9576  if (this.modExists("groupRows", true)) {
9577 
9578  this.options.groupStartOpen = values;
9579 
9580  this.modules.groupRows.initialize();
9581 
9582  if (this.options.groupBy) {
9583 
9584  this.rowManager.refreshActiveData("group");
9585 
9586  if (this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group) {
9587 
9588  this.modules.persistence.save("group");
9589  }
9590  } else {
9591 
9592  console.warn("Grouping Update - cant refresh view, no groups have been set");
9593  }
9594  } else {
9595 
9596  return false;
9597  }
9598  };
9599 
9600  Tabulator.prototype.setGroupHeader = function (values) {
9601 
9602  if (this.modExists("groupRows", true)) {
9603 
9604  this.options.groupHeader = values;
9605 
9606  this.modules.groupRows.initialize();
9607 
9608  if (this.options.groupBy) {
9609 
9610  this.rowManager.refreshActiveData("group");
9611 
9612  if (this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group) {
9613 
9614  this.modules.persistence.save("group");
9615  }
9616  } else {
9617 
9618  console.warn("Grouping Update - cant refresh view, no groups have been set");
9619  }
9620  } else {
9621 
9622  return false;
9623  }
9624  };
9625 
9626  Tabulator.prototype.getGroups = function (values) {
9627 
9628  if (this.modExists("groupRows", true)) {
9629 
9630  return this.modules.groupRows.getGroups(true);
9631  } else {
9632 
9633  return false;
9634  }
9635  };
9636 
9637  // get grouped table data in the same format as getData()
9638 
9639  Tabulator.prototype.getGroupedData = function () {
9640 
9641  if (this.modExists("groupRows", true)) {
9642 
9643  return this.options.groupBy ? this.modules.groupRows.getGroupedData() : this.getData();
9644  }
9645  };
9646 
9648 
9649  Tabulator.prototype.getCalcResults = function () {
9650 
9651  if (this.modExists("columnCalcs", true)) {
9652 
9653  return this.modules.columnCalcs.getResults();
9654  } else {
9655 
9656  return false;
9657  }
9658  };
9659 
9661 
9662 
9663  Tabulator.prototype.navigatePrev = function () {
9664 
9665  var cell = false;
9666 
9667  if (this.modExists("edit", true)) {
9668 
9669  cell = this.modules.edit.currentCell;
9670 
9671  if (cell) {
9672 
9673  return cell.nav().prev();
9674  }
9675  }
9676 
9677  return false;
9678  };
9679 
9680  Tabulator.prototype.navigateNext = function () {
9681 
9682  var cell = false;
9683 
9684  if (this.modExists("edit", true)) {
9685 
9686  cell = this.modules.edit.currentCell;
9687 
9688  if (cell) {
9689 
9690  return cell.nav().next();
9691  }
9692  }
9693 
9694  return false;
9695  };
9696 
9697  Tabulator.prototype.navigateLeft = function () {
9698 
9699  var cell = false;
9700 
9701  if (this.modExists("edit", true)) {
9702 
9703  cell = this.modules.edit.currentCell;
9704 
9705  if (cell) {
9706 
9707  e.preventDefault();
9708 
9709  return cell.nav().left();
9710  }
9711  }
9712 
9713  return false;
9714  };
9715 
9716  Tabulator.prototype.navigateRight = function () {
9717 
9718  var cell = false;
9719 
9720  if (this.modExists("edit", true)) {
9721 
9722  cell = this.modules.edit.currentCell;
9723 
9724  if (cell) {
9725 
9726  e.preventDefault();
9727 
9728  return cell.nav().right();
9729  }
9730  }
9731 
9732  return false;
9733  };
9734 
9735  Tabulator.prototype.navigateUp = function () {
9736 
9737  var cell = false;
9738 
9739  if (this.modExists("edit", true)) {
9740 
9741  cell = this.modules.edit.currentCell;
9742 
9743  if (cell) {
9744 
9745  e.preventDefault();
9746 
9747  return cell.nav().up();
9748  }
9749  }
9750 
9751  return false;
9752  };
9753 
9754  Tabulator.prototype.navigateDown = function () {
9755 
9756  var cell = false;
9757 
9758  if (this.modExists("edit", true)) {
9759 
9760  cell = this.modules.edit.currentCell;
9761 
9762  if (cell) {
9763 
9764  e.preventDefault();
9765 
9766  return cell.nav().down();
9767  }
9768  }
9769 
9770  return false;
9771  };
9772 
9774 
9775  Tabulator.prototype.undo = function () {
9776 
9777  if (this.options.history && this.modExists("history", true)) {
9778 
9779  return this.modules.history.undo();
9780  } else {
9781 
9782  return false;
9783  }
9784  };
9785 
9786  Tabulator.prototype.redo = function () {
9787 
9788  if (this.options.history && this.modExists("history", true)) {
9789 
9790  return this.modules.history.redo();
9791  } else {
9792 
9793  return false;
9794  }
9795  };
9796 
9797  Tabulator.prototype.getHistoryUndoSize = function () {
9798 
9799  if (this.options.history && this.modExists("history", true)) {
9800 
9801  return this.modules.history.getHistoryUndoSize();
9802  } else {
9803 
9804  return false;
9805  }
9806  };
9807 
9808  Tabulator.prototype.getHistoryRedoSize = function () {
9809 
9810  if (this.options.history && this.modExists("history", true)) {
9811 
9812  return this.modules.history.getHistoryRedoSize();
9813  } else {
9814 
9815  return false;
9816  }
9817  };
9818 
9820 
9821 
9822  Tabulator.prototype.download = function (type, filename, options, active) {
9823 
9824  if (this.modExists("download", true)) {
9825 
9826  this.modules.download.download(type, filename, options, active);
9827  }
9828  };
9829 
9830  Tabulator.prototype.downloadToTab = function (type, filename, options, active) {
9831 
9832  if (this.modExists("download", true)) {
9833 
9834  this.modules.download.download(type, filename, options, active, true);
9835  }
9836  };
9837 
9839 
9840 
9841  Tabulator.prototype.tableComms = function (table, module, action, data) {
9842 
9843  this.modules.comms.receive(table, module, action, data);
9844  };
9845 
9847 
9848 
9849  //object to hold module
9850 
9851  Tabulator.prototype.moduleBindings = {};
9852 
9853  //extend module
9854 
9855  Tabulator.prototype.extendModule = function (name, property, values) {
9856 
9857  if (Tabulator.prototype.moduleBindings[name]) {
9858 
9859  var source = Tabulator.prototype.moduleBindings[name].prototype[property];
9860 
9861  if (source) {
9862 
9863  if ((typeof values === 'undefined' ? 'undefined' : _typeof(values)) == "object") {
9864 
9865  for (var key in values) {
9866 
9867  source[key] = values[key];
9868  }
9869  } else {
9870 
9871  console.warn("Module Error - Invalid value type, it must be an object");
9872  }
9873  } else {
9874 
9875  console.warn("Module Error - property does not exist:", property);
9876  }
9877  } else {
9878 
9879  console.warn("Module Error - module does not exist:", name);
9880  }
9881  };
9882 
9883  //add module to tabulator
9884 
9885  Tabulator.prototype.registerModule = function (name, module) {
9886 
9887  var self = this;
9888 
9889  Tabulator.prototype.moduleBindings[name] = module;
9890  };
9891 
9892  //ensure that module are bound to instantiated function
9893 
9894  Tabulator.prototype.bindModules = function () {
9895 
9896  this.modules = {};
9897 
9898  for (var name in Tabulator.prototype.moduleBindings) {
9899 
9900  this.modules[name] = new Tabulator.prototype.moduleBindings[name](this);
9901  }
9902  };
9903 
9904  //Check for module
9905 
9906  Tabulator.prototype.modExists = function (plugin, required) {
9907 
9908  if (this.modules[plugin]) {
9909 
9910  return true;
9911  } else {
9912 
9913  if (required) {
9914 
9915  console.error("Tabulator Module Not Installed: " + plugin);
9916  }
9917 
9918  return false;
9919  }
9920  };
9921 
9922  Tabulator.prototype.helpers = {
9923 
9924  elVisible: function elVisible(el) {
9925 
9926  return !(el.offsetWidth <= 0 && el.offsetHeight <= 0);
9927  },
9928 
9929  elOffset: function elOffset(el) {
9930 
9931  var box = el.getBoundingClientRect();
9932 
9933  return {
9934 
9935  top: box.top + window.pageYOffset - document.documentElement.clientTop,
9936 
9937  left: box.left + window.pageXOffset - document.documentElement.clientLeft
9938 
9939  };
9940  },
9941 
9942  deepClone: function deepClone(obj) {
9943 
9944  var clone = Array.isArray(obj) ? [] : {};
9945 
9946  for (var i in obj) {
9947 
9948  if (obj[i] != null && _typeof(obj[i]) === "object") {
9949 
9950  if (obj[i] instanceof Date) {
9951 
9952  clone[i] = new Date(obj[i]);
9953  } else {
9954 
9955  clone[i] = this.deepClone(obj[i]);
9956  }
9957  } else {
9958 
9959  clone[i] = obj[i];
9960  }
9961  }
9962 
9963  return clone;
9964  }
9965 
9966  };
9967 
9968  Tabulator.prototype.comms = {
9969 
9970  tables: [],
9971 
9972  register: function register(table) {
9973 
9974  Tabulator.prototype.comms.tables.push(table);
9975  },
9976 
9977  deregister: function deregister(table) {
9978 
9979  var index = Tabulator.prototype.comms.tables.indexOf(table);
9980 
9981  if (index > -1) {
9982 
9983  Tabulator.prototype.comms.tables.splice(index, 1);
9984  }
9985  },
9986 
9987  lookupTable: function lookupTable(query, silent) {
9988 
9989  var results = [],
9990  matches,
9991  match;
9992 
9993  if (typeof query === "string") {
9994 
9995  matches = document.querySelectorAll(query);
9996 
9997  if (matches.length) {
9998 
9999  for (var i = 0; i < matches.length; i++) {
10000 
10001  match = Tabulator.prototype.comms.matchElement(matches[i]);
10002 
10003  if (match) {
10004 
10005  results.push(match);
10006  }
10007  }
10008  }
10009  } else if (typeof HTMLElement !== "undefined" && query instanceof HTMLElement || query instanceof Tabulator) {
10010 
10011  match = Tabulator.prototype.comms.matchElement(query);
10012 
10013  if (match) {
10014 
10015  results.push(match);
10016  }
10017  } else if (Array.isArray(query)) {
10018 
10019  query.forEach(function (item) {
10020 
10021  results = results.concat(Tabulator.prototype.comms.lookupTable(item));
10022  });
10023  } else {
10024 
10025  if (!silent) {
10026 
10027  console.warn("Table Connection Error - Invalid Selector", query);
10028  }
10029  }
10030 
10031  return results;
10032  },
10033 
10034  matchElement: function matchElement(element) {
10035 
10036  return Tabulator.prototype.comms.tables.find(function (table) {
10037 
10038  return element instanceof Tabulator ? table === element : table.element === element;
10039  });
10040  }
10041 
10042  };
10043 
10044  Tabulator.prototype.findTable = function (query) {
10045 
10046  var results = Tabulator.prototype.comms.lookupTable(query, true);
10047 
10048  return Array.isArray(results) && !results.length ? false : results;
10049  };
10050 
10051  var Layout = function Layout(table) {
10052 
10053  this.table = table;
10054 
10055  this.mode = null;
10056  };
10057 
10058  //initialize layout system
10059 
10060 
10061  Layout.prototype.initialize = function (layout) {
10062 
10063  if (this.modes[layout]) {
10064 
10065  this.mode = layout;
10066  } else {
10067 
10068  console.warn("Layout Error - invalid mode set, defaulting to 'fitData' : " + layout);
10069 
10070  this.mode = 'fitData';
10071  }
10072 
10073  this.table.element.setAttribute("tabulator-layout", this.mode);
10074  };
10075 
10076  Layout.prototype.getMode = function () {
10077 
10078  return this.mode;
10079  };
10080 
10081  //trigger table layout
10082 
10083 
10084  Layout.prototype.layout = function () {
10085 
10086  this.modes[this.mode].call(this, this.table.columnManager.columnsByIndex);
10087  };
10088 
10089  //layout render functions
10090 
10091 
10092  Layout.prototype.modes = {
10093 
10094  //resize columns to fit data the contain
10095 
10096 
10097  "fitData": function fitData(columns) {
10098 
10099  columns.forEach(function (column) {
10100 
10101  column.reinitializeWidth();
10102  });
10103 
10104  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
10105 
10106  this.table.modules.responsiveLayout.update();
10107  }
10108  },
10109 
10110  //resize columns to fit data the contain and stretch row to fill table
10111 
10112 
10113  "fitDataFill": function fitDataFill(columns) {
10114 
10115  columns.forEach(function (column) {
10116 
10117  column.reinitializeWidth();
10118  });
10119 
10120  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
10121 
10122  this.table.modules.responsiveLayout.update();
10123  }
10124  },
10125 
10126  //resize columns to fit data the contain and stretch last column to fill table
10127 
10128 
10129  "fitDataStretch": function fitDataStretch(columns) {
10130  var _this30 = this;
10131 
10132  var colsWidth = 0,
10133  tableWidth = this.table.rowManager.element.clientWidth,
10134  gap = 0,
10135  lastCol = false;
10136 
10137  columns.forEach(function (column, i) {
10138 
10139  if (!column.widthFixed) {
10140 
10141  column.reinitializeWidth();
10142  }
10143 
10144  if (_this30.table.options.responsiveLayout ? column.modules.responsive.visible : column.visible) {
10145 
10146  lastCol = column;
10147  }
10148 
10149  if (column.visible) {
10150 
10151  colsWidth += column.getWidth();
10152  }
10153  });
10154 
10155  if (lastCol) {
10156 
10157  gap = tableWidth - colsWidth + lastCol.getWidth();
10158 
10159  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
10160 
10161  lastCol.setWidth(0);
10162 
10163  this.table.modules.responsiveLayout.update();
10164  }
10165 
10166  if (gap > 0) {
10167 
10168  lastCol.setWidth(gap);
10169  } else {
10170 
10171  lastCol.reinitializeWidth();
10172  }
10173  } else {
10174 
10175  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
10176 
10177  this.table.modules.responsiveLayout.update();
10178  }
10179  }
10180  },
10181 
10182  //resize columns to fit
10183 
10184 
10185  "fitColumns": function fitColumns(columns) {
10186 
10187  var self = this;
10188 
10189  var totalWidth = self.table.element.clientWidth; //table element width
10190 
10191 
10192  var fixedWidth = 0; //total width of columns with a defined width
10193 
10194 
10195  var flexWidth = 0; //total width available to flexible columns
10196 
10197 
10198  var flexGrowUnits = 0; //total number of widthGrow blocks accross all columns
10199 
10200 
10201  var flexColWidth = 0; //desired width of flexible columns
10202 
10203 
10204  var flexColumns = []; //array of flexible width columns
10205 
10206 
10207  var fixedShrinkColumns = []; //array of fixed width columns that can shrink
10208 
10209 
10210  var flexShrinkUnits = 0; //total number of widthShrink blocks accross all columns
10211 
10212 
10213  var overflowWidth = 0; //horizontal overflow width
10214 
10215 
10216  var gapFill = 0; //number of pixels to be added to final column to close and half pixel gaps
10217 
10218 
10219  function calcWidth(width) {
10220 
10221  var colWidth;
10222 
10223  if (typeof width == "string") {
10224 
10225  if (width.indexOf("%") > -1) {
10226 
10227  colWidth = totalWidth / 100 * parseInt(width);
10228  } else {
10229 
10230  colWidth = parseInt(width);
10231  }
10232  } else {
10233 
10234  colWidth = width;
10235  }
10236 
10237  return colWidth;
10238  }
10239 
10240  //ensure columns resize to take up the correct amount of space
10241 
10242 
10243  function scaleColumns(columns, freeSpace, colWidth, shrinkCols) {
10244 
10245  var oversizeCols = [],
10246  oversizeSpace = 0,
10247  remainingSpace = 0,
10248  nextColWidth = 0,
10249  gap = 0,
10250  changeUnits = 0,
10251  undersizeCols = [];
10252 
10253  function calcGrow(col) {
10254 
10255  return colWidth * (col.column.definition.widthGrow || 1);
10256  }
10257 
10258  function calcShrink(col) {
10259 
10260  return calcWidth(col.width) - colWidth * (col.column.definition.widthShrink || 0);
10261  }
10262 
10263  columns.forEach(function (col, i) {
10264 
10265  var width = shrinkCols ? calcShrink(col) : calcGrow(col);
10266 
10267  if (col.column.minWidth >= width) {
10268 
10269  oversizeCols.push(col);
10270  } else {
10271 
10272  undersizeCols.push(col);
10273 
10274  changeUnits += shrinkCols ? col.column.definition.widthShrink || 1 : col.column.definition.widthGrow || 1;
10275  }
10276  });
10277 
10278  if (oversizeCols.length) {
10279 
10280  oversizeCols.forEach(function (col) {
10281 
10282  oversizeSpace += shrinkCols ? col.width - col.column.minWidth : col.column.minWidth;
10283 
10284  col.width = col.column.minWidth;
10285  });
10286 
10287  remainingSpace = freeSpace - oversizeSpace;
10288 
10289  nextColWidth = changeUnits ? Math.floor(remainingSpace / changeUnits) : remainingSpace;
10290 
10291  gap = remainingSpace - nextColWidth * changeUnits;
10292 
10293  gap += scaleColumns(undersizeCols, remainingSpace, nextColWidth, shrinkCols);
10294  } else {
10295 
10296  gap = changeUnits ? freeSpace - Math.floor(freeSpace / changeUnits) * changeUnits : freeSpace;
10297 
10298  undersizeCols.forEach(function (column) {
10299 
10300  column.width = shrinkCols ? calcShrink(column) : calcGrow(column);
10301  });
10302  }
10303 
10304  return gap;
10305  }
10306 
10307  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
10308 
10309  this.table.modules.responsiveLayout.update();
10310  }
10311 
10312  //adjust for vertical scrollbar if present
10313 
10314 
10315  if (this.table.rowManager.element.scrollHeight > this.table.rowManager.element.clientHeight) {
10316 
10317  totalWidth -= this.table.rowManager.element.offsetWidth - this.table.rowManager.element.clientWidth;
10318  }
10319 
10320  columns.forEach(function (column) {
10321 
10322  var width, minWidth, colWidth;
10323 
10324  if (column.visible) {
10325 
10326  width = column.definition.width;
10327 
10328  minWidth = parseInt(column.minWidth);
10329 
10330  if (width) {
10331 
10332  colWidth = calcWidth(width);
10333 
10334  fixedWidth += colWidth > minWidth ? colWidth : minWidth;
10335 
10336  if (column.definition.widthShrink) {
10337 
10338  fixedShrinkColumns.push({
10339 
10340  column: column,
10341 
10342  width: colWidth > minWidth ? colWidth : minWidth
10343 
10344  });
10345 
10346  flexShrinkUnits += column.definition.widthShrink;
10347  }
10348  } else {
10349 
10350  flexColumns.push({
10351 
10352  column: column,
10353 
10354  width: 0
10355 
10356  });
10357 
10358  flexGrowUnits += column.definition.widthGrow || 1;
10359  }
10360  }
10361  });
10362 
10363  //calculate available space
10364 
10365 
10366  flexWidth = totalWidth - fixedWidth;
10367 
10368  //calculate correct column size
10369 
10370 
10371  flexColWidth = Math.floor(flexWidth / flexGrowUnits);
10372 
10373  //generate column widths
10374 
10375 
10376  var gapFill = scaleColumns(flexColumns, flexWidth, flexColWidth, false);
10377 
10378  //increase width of last column to account for rounding errors
10379 
10380 
10381  if (flexColumns.length && gapFill > 0) {
10382 
10383  flexColumns[flexColumns.length - 1].width += +gapFill;
10384  }
10385 
10386  //caculate space for columns to be shrunk into
10387 
10388 
10389  flexColumns.forEach(function (col) {
10390 
10391  flexWidth -= col.width;
10392  });
10393 
10394  overflowWidth = Math.abs(gapFill) + flexWidth;
10395 
10396  //shrink oversize columns if there is no available space
10397 
10398 
10399  if (overflowWidth > 0 && flexShrinkUnits) {
10400 
10401  gapFill = scaleColumns(fixedShrinkColumns, overflowWidth, Math.floor(overflowWidth / flexShrinkUnits), true);
10402  }
10403 
10404  //decrease width of last column to account for rounding errors
10405 
10406 
10407  if (fixedShrinkColumns.length) {
10408 
10409  fixedShrinkColumns[fixedShrinkColumns.length - 1].width -= gapFill;
10410  }
10411 
10412  flexColumns.forEach(function (col) {
10413 
10414  col.column.setWidth(col.width);
10415  });
10416 
10417  fixedShrinkColumns.forEach(function (col) {
10418 
10419  col.column.setWidth(col.width);
10420  });
10421  }
10422 
10423  };
10424 
10425  Tabulator.prototype.registerModule("layout", Layout);
10426 
10427  var Localize = function Localize(table) {
10428 
10429  this.table = table; //hold Tabulator object
10430 
10431  this.locale = "default"; //current locale
10432 
10433  this.lang = false; //current language
10434 
10435  this.bindings = {}; //update events to call when locale is changed
10436  };
10437 
10438  //set header placehoder
10439 
10440  Localize.prototype.setHeaderFilterPlaceholder = function (placeholder) {
10441 
10442  this.langs.default.headerFilters.default = placeholder;
10443  };
10444 
10445  //set header filter placeholder by column
10446 
10447  Localize.prototype.setHeaderFilterColumnPlaceholder = function (column, placeholder) {
10448 
10449  this.langs.default.headerFilters.columns[column] = placeholder;
10450 
10451  if (this.lang && !this.lang.headerFilters.columns[column]) {
10452 
10453  this.lang.headerFilters.columns[column] = placeholder;
10454  }
10455  };
10456 
10457  //setup a lang description object
10458 
10459  Localize.prototype.installLang = function (locale, lang) {
10460 
10461  if (this.langs[locale]) {
10462 
10463  this._setLangProp(this.langs[locale], lang);
10464  } else {
10465 
10466  this.langs[locale] = lang;
10467  }
10468  };
10469 
10470  Localize.prototype._setLangProp = function (lang, values) {
10471 
10472  for (var key in values) {
10473 
10474  if (lang[key] && _typeof(lang[key]) == "object") {
10475 
10476  this._setLangProp(lang[key], values[key]);
10477  } else {
10478 
10479  lang[key] = values[key];
10480  }
10481  }
10482  };
10483 
10484  //set current locale
10485 
10486  Localize.prototype.setLocale = function (desiredLocale) {
10487 
10488  var self = this;
10489 
10490  desiredLocale = desiredLocale || "default";
10491 
10492  //fill in any matching languge values
10493 
10494  function traverseLang(trans, path) {
10495 
10496  for (var prop in trans) {
10497 
10498  if (_typeof(trans[prop]) == "object") {
10499 
10500  if (!path[prop]) {
10501 
10502  path[prop] = {};
10503  }
10504 
10505  traverseLang(trans[prop], path[prop]);
10506  } else {
10507 
10508  path[prop] = trans[prop];
10509  }
10510  }
10511  }
10512 
10513  //determing correct locale to load
10514 
10515  if (desiredLocale === true && navigator.language) {
10516 
10517  //get local from system
10518 
10519  desiredLocale = navigator.language.toLowerCase();
10520  }
10521 
10522  if (desiredLocale) {
10523 
10524  //if locale is not set, check for matching top level locale else use default
10525 
10526  if (!self.langs[desiredLocale]) {
10527 
10528  var prefix = desiredLocale.split("-")[0];
10529 
10530  if (self.langs[prefix]) {
10531 
10532  console.warn("Localization Error - Exact matching locale not found, using closest match: ", desiredLocale, prefix);
10533 
10534  desiredLocale = prefix;
10535  } else {
10536 
10537  console.warn("Localization Error - Matching locale not found, using default: ", desiredLocale);
10538 
10539  desiredLocale = "default";
10540  }
10541  }
10542  }
10543 
10544  self.locale = desiredLocale;
10545 
10546  //load default lang template
10547 
10548  self.lang = Tabulator.prototype.helpers.deepClone(self.langs.default || {});
10549 
10550  if (desiredLocale != "default") {
10551 
10552  traverseLang(self.langs[desiredLocale], self.lang);
10553  }
10554 
10555  self.table.options.localized.call(self.table, self.locale, self.lang);
10556 
10557  self._executeBindings();
10558  };
10559 
10560  //get current locale
10561 
10562  Localize.prototype.getLocale = function (locale) {
10563 
10564  return self.locale;
10565  };
10566 
10567  //get lang object for given local or current if none provided
10568 
10569  Localize.prototype.getLang = function (locale) {
10570 
10571  return locale ? this.langs[locale] : this.lang;
10572  };
10573 
10574  //get text for current locale
10575 
10576  Localize.prototype.getText = function (path, value) {
10577 
10578  var path = value ? path + "|" + value : path,
10579  pathArray = path.split("|"),
10580  text = this._getLangElement(pathArray, this.locale);
10581 
10582  // if(text === false){
10583 
10584  // console.warn("Localization Error - Matching localized text not found for given path: ", path);
10585 
10586  // }
10587 
10588 
10589  return text || "";
10590  };
10591 
10592  //traverse langs object and find localized copy
10593 
10594  Localize.prototype._getLangElement = function (path, locale) {
10595 
10596  var self = this;
10597 
10598  var root = self.lang;
10599 
10600  path.forEach(function (level) {
10601 
10602  var rootPath;
10603 
10604  if (root) {
10605 
10606  rootPath = root[level];
10607 
10608  if (typeof rootPath != "undefined") {
10609 
10610  root = rootPath;
10611  } else {
10612 
10613  root = false;
10614  }
10615  }
10616  });
10617 
10618  return root;
10619  };
10620 
10621  //set update binding
10622 
10623  Localize.prototype.bind = function (path, callback) {
10624 
10625  if (!this.bindings[path]) {
10626 
10627  this.bindings[path] = [];
10628  }
10629 
10630  this.bindings[path].push(callback);
10631 
10632  callback(this.getText(path), this.lang);
10633  };
10634 
10635  //itterate through bindings and trigger updates
10636 
10637  Localize.prototype._executeBindings = function () {
10638 
10639  var self = this;
10640 
10641  var _loop = function _loop(path) {
10642 
10643  self.bindings[path].forEach(function (binding) {
10644 
10645  binding(self.getText(path), self.lang);
10646  });
10647  };
10648 
10649  for (var path in self.bindings) {
10650  _loop(path);
10651  }
10652  };
10653 
10654  //Localized text listings
10655 
10656  Localize.prototype.langs = {
10657 
10658  "default": { //hold default locale text
10659 
10660  "groups": {
10661 
10662  "item": "item",
10663 
10664  "items": "items"
10665 
10666  },
10667 
10668  "columns": {},
10669 
10670  "ajax": {
10671 
10672  "loading": "Loading",
10673 
10674  "error": "Error"
10675 
10676  },
10677 
10678  "pagination": {
10679 
10680  "page_size": "Page Size",
10681 
10682  "first": "First",
10683 
10684  "first_title": "First Page",
10685 
10686  "last": "Last",
10687 
10688  "last_title": "Last Page",
10689 
10690  "prev": "Prev",
10691 
10692  "prev_title": "Prev Page",
10693 
10694  "next": "Next",
10695 
10696  "next_title": "Next Page"
10697 
10698  },
10699 
10700  "headerFilters": {
10701 
10702  "default": "filter column...",
10703 
10704  "columns": {}
10705 
10706  }
10707 
10708  }
10709 
10710  };
10711 
10712  Tabulator.prototype.registerModule("localize", Localize);
10713 
10714  var Comms = function Comms(table) {
10715 
10716  this.table = table;
10717  };
10718 
10719  Comms.prototype.getConnections = function (selectors) {
10720 
10721  var self = this,
10722  connections = [],
10723  connection;
10724 
10725  connection = Tabulator.prototype.comms.lookupTable(selectors);
10726 
10727  connection.forEach(function (con) {
10728 
10729  if (self.table !== con) {
10730 
10731  connections.push(con);
10732  }
10733  });
10734 
10735  return connections;
10736  };
10737 
10738  Comms.prototype.send = function (selectors, module, action, data) {
10739 
10740  var self = this,
10741  connections = this.getConnections(selectors);
10742 
10743  connections.forEach(function (connection) {
10744 
10745  connection.tableComms(self.table.element, module, action, data);
10746  });
10747 
10748  if (!connections.length && selectors) {
10749 
10750  console.warn("Table Connection Error - No tables matching selector found", selectors);
10751  }
10752  };
10753 
10754  Comms.prototype.receive = function (table, module, action, data) {
10755 
10756  if (this.table.modExists(module)) {
10757 
10758  return this.table.modules[module].commsReceived(table, action, data);
10759  } else {
10760 
10761  console.warn("Inter-table Comms Error - no such module:", module);
10762  }
10763  };
10764 
10765  Tabulator.prototype.registerModule("comms", Comms);
10766 
10767  var Accessor = function Accessor(table) {
10768  this.table = table; //hold Tabulator object
10769  this.allowedTypes = ["", "data", "download", "clipboard"]; //list of accessor types
10770  };
10771 
10772  //initialize column accessor
10773  Accessor.prototype.initializeColumn = function (column) {
10774  var self = this,
10775  match = false,
10776  config = {};
10777 
10778  this.allowedTypes.forEach(function (type) {
10779  var key = "accessor" + (type.charAt(0).toUpperCase() + type.slice(1)),
10780  accessor;
10781 
10782  if (column.definition[key]) {
10783  accessor = self.lookupAccessor(column.definition[key]);
10784 
10785  if (accessor) {
10786  match = true;
10787 
10788  config[key] = {
10789  accessor: accessor,
10790  params: column.definition[key + "Params"] || {}
10791  };
10792  }
10793  }
10794  });
10795 
10796  if (match) {
10797  column.modules.accessor = config;
10798  }
10799  }, Accessor.prototype.lookupAccessor = function (value) {
10800  var accessor = false;
10801 
10802  //set column accessor
10803  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
10804  case "string":
10805  if (this.accessors[value]) {
10806  accessor = this.accessors[value];
10807  } else {
10808  console.warn("Accessor Error - No such accessor found, ignoring: ", value);
10809  }
10810  break;
10811 
10812  case "function":
10813  accessor = value;
10814  break;
10815  }
10816 
10817  return accessor;
10818  };
10819 
10820  //apply accessor to row
10821  Accessor.prototype.transformRow = function (dataIn, type) {
10822  var self = this,
10823  key = "accessor" + (type.charAt(0).toUpperCase() + type.slice(1));
10824 
10825  //clone data object with deep copy to isolate internal data from returned result
10826  var data = Tabulator.prototype.helpers.deepClone(dataIn || {});
10827 
10828  self.table.columnManager.traverse(function (column) {
10829  var value, accessor, params, component;
10830 
10831  if (column.modules.accessor) {
10832 
10833  accessor = column.modules.accessor[key] || column.modules.accessor.accessor || false;
10834 
10835  if (accessor) {
10836  value = column.getFieldValue(data);
10837 
10838  if (value != "undefined") {
10839  component = column.getComponent();
10840  params = typeof accessor.params === "function" ? accessor.params(value, data, type, component) : accessor.params;
10841  column.setFieldValue(data, accessor.accessor(value, data, type, params, component));
10842  }
10843  }
10844  }
10845  });
10846 
10847  return data;
10848  },
10849 
10850  //default accessors
10851  Accessor.prototype.accessors = {};
10852 
10853  Tabulator.prototype.registerModule("accessor", Accessor);
10854  var Ajax = function Ajax(table) {
10855 
10856  this.table = table; //hold Tabulator object
10857  this.config = false; //hold config object for ajax request
10858  this.url = ""; //request URL
10859  this.urlGenerator = false;
10860  this.params = false; //request parameters
10861 
10862  this.loaderElement = this.createLoaderElement(); //loader message div
10863  this.msgElement = this.createMsgElement(); //message element
10864  this.loadingElement = false;
10865  this.errorElement = false;
10866  this.loaderPromise = false;
10867 
10868  this.progressiveLoad = false;
10869  this.loading = false;
10870 
10871  this.requestOrder = 0; //prevent requests comming out of sequence if overridden by another load request
10872  };
10873 
10874  //initialize setup options
10875  Ajax.prototype.initialize = function () {
10876  var template;
10877 
10878  this.loaderElement.appendChild(this.msgElement);
10879 
10880  if (this.table.options.ajaxLoaderLoading) {
10881  if (typeof this.table.options.ajaxLoaderLoading == "string") {
10882  template = document.createElement('template');
10883  template.innerHTML = this.table.options.ajaxLoaderLoading.trim();
10884  this.loadingElement = template.content.firstChild;
10885  } else {
10886  this.loadingElement = this.table.options.ajaxLoaderLoading;
10887  }
10888  }
10889 
10890  this.loaderPromise = this.table.options.ajaxRequestFunc || this.defaultLoaderPromise;
10891 
10892  this.urlGenerator = this.table.options.ajaxURLGenerator || this.defaultURLGenerator;
10893 
10894  if (this.table.options.ajaxLoaderError) {
10895  if (typeof this.table.options.ajaxLoaderError == "string") {
10896  template = document.createElement('template');
10897  template.innerHTML = this.table.options.ajaxLoaderError.trim();
10898  this.errorElement = template.content.firstChild;
10899  } else {
10900  this.errorElement = this.table.options.ajaxLoaderError;
10901  }
10902  }
10903 
10904  if (this.table.options.ajaxParams) {
10905  this.setParams(this.table.options.ajaxParams);
10906  }
10907 
10908  if (this.table.options.ajaxConfig) {
10909  this.setConfig(this.table.options.ajaxConfig);
10910  }
10911 
10912  if (this.table.options.ajaxURL) {
10913  this.setUrl(this.table.options.ajaxURL);
10914  }
10915 
10916  if (this.table.options.ajaxProgressiveLoad) {
10917  if (this.table.options.pagination) {
10918  this.progressiveLoad = false;
10919  console.error("Progressive Load Error - Pagination and progressive load cannot be used at the same time");
10920  } else {
10921  if (this.table.modExists("page")) {
10922  this.progressiveLoad = this.table.options.ajaxProgressiveLoad;
10923  this.table.modules.page.initializeProgressive(this.progressiveLoad);
10924  } else {
10925  console.error("Pagination plugin is required for progressive ajax loading");
10926  }
10927  }
10928  }
10929  };
10930 
10931  Ajax.prototype.createLoaderElement = function () {
10932  var el = document.createElement("div");
10933  el.classList.add("tabulator-loader");
10934  return el;
10935  };
10936 
10937  Ajax.prototype.createMsgElement = function () {
10938  var el = document.createElement("div");
10939 
10940  el.classList.add("tabulator-loader-msg");
10941  el.setAttribute("role", "alert");
10942 
10943  return el;
10944  };
10945 
10946  //set ajax params
10947  Ajax.prototype.setParams = function (params, update) {
10948  if (update) {
10949  this.params = this.params || {};
10950 
10951  for (var key in params) {
10952  this.params[key] = params[key];
10953  }
10954  } else {
10955  this.params = params;
10956  }
10957  };
10958 
10959  Ajax.prototype.getParams = function () {
10960  return this.params || {};
10961  };
10962 
10963  //load config object
10964  Ajax.prototype.setConfig = function (config) {
10965  this._loadDefaultConfig();
10966 
10967  if (typeof config == "string") {
10968  this.config.method = config;
10969  } else {
10970  for (var key in config) {
10971  this.config[key] = config[key];
10972  }
10973  }
10974  };
10975 
10976  //create config object from default
10977  Ajax.prototype._loadDefaultConfig = function (force) {
10978  var self = this;
10979  if (!self.config || force) {
10980 
10981  self.config = {};
10982 
10983  //load base config from defaults
10984  for (var key in self.defaultConfig) {
10985  self.config[key] = self.defaultConfig[key];
10986  }
10987  }
10988  };
10989 
10990  //set request url
10991  Ajax.prototype.setUrl = function (url) {
10992  this.url = url;
10993  };
10994 
10995  //get request url
10996  Ajax.prototype.getUrl = function () {
10997  return this.url;
10998  };
10999 
11000  //lstandard loading function
11001  Ajax.prototype.loadData = function (inPosition) {
11002  var self = this;
11003 
11004  if (this.progressiveLoad) {
11005  return this._loadDataProgressive();
11006  } else {
11007  return this._loadDataStandard(inPosition);
11008  }
11009  };
11010 
11011  Ajax.prototype.nextPage = function (diff) {
11012  var margin;
11013 
11014  if (!this.loading) {
11015 
11016  margin = this.table.options.ajaxProgressiveLoadScrollMargin || this.table.rowManager.getElement().clientHeight * 2;
11017 
11018  if (diff < margin) {
11019  this.table.modules.page.nextPage().then(function () {}).catch(function () {});
11020  }
11021  }
11022  };
11023 
11024  Ajax.prototype.blockActiveRequest = function () {
11025  this.requestOrder++;
11026  };
11027 
11028  Ajax.prototype._loadDataProgressive = function () {
11029  this.table.rowManager.setData([]);
11030  return this.table.modules.page.setPage(1);
11031  };
11032 
11033  Ajax.prototype._loadDataStandard = function (inPosition) {
11034  var _this31 = this;
11035 
11036  return new Promise(function (resolve, reject) {
11037  _this31.sendRequest(inPosition).then(function (data) {
11038  _this31.table.rowManager.setData(data, inPosition).then(function () {
11039  resolve();
11040  }).catch(function (e) {
11041  reject(e);
11042  });
11043  }).catch(function (e) {
11044  reject(e);
11045  });
11046  });
11047  };
11048 
11049  Ajax.prototype.generateParamsList = function (data, prefix) {
11050  var self = this,
11051  output = [];
11052 
11053  prefix = prefix || "";
11054 
11055  if (Array.isArray(data)) {
11056  data.forEach(function (item, i) {
11057  output = output.concat(self.generateParamsList(item, prefix ? prefix + "[" + i + "]" : i));
11058  });
11059  } else if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === "object") {
11060  for (var key in data) {
11061  output = output.concat(self.generateParamsList(data[key], prefix ? prefix + "[" + key + "]" : key));
11062  }
11063  } else {
11064  output.push({ key: prefix, value: data });
11065  }
11066 
11067  return output;
11068  };
11069 
11070  Ajax.prototype.serializeParams = function (params) {
11071  var output = this.generateParamsList(params),
11072  encoded = [];
11073 
11074  output.forEach(function (item) {
11075  encoded.push(encodeURIComponent(item.key) + "=" + encodeURIComponent(item.value));
11076  });
11077 
11078  return encoded.join("&");
11079  };
11080 
11081  //send ajax request
11082  Ajax.prototype.sendRequest = function (silent) {
11083  var _this32 = this;
11084 
11085  var self = this,
11086  url = self.url,
11087  requestNo,
11088  esc,
11089  query;
11090 
11091  self.requestOrder++;
11092  requestNo = self.requestOrder;
11093 
11094  self._loadDefaultConfig();
11095 
11096  return new Promise(function (resolve, reject) {
11097  if (self.table.options.ajaxRequesting.call(_this32.table, self.url, self.params) !== false) {
11098 
11099  self.loading = true;
11100 
11101  if (!silent) {
11102  self.showLoader();
11103  }
11104 
11105  _this32.loaderPromise(url, self.config, self.params).then(function (data) {
11106  if (requestNo === self.requestOrder) {
11107  if (self.table.options.ajaxResponse) {
11108  data = self.table.options.ajaxResponse.call(self.table, self.url, self.params, data);
11109  }
11110  resolve(data);
11111  } else {
11112  console.warn("Ajax Response Blocked - An active ajax request was blocked by an attempt to change table data while the request was being made");
11113  }
11114 
11115  self.hideLoader();
11116 
11117  self.loading = false;
11118  }).catch(function (error) {
11119  console.error("Ajax Load Error: ", error);
11120  self.table.options.ajaxError.call(self.table, error);
11121 
11122  self.showError();
11123 
11124  setTimeout(function () {
11125  self.hideLoader();
11126  }, 3000);
11127 
11128  self.loading = false;
11129 
11130  reject();
11131  });
11132  } else {
11133  reject();
11134  }
11135  });
11136  };
11137 
11138  Ajax.prototype.showLoader = function () {
11139  var shouldLoad = typeof this.table.options.ajaxLoader === "function" ? this.table.options.ajaxLoader() : this.table.options.ajaxLoader;
11140 
11141  if (shouldLoad) {
11142 
11143  this.hideLoader();
11144 
11145  while (this.msgElement.firstChild) {
11146  this.msgElement.removeChild(this.msgElement.firstChild);
11147  }this.msgElement.classList.remove("tabulator-error");
11148  this.msgElement.classList.add("tabulator-loading");
11149 
11150  if (this.loadingElement) {
11151  this.msgElement.appendChild(this.loadingElement);
11152  } else {
11153  this.msgElement.innerHTML = this.table.modules.localize.getText("ajax|loading");
11154  }
11155 
11156  this.table.element.appendChild(this.loaderElement);
11157  }
11158  };
11159 
11160  Ajax.prototype.showError = function () {
11161  this.hideLoader();
11162 
11163  while (this.msgElement.firstChild) {
11164  this.msgElement.removeChild(this.msgElement.firstChild);
11165  }this.msgElement.classList.remove("tabulator-loading");
11166  this.msgElement.classList.add("tabulator-error");
11167 
11168  if (this.errorElement) {
11169  this.msgElement.appendChild(this.errorElement);
11170  } else {
11171  this.msgElement.innerHTML = this.table.modules.localize.getText("ajax|error");
11172  }
11173 
11174  this.table.element.appendChild(this.loaderElement);
11175  };
11176 
11177  Ajax.prototype.hideLoader = function () {
11178  if (this.loaderElement.parentNode) {
11179  this.loaderElement.parentNode.removeChild(this.loaderElement);
11180  }
11181  };
11182 
11183  //default ajax config object
11184  Ajax.prototype.defaultConfig = {
11185  method: "GET"
11186  };
11187 
11188  Ajax.prototype.defaultURLGenerator = function (url, config, params) {
11189 
11190  if (url) {
11191  if (params && Object.keys(params).length) {
11192  if (!config.method || config.method.toLowerCase() == "get") {
11193  config.method = "get";
11194 
11195  url += (url.includes("?") ? "&" : "?") + this.serializeParams(params);
11196  }
11197  }
11198  }
11199 
11200  return url;
11201  };
11202 
11203  Ajax.prototype.defaultLoaderPromise = function (url, config, params) {
11204  var self = this,
11205  contentType;
11206 
11207  return new Promise(function (resolve, reject) {
11208 
11209  //set url
11210  url = self.urlGenerator(url, config, params);
11211 
11212  //set body content if not GET request
11213  if (config.method.toUpperCase() != "GET") {
11214  contentType = _typeof(self.table.options.ajaxContentType) === "object" ? self.table.options.ajaxContentType : self.contentTypeFormatters[self.table.options.ajaxContentType];
11215  if (contentType) {
11216 
11217  for (var key in contentType.headers) {
11218  if (!config.headers) {
11219  config.headers = {};
11220  }
11221 
11222  if (typeof config.headers[key] === "undefined") {
11223  config.headers[key] = contentType.headers[key];
11224  }
11225  }
11226 
11227  config.body = contentType.body.call(self, url, config, params);
11228  } else {
11229  console.warn("Ajax Error - Invalid ajaxContentType value:", self.table.options.ajaxContentType);
11230  }
11231  }
11232 
11233  if (url) {
11234 
11235  //configure headers
11236  if (typeof config.headers === "undefined") {
11237  config.headers = {};
11238  }
11239 
11240  if (typeof config.headers.Accept === "undefined") {
11241  config.headers.Accept = "application/json";
11242  }
11243 
11244  if (typeof config.headers["X-Requested-With"] === "undefined") {
11245  config.headers["X-Requested-With"] = "XMLHttpRequest";
11246  }
11247 
11248  if (typeof config.mode === "undefined") {
11249  config.mode = "cors";
11250  }
11251 
11252  if (config.mode == "cors") {
11253 
11254  if (typeof config.headers["Access-Control-Allow-Origin"] === "undefined") {
11255  config.headers["Access-Control-Allow-Origin"] = window.location.origin;
11256  }
11257 
11258  if (typeof config.credentials === "undefined") {
11259  config.credentials = 'same-origin';
11260  }
11261  } else {
11262  if (typeof config.credentials === "undefined") {
11263  config.credentials = 'include';
11264  }
11265  }
11266 
11267  //send request
11268  fetch(url, config).then(function (response) {
11269  if (response.ok) {
11270  response.json().then(function (data) {
11271  resolve(data);
11272  }).catch(function (error) {
11273  reject(error);
11274  console.warn("Ajax Load Error - Invalid JSON returned", error);
11275  });
11276  } else {
11277  console.error("Ajax Load Error - Connection Error: " + response.status, response.statusText);
11278  reject(response);
11279  }
11280  }).catch(function (error) {
11281  console.error("Ajax Load Error - Connection Error: ", error);
11282  reject(error);
11283  });
11284  } else {
11285  console.warn("Ajax Load Error - No URL Set");
11286  resolve([]);
11287  }
11288  });
11289  };
11290 
11291  Ajax.prototype.contentTypeFormatters = {
11292  "json": {
11293  headers: {
11294  'Content-Type': 'application/json'
11295  },
11296  body: function body(url, config, params) {
11297  return JSON.stringify(params);
11298  }
11299  },
11300  "form": {
11301  headers: {},
11302  body: function body(url, config, params) {
11303  var output = this.generateParamsList(params),
11304  form = new FormData();
11305 
11306  output.forEach(function (item) {
11307  form.append(item.key, item.value);
11308  });
11309 
11310  return form;
11311  }
11312  }
11313  };
11314 
11315  Tabulator.prototype.registerModule("ajax", Ajax);
11316 
11317  var ColumnCalcs = function ColumnCalcs(table) {
11318  this.table = table; //hold Tabulator object
11319  this.topCalcs = [];
11320  this.botCalcs = [];
11321  this.genColumn = false;
11322  this.topElement = this.createElement();
11323  this.botElement = this.createElement();
11324  this.topRow = false;
11325  this.botRow = false;
11326  this.topInitialized = false;
11327  this.botInitialized = false;
11328 
11329  this.initialize();
11330  };
11331 
11332  ColumnCalcs.prototype.createElement = function () {
11333  var el = document.createElement("div");
11334  el.classList.add("tabulator-calcs-holder");
11335  return el;
11336  };
11337 
11338  ColumnCalcs.prototype.initialize = function () {
11339  this.genColumn = new Column({ field: "value" }, this);
11340  };
11341 
11342  //dummy functions to handle being mock column manager
11343  ColumnCalcs.prototype.registerColumnField = function () {};
11344 
11345  //initialize column calcs
11346  ColumnCalcs.prototype.initializeColumn = function (column) {
11347  var def = column.definition;
11348 
11349  var config = {
11350  topCalcParams: def.topCalcParams || {},
11351  botCalcParams: def.bottomCalcParams || {}
11352  };
11353 
11354  if (def.topCalc) {
11355 
11356  switch (_typeof(def.topCalc)) {
11357  case "string":
11358  if (this.calculations[def.topCalc]) {
11359  config.topCalc = this.calculations[def.topCalc];
11360  } else {
11361  console.warn("Column Calc Error - No such calculation found, ignoring: ", def.topCalc);
11362  }
11363  break;
11364 
11365  case "function":
11366  config.topCalc = def.topCalc;
11367  break;
11368 
11369  }
11370 
11371  if (config.topCalc) {
11372  column.modules.columnCalcs = config;
11373  this.topCalcs.push(column);
11374 
11375  if (this.table.options.columnCalcs != "group") {
11376  this.initializeTopRow();
11377  }
11378  }
11379  }
11380 
11381  if (def.bottomCalc) {
11382  switch (_typeof(def.bottomCalc)) {
11383  case "string":
11384  if (this.calculations[def.bottomCalc]) {
11385  config.botCalc = this.calculations[def.bottomCalc];
11386  } else {
11387  console.warn("Column Calc Error - No such calculation found, ignoring: ", def.bottomCalc);
11388  }
11389  break;
11390 
11391  case "function":
11392  config.botCalc = def.bottomCalc;
11393  break;
11394 
11395  }
11396 
11397  if (config.botCalc) {
11398  column.modules.columnCalcs = config;
11399  this.botCalcs.push(column);
11400 
11401  if (this.table.options.columnCalcs != "group") {
11402  this.initializeBottomRow();
11403  }
11404  }
11405  }
11406  };
11407 
11408  ColumnCalcs.prototype.removeCalcs = function () {
11409  var changed = false;
11410 
11411  if (this.topInitialized) {
11412  this.topInitialized = false;
11413  this.topElement.parentNode.removeChild(this.topElement);
11414  changed = true;
11415  }
11416 
11417  if (this.botInitialized) {
11418  this.botInitialized = false;
11419  this.table.footerManager.remove(this.botElement);
11420  changed = true;
11421  }
11422 
11423  if (changed) {
11424  this.table.rowManager.adjustTableSize();
11425  }
11426  };
11427 
11428  ColumnCalcs.prototype.initializeTopRow = function () {
11429  if (!this.topInitialized) {
11430  // this.table.columnManager.headersElement.after(this.topElement);
11431  this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
11432  this.topInitialized = true;
11433  }
11434  };
11435 
11436  ColumnCalcs.prototype.initializeBottomRow = function () {
11437  if (!this.botInitialized) {
11438  this.table.footerManager.prepend(this.botElement);
11439  this.botInitialized = true;
11440  }
11441  };
11442 
11443  ColumnCalcs.prototype.scrollHorizontal = function (left) {
11444  var hozAdjust = 0,
11445  scrollWidth = this.table.columnManager.getElement().scrollWidth - this.table.element.clientWidth;
11446 
11447  if (this.botInitialized) {
11448  this.botRow.getElement().style.marginLeft = -left + "px";
11449  }
11450  };
11451 
11452  ColumnCalcs.prototype.recalc = function (rows) {
11453  var data, row;
11454 
11455  if (this.topInitialized || this.botInitialized) {
11456  data = this.rowsToData(rows);
11457 
11458  if (this.topInitialized) {
11459  if (this.topRow) {
11460  this.topRow.deleteCells();
11461  }
11462 
11463  row = this.generateRow("top", this.rowsToData(rows));
11464  this.topRow = row;
11465  while (this.topElement.firstChild) {
11466  this.topElement.removeChild(this.topElement.firstChild);
11467  }this.topElement.appendChild(row.getElement());
11468  row.initialize(true);
11469  }
11470 
11471  if (this.botInitialized) {
11472  if (this.botRow) {
11473  this.botRow.deleteCells();
11474  }
11475 
11476  row = this.generateRow("bottom", this.rowsToData(rows));
11477  this.botRow = row;
11478  while (this.botElement.firstChild) {
11479  this.botElement.removeChild(this.botElement.firstChild);
11480  }this.botElement.appendChild(row.getElement());
11481  row.initialize(true);
11482  }
11483 
11484  this.table.rowManager.adjustTableSize();
11485 
11486  //set resizable handles
11487  if (this.table.modExists("frozenColumns")) {
11488  this.table.modules.frozenColumns.layout();
11489  }
11490  }
11491  };
11492 
11493  ColumnCalcs.prototype.recalcRowGroup = function (row) {
11494  this.recalcGroup(this.table.modules.groupRows.getRowGroup(row));
11495  };
11496 
11497  ColumnCalcs.prototype.recalcGroup = function (group) {
11498  var data, rowData;
11499 
11500  if (group) {
11501  if (group.calcs) {
11502  if (group.calcs.bottom) {
11503  data = this.rowsToData(group.rows);
11504  rowData = this.generateRowData("bottom", data);
11505 
11506  group.calcs.bottom.updateData(rowData);
11507  group.calcs.bottom.reinitialize();
11508  }
11509 
11510  if (group.calcs.top) {
11511  data = this.rowsToData(group.rows);
11512  rowData = this.generateRowData("top", data);
11513 
11514  group.calcs.top.updateData(rowData);
11515  group.calcs.top.reinitialize();
11516  }
11517  }
11518  }
11519  };
11520 
11521  //generate top stats row
11522  ColumnCalcs.prototype.generateTopRow = function (rows) {
11523  return this.generateRow("top", this.rowsToData(rows));
11524  };
11525  //generate bottom stats row
11526  ColumnCalcs.prototype.generateBottomRow = function (rows) {
11527  return this.generateRow("bottom", this.rowsToData(rows));
11528  };
11529 
11530  ColumnCalcs.prototype.rowsToData = function (rows) {
11531  var data = [];
11532 
11533  rows.forEach(function (row) {
11534  data.push(row.getData());
11535  });
11536 
11537  return data;
11538  };
11539 
11540  //generate stats row
11541  ColumnCalcs.prototype.generateRow = function (pos, data) {
11542  var self = this,
11543  rowData = this.generateRowData(pos, data),
11544  row;
11545 
11546  if (self.table.modExists("mutator")) {
11547  self.table.modules.mutator.disable();
11548  }
11549 
11550  row = new Row(rowData, this, "calc");
11551 
11552  if (self.table.modExists("mutator")) {
11553  self.table.modules.mutator.enable();
11554  }
11555 
11556  row.getElement().classList.add("tabulator-calcs", "tabulator-calcs-" + pos);
11557 
11558  row.generateCells = function () {
11559 
11560  var cells = [];
11561 
11562  self.table.columnManager.columnsByIndex.forEach(function (column) {
11563 
11564  //set field name of mock column
11565  self.genColumn.setField(column.getField());
11566  self.genColumn.hozAlign = column.hozAlign;
11567 
11568  if (column.definition[pos + "CalcFormatter"] && self.table.modExists("format")) {
11569 
11570  self.genColumn.modules.format = {
11571  formatter: self.table.modules.format.getFormatter(column.definition[pos + "CalcFormatter"]),
11572  params: column.definition[pos + "CalcFormatterParams"]
11573  };
11574  } else {
11575  self.genColumn.modules.format = {
11576  formatter: self.table.modules.format.getFormatter("plaintext"),
11577  params: {}
11578  };
11579  }
11580 
11581  //ensure css class defintion is replicated to calculation cell
11582  self.genColumn.definition.cssClass = column.definition.cssClass;
11583 
11584  //generate cell and assign to correct column
11585  var cell = new Cell(self.genColumn, row);
11586  cell.column = column;
11587  cell.setWidth();
11588 
11589  column.cells.push(cell);
11590  cells.push(cell);
11591 
11592  if (!column.visible) {
11593  cell.hide();
11594  }
11595  });
11596 
11597  this.cells = cells;
11598  };
11599 
11600  return row;
11601  };
11602 
11603  //generate stats row
11604  ColumnCalcs.prototype.generateRowData = function (pos, data) {
11605  var rowData = {},
11606  calcs = pos == "top" ? this.topCalcs : this.botCalcs,
11607  type = pos == "top" ? "topCalc" : "botCalc",
11608  params,
11609  paramKey;
11610 
11611  calcs.forEach(function (column) {
11612  var values = [];
11613 
11614  if (column.modules.columnCalcs && column.modules.columnCalcs[type]) {
11615  data.forEach(function (item) {
11616  values.push(column.getFieldValue(item));
11617  });
11618 
11619  paramKey = type + "Params";
11620  params = typeof column.modules.columnCalcs[paramKey] === "function" ? column.modules.columnCalcs[paramKey](values, data) : column.modules.columnCalcs[paramKey];
11621 
11622  column.setFieldValue(rowData, column.modules.columnCalcs[type](values, data, params));
11623  }
11624  });
11625 
11626  return rowData;
11627  };
11628 
11629  ColumnCalcs.prototype.hasTopCalcs = function () {
11630  return !!this.topCalcs.length;
11631  };
11632 
11633  ColumnCalcs.prototype.hasBottomCalcs = function () {
11634  return !!this.botCalcs.length;
11635  };
11636 
11637  //handle table redraw
11638  ColumnCalcs.prototype.redraw = function () {
11639  if (this.topRow) {
11640  this.topRow.normalizeHeight(true);
11641  }
11642  if (this.botRow) {
11643  this.botRow.normalizeHeight(true);
11644  }
11645  };
11646 
11647  //return the calculated
11648  ColumnCalcs.prototype.getResults = function () {
11649  var self = this,
11650  results = {},
11651  groups;
11652 
11653  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
11654  groups = this.table.modules.groupRows.getGroups(true);
11655 
11656  groups.forEach(function (group) {
11657  results[group.getKey()] = self.getGroupResults(group);
11658  });
11659  } else {
11660  results = {
11661  top: this.topRow ? this.topRow.getData() : {},
11662  bottom: this.botRow ? this.botRow.getData() : {}
11663  };
11664  }
11665 
11666  return results;
11667  };
11668 
11669  //get results from a group
11670  ColumnCalcs.prototype.getGroupResults = function (group) {
11671  var self = this,
11672  groupObj = group._getSelf(),
11673  subGroups = group.getSubGroups(),
11674  subGroupResults = {},
11675  results = {};
11676 
11677  subGroups.forEach(function (subgroup) {
11678  subGroupResults[subgroup.getKey()] = self.getGroupResults(subgroup);
11679  });
11680 
11681  results = {
11682  top: groupObj.calcs.top ? groupObj.calcs.top.getData() : {},
11683  bottom: groupObj.calcs.bottom ? groupObj.calcs.bottom.getData() : {},
11684  groups: subGroupResults
11685  };
11686 
11687  return results;
11688  };
11689 
11690  //default calculations
11691  ColumnCalcs.prototype.calculations = {
11692  "avg": function avg(values, data, calcParams) {
11693  var output = 0,
11694  precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : 2;
11695 
11696  if (values.length) {
11697  output = values.reduce(function (sum, value) {
11698  value = Number(value);
11699  return sum + value;
11700  });
11701 
11702  output = output / values.length;
11703 
11704  output = precision !== false ? output.toFixed(precision) : output;
11705  }
11706 
11707  return parseFloat(output).toString();
11708  },
11709  "max": function max(values, data, calcParams) {
11710  var output = null,
11711  precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : false;
11712 
11713  values.forEach(function (value) {
11714 
11715  value = Number(value);
11716 
11717  if (value > output || output === null) {
11718  output = value;
11719  }
11720  });
11721 
11722  return output !== null ? precision !== false ? output.toFixed(precision) : output : "";
11723  },
11724  "min": function min(values, data, calcParams) {
11725  var output = null,
11726  precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : false;
11727 
11728  values.forEach(function (value) {
11729 
11730  value = Number(value);
11731 
11732  if (value < output || output === null) {
11733  output = value;
11734  }
11735  });
11736 
11737  return output !== null ? precision !== false ? output.toFixed(precision) : output : "";
11738  },
11739  "sum": function sum(values, data, calcParams) {
11740  var output = 0,
11741  precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : false;
11742 
11743  if (values.length) {
11744  values.forEach(function (value) {
11745  value = Number(value);
11746 
11747  output += !isNaN(value) ? Number(value) : 0;
11748  });
11749  }
11750 
11751  return precision !== false ? output.toFixed(precision) : output;
11752  },
11753  "concat": function concat(values, data, calcParams) {
11754  var output = 0;
11755 
11756  if (values.length) {
11757  output = values.reduce(function (sum, value) {
11758  return String(sum) + String(value);
11759  });
11760  }
11761 
11762  return output;
11763  },
11764  "count": function count(values, data, calcParams) {
11765  var output = 0;
11766 
11767  if (values.length) {
11768  values.forEach(function (value) {
11769  if (value) {
11770  output++;
11771  }
11772  });
11773  }
11774 
11775  return output;
11776  }
11777  };
11778 
11779  Tabulator.prototype.registerModule("columnCalcs", ColumnCalcs);
11780 
11781  var Clipboard = function Clipboard(table) {
11782  this.table = table;
11783  this.mode = true;
11784  this.copySelector = false;
11785  this.copySelectorParams = {};
11786  this.copyFormatter = false;
11787  this.copyFormatterParams = {};
11788  this.pasteParser = function () {};
11789  this.pasteAction = function () {};
11790  this.htmlElement = false;
11791  this.config = {};
11792 
11793  this.blocked = true; //block copy actions not originating from this command
11794  };
11795 
11796  Clipboard.prototype.initialize = function () {
11797  var self = this;
11798 
11799  this.mode = this.table.options.clipboard;
11800 
11801  if (this.mode === true || this.mode === "copy") {
11802  this.table.element.addEventListener("copy", function (e) {
11803  var data;
11804 
11805  self.processConfig();
11806 
11807  if (!self.blocked) {
11808  e.preventDefault();
11809 
11810  data = self.generateContent();
11811 
11812  if (window.clipboardData && window.clipboardData.setData) {
11813  window.clipboardData.setData('Text', data);
11814  } else if (e.clipboardData && e.clipboardData.setData) {
11815  e.clipboardData.setData('text/plain', data);
11816  if (self.htmlElement) {
11817  e.clipboardData.setData('text/html', self.htmlElement.outerHTML);
11818  }
11819  } else if (e.originalEvent && e.originalEvent.clipboardData.setData) {
11820  e.originalEvent.clipboardData.setData('text/plain', data);
11821  if (self.htmlElement) {
11822  e.originalEvent.clipboardData.setData('text/html', self.htmlElement.outerHTML);
11823  }
11824  }
11825 
11826  self.table.options.clipboardCopied.call(this.table, data);
11827 
11828  self.reset();
11829  }
11830  });
11831  }
11832 
11833  if (this.mode === true || this.mode === "paste") {
11834  this.table.element.addEventListener("paste", function (e) {
11835  self.paste(e);
11836  });
11837  }
11838 
11839  this.setPasteParser(this.table.options.clipboardPasteParser);
11840  this.setPasteAction(this.table.options.clipboardPasteAction);
11841  };
11842 
11843  Clipboard.prototype.processConfig = function () {
11844  var config = {
11845  columnHeaders: "groups",
11846  rowGroups: true,
11847  columnCalcs: true
11848  };
11849 
11850  if (typeof this.table.options.clipboardCopyHeader !== "undefined") {
11851  config.columnHeaders = this.table.options.clipboardCopyHeader;
11852  console.warn("DEPRECATION WARNING - clipboardCopyHeader option has been deprecated, please use the columnHeaders property on the clipboardCopyConfig option");
11853  }
11854 
11855  if (this.table.options.clipboardCopyConfig) {
11856  for (var key in this.table.options.clipboardCopyConfig) {
11857  config[key] = this.table.options.clipboardCopyConfig[key];
11858  }
11859  }
11860 
11861  if (config.rowGroups && this.table.options.groupBy && this.table.modExists("groupRows")) {
11862  this.config.rowGroups = true;
11863  }
11864 
11865  if (config.columnHeaders) {
11866  if ((config.columnHeaders === "groups" || config === true) && this.table.columnManager.columns.length != this.table.columnManager.columnsByIndex.length) {
11867  this.config.columnHeaders = "groups";
11868  } else {
11869  this.config.columnHeaders = "columns";
11870  }
11871  } else {
11872  this.config.columnHeaders = false;
11873  }
11874 
11875  if (config.columnCalcs && this.table.modExists("columnCalcs")) {
11876  this.config.columnCalcs = true;
11877  }
11878  };
11879 
11880  Clipboard.prototype.reset = function () {
11881  this.blocked = false;
11882  this.originalSelectionText = "";
11883  };
11884 
11885  Clipboard.prototype.setPasteAction = function (action) {
11886 
11887  switch (typeof action === 'undefined' ? 'undefined' : _typeof(action)) {
11888  case "string":
11889  this.pasteAction = this.pasteActions[action];
11890 
11891  if (!this.pasteAction) {
11892  console.warn("Clipboard Error - No such paste action found:", action);
11893  }
11894  break;
11895 
11896  case "function":
11897  this.pasteAction = action;
11898  break;
11899  }
11900  };
11901 
11902  Clipboard.prototype.setPasteParser = function (parser) {
11903  switch (typeof parser === 'undefined' ? 'undefined' : _typeof(parser)) {
11904  case "string":
11905  this.pasteParser = this.pasteParsers[parser];
11906 
11907  if (!this.pasteParser) {
11908  console.warn("Clipboard Error - No such paste parser found:", parser);
11909  }
11910  break;
11911 
11912  case "function":
11913  this.pasteParser = parser;
11914  break;
11915  }
11916  };
11917 
11918  Clipboard.prototype.paste = function (e) {
11919  var data, rowData, rows;
11920 
11921  if (this.checkPaseOrigin(e)) {
11922 
11923  data = this.getPasteData(e);
11924 
11925  rowData = this.pasteParser.call(this, data);
11926 
11927  if (rowData) {
11928  e.preventDefault();
11929 
11930  if (this.table.modExists("mutator")) {
11931  rowData = this.mutateData(rowData);
11932  }
11933 
11934  rows = this.pasteAction.call(this, rowData);
11935  this.table.options.clipboardPasted.call(this.table, data, rowData, rows);
11936  } else {
11937  this.table.options.clipboardPasteError.call(this.table, data);
11938  }
11939  }
11940  };
11941 
11942  Clipboard.prototype.mutateData = function (data) {
11943  var self = this,
11944  output = [];
11945 
11946  if (Array.isArray(data)) {
11947  data.forEach(function (row) {
11948  output.push(self.table.modules.mutator.transformRow(row, "clipboard"));
11949  });
11950  } else {
11951  output = data;
11952  }
11953 
11954  return output;
11955  };
11956 
11957  Clipboard.prototype.checkPaseOrigin = function (e) {
11958  var valid = true;
11959 
11960  if (e.target.tagName != "DIV" || this.table.modules.edit.currentCell) {
11961  valid = false;
11962  }
11963 
11964  return valid;
11965  };
11966 
11967  Clipboard.prototype.getPasteData = function (e) {
11968  var data;
11969 
11970  if (window.clipboardData && window.clipboardData.getData) {
11971  data = window.clipboardData.getData('Text');
11972  } else if (e.clipboardData && e.clipboardData.getData) {
11973  data = e.clipboardData.getData('text/plain');
11974  } else if (e.originalEvent && e.originalEvent.clipboardData.getData) {
11975  data = e.originalEvent.clipboardData.getData('text/plain');
11976  }
11977 
11978  return data;
11979  };
11980 
11981  Clipboard.prototype.copy = function (selector, selectorParams, formatter, formatterParams, internal) {
11982  var range, sel, textRange;
11983  this.blocked = false;
11984 
11985  if (this.mode === true || this.mode === "copy") {
11986 
11987  if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
11988  range = document.createRange();
11989  range.selectNodeContents(this.table.element);
11990  sel = window.getSelection();
11991 
11992  if (sel.toString() && internal) {
11993  selector = "userSelection";
11994  formatter = "raw";
11995  selectorParams = sel.toString();
11996  }
11997 
11998  sel.removeAllRanges();
11999  sel.addRange(range);
12000  } else if (typeof document.selection != "undefined" && typeof document.body.createTextRange != "undefined") {
12001  textRange = document.body.createTextRange();
12002  textRange.moveToElementText(this.table.element);
12003  textRange.select();
12004  }
12005 
12006  this.setSelector(selector);
12007  this.copySelectorParams = typeof selectorParams != "undefined" && selectorParams != null ? selectorParams : this.config.columnHeaders;
12008  this.setFormatter(formatter);
12009  this.copyFormatterParams = typeof formatterParams != "undefined" && formatterParams != null ? formatterParams : {};
12010 
12011  document.execCommand('copy');
12012 
12013  if (sel) {
12014  sel.removeAllRanges();
12015  }
12016  }
12017  };
12018 
12019  Clipboard.prototype.setSelector = function (selector) {
12020  selector = selector || this.table.options.clipboardCopySelector;
12021 
12022  switch (typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) {
12023  case "string":
12024  if (this.copySelectors[selector]) {
12025  this.copySelector = this.copySelectors[selector];
12026  } else {
12027  console.warn("Clipboard Error - No such selector found:", selector);
12028  }
12029  break;
12030 
12031  case "function":
12032  this.copySelector = selector;
12033  break;
12034  }
12035  };
12036 
12037  Clipboard.prototype.setFormatter = function (formatter) {
12038 
12039  formatter = formatter || this.table.options.clipboardCopyFormatter;
12040 
12041  switch (typeof formatter === 'undefined' ? 'undefined' : _typeof(formatter)) {
12042  case "string":
12043  if (this.copyFormatters[formatter]) {
12044  this.copyFormatter = this.copyFormatters[formatter];
12045  } else {
12046  console.warn("Clipboard Error - No such formatter found:", formatter);
12047  }
12048  break;
12049 
12050  case "function":
12051  this.copyFormatter = formatter;
12052  break;
12053  }
12054  };
12055 
12056  Clipboard.prototype.generateContent = function () {
12057  var data;
12058 
12059  this.htmlElement = false;
12060  data = this.copySelector.call(this, this.config, this.copySelectorParams);
12061 
12062  return this.copyFormatter.call(this, data, this.config, this.copyFormatterParams);
12063  };
12064 
12065  Clipboard.prototype.generateSimpleHeaders = function (columns) {
12066  var headers = [];
12067 
12068  columns.forEach(function (column) {
12069  headers.push(column.definition.title);
12070  });
12071 
12072  return headers;
12073  };
12074 
12075  Clipboard.prototype.generateColumnGroupHeaders = function (columns) {
12076  var _this33 = this;
12077 
12078  var output = [];
12079 
12080  this.table.columnManager.columns.forEach(function (column) {
12081  var colData = _this33.processColumnGroup(column);
12082 
12083  if (colData) {
12084  output.push(colData);
12085  }
12086  });
12087 
12088  return output;
12089  };
12090 
12091  Clipboard.prototype.processColumnGroup = function (column) {
12092  var _this34 = this;
12093 
12094  var subGroups = column.columns;
12095 
12096  var groupData = {
12097  type: "group",
12098  title: column.definition.title,
12099  column: column
12100  };
12101 
12102  if (subGroups.length) {
12103  groupData.subGroups = [];
12104  groupData.width = 0;
12105 
12106  subGroups.forEach(function (subGroup) {
12107  var subGroupData = _this34.processColumnGroup(subGroup);
12108 
12109  if (subGroupData) {
12110  groupData.width += subGroupData.width;
12111  groupData.subGroups.push(subGroupData);
12112  }
12113  });
12114 
12115  if (!groupData.width) {
12116  return false;
12117  }
12118  } else {
12119  if (column.field && (column.definition.clipboard || column.visible && column.definition.clipboard !== false)) {
12120  groupData.width = 1;
12121  } else {
12122  return false;
12123  }
12124  }
12125 
12126  return groupData;
12127  };
12128 
12129  Clipboard.prototype.groupHeadersToRows = function (columns) {
12130 
12131  var headers = [];
12132 
12133  function parseColumnGroup(column, level) {
12134 
12135  if (typeof headers[level] === "undefined") {
12136  headers[level] = [];
12137  }
12138 
12139  headers[level].push(column.title);
12140 
12141  if (column.subGroups) {
12142  column.subGroups.forEach(function (subGroup) {
12143  parseColumnGroup(subGroup, level + 1);
12144  });
12145  } else {
12146  padColumnheaders();
12147  }
12148  }
12149 
12150  function padColumnheaders() {
12151  var max = 0;
12152 
12153  headers.forEach(function (title) {
12154  var len = title.length;
12155  if (len > max) {
12156  max = len;
12157  }
12158  });
12159 
12160  headers.forEach(function (title) {
12161  var len = title.length;
12162  if (len < max) {
12163  for (var i = len; i < max; i++) {
12164  title.push("");
12165  }
12166  }
12167  });
12168  }
12169 
12170  columns.forEach(function (column) {
12171  parseColumnGroup(column, 0);
12172  });
12173 
12174  return headers;
12175  };
12176 
12177  Clipboard.prototype.rowsToData = function (rows, columns, config, params) {
12178  var data = [];
12179 
12180  rows.forEach(function (row) {
12181  var rowArray = [],
12182  rowData = row instanceof RowComponent ? row.getData("clipboard") : row;
12183 
12184  columns.forEach(function (column) {
12185  var value = column.getFieldValue(rowData);
12186 
12187  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
12188  case "object":
12189  value = JSON.stringify(value);
12190  break;
12191 
12192  case "undefined":
12193  case "null":
12194  value = "";
12195  break;
12196 
12197  default:
12198  value = value;
12199  }
12200 
12201  rowArray.push(value);
12202  });
12203 
12204  data.push(rowArray);
12205  });
12206 
12207  return data;
12208  };
12209 
12210  Clipboard.prototype.buildComplexRows = function (config) {
12211  var _this35 = this;
12212 
12213  var output = [],
12214  groups = this.table.modules.groupRows.getGroups();
12215 
12216  groups.forEach(function (group) {
12217  output.push(_this35.processGroupData(group));
12218  });
12219 
12220  return output;
12221  };
12222 
12223  Clipboard.prototype.processGroupData = function (group) {
12224  var _this36 = this;
12225 
12226  var subGroups = group.getSubGroups();
12227 
12228  var groupData = {
12229  type: "group",
12230  key: group.key
12231  };
12232 
12233  if (subGroups.length) {
12234  groupData.subGroups = [];
12235 
12236  subGroups.forEach(function (subGroup) {
12237  groupData.subGroups.push(_this36.processGroupData(subGroup));
12238  });
12239  } else {
12240  groupData.rows = group.getRows(true);
12241  }
12242 
12243  return groupData;
12244  };
12245 
12246  Clipboard.prototype.getCalcRow = function (calcs, columns, selector, pos) {
12247  var calcData = calcs[selector];
12248 
12249  if (calcData) {
12250  if (pos) {
12251  calcData = calcData[pos];
12252  }
12253 
12254  if (Object.keys(calcData).length) {
12255  return this.rowsToData([calcData], columns);
12256  }
12257  }
12258 
12259  return [];
12260  };
12261 
12262  Clipboard.prototype.buildOutput = function (rows, config, params) {
12263  var _this37 = this;
12264 
12265  var output = [],
12266  calcs,
12267  columns = [],
12268  columnsByIndex = [];
12269 
12270  this.table.columnManager.columnsByIndex.forEach(function (column) {
12271  if (column.definition.clipboard || column.visible && column.definition.clipboard !== false) {
12272  columnsByIndex.push(column);
12273  }
12274  });
12275 
12276  if (config.columnHeaders == "groups") {
12277  columns = this.generateColumnGroupHeaders(this.table.columnManager.columns);
12278  output = output.concat(this.groupHeadersToRows(columns));
12279  } else {
12280  columns = columnsByIndex;
12281 
12282  output.push(this.generateSimpleHeaders(columns));
12283  }
12284 
12285  if (this.config.columnCalcs) {
12286  calcs = this.table.getCalcResults();
12287  }
12288 
12289  //generate styled content
12290  if (this.table.options.clipboardCopyStyled) {
12291  this.generateHTML(rows, columns, calcs, config, params);
12292  }
12293 
12294  //generate unstyled content
12295  if (config.rowGroups) {
12296  rows.forEach(function (row) {
12297  output = output.concat(_this37.parseRowGroupData(row, columnsByIndex, config, params, calcs || {}));
12298  });
12299  } else {
12300  if (config.columnCalcs) {
12301  output = output.concat(this.getCalcRow(calcs, columnsByIndex, "top"));
12302  }
12303 
12304  output = output.concat(this.rowsToData(rows, columnsByIndex, config, params));
12305 
12306  if (config.columnCalcs) {
12307  output = output.concat(this.getCalcRow(calcs, columnsByIndex, "bottom"));
12308  }
12309  }
12310 
12311  return output;
12312  };
12313 
12314  Clipboard.prototype.parseRowGroupData = function (group, columns, config, params, calcObj) {
12315  var _this38 = this;
12316 
12317  var groupData = [];
12318 
12319  groupData.push([group.key]);
12320 
12321  if (group.subGroups) {
12322  group.subGroups.forEach(function (subGroup) {
12323  groupData = groupData.concat(_this38.parseRowGroupData(subGroup, config, params, calcObj[group.key] ? calcObj[group.key].groups || {} : {}));
12324  });
12325  } else {
12326  if (config.columnCalcs) {
12327  groupData = groupData.concat(this.getCalcRow(calcObj, columns, group.key, "top"));
12328  }
12329 
12330  groupData = groupData.concat(this.rowsToData(group.rows, columns, config, params));
12331 
12332  if (config.columnCalcs) {
12333  groupData = groupData.concat(this.getCalcRow(calcObj, columns, group.key, "bottom"));
12334  }
12335  }
12336 
12337  return groupData;
12338  };
12339 
12340  Clipboard.prototype.generateHTML = function (rows, columns, calcs, config, params) {
12341  var self = this,
12342  data = [],
12343  headers = [],
12344  body,
12345  oddRow,
12346  evenRow,
12347  calcRow,
12348  firstRow,
12349  firstCell,
12350  firstGroup,
12351  lastCell,
12352  styleCells;
12353 
12354  //create table element
12355  this.htmlElement = document.createElement("table");
12356  self.mapElementStyles(this.table.element, this.htmlElement, ["border-top", "border-left", "border-right", "border-bottom"]);
12357 
12358  function generateSimpleHeaders() {
12359  var headerEl = document.createElement("tr");
12360 
12361  columns.forEach(function (column) {
12362  var columnEl = document.createElement("th");
12363  columnEl.innerHTML = column.definition.title;
12364 
12365  self.mapElementStyles(column.getElement(), columnEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
12366 
12367  headerEl.appendChild(columnEl);
12368  });
12369 
12370  self.mapElementStyles(self.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
12371 
12372  self.htmlElement.appendChild(document.createElement("thead").appendChild(headerEl));
12373  }
12374 
12375  function generateHeaders(headers) {
12376 
12377  var headerHolderEl = document.createElement("thead");
12378 
12379  headers.forEach(function (columns) {
12380  var headerEl = document.createElement("tr");
12381 
12382  columns.forEach(function (column) {
12383  var columnEl = document.createElement("th");
12384 
12385  if (column.width > 1) {
12386  columnEl.colSpan = column.width;
12387  }
12388 
12389  if (column.height > 1) {
12390  columnEl.rowSpan = column.height;
12391  }
12392 
12393  columnEl.innerHTML = column.title;
12394 
12395  self.mapElementStyles(column.element, columnEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
12396 
12397  headerEl.appendChild(columnEl);
12398  });
12399 
12400  self.mapElementStyles(self.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
12401 
12402  headerHolderEl.appendChild(headerEl);
12403  });
12404 
12405  self.htmlElement.appendChild(headerHolderEl);
12406  }
12407 
12408  function parseColumnGroup(column, level) {
12409 
12410  var actualColumns = [];
12411 
12412  if (typeof headers[level] === "undefined") {
12413  headers[level] = [];
12414  }
12415 
12416  headers[level].push({
12417  title: column.title,
12418  width: column.width,
12419  height: 1,
12420  children: !!column.subGroups,
12421  element: column.column.getElement()
12422  });
12423 
12424  if (column.subGroups) {
12425  column.subGroups.forEach(function (subGroup) {
12426  actualColumns = actualColumns.concat(parseColumnGroup(subGroup, level + 1));
12427  });
12428 
12429  return actualColumns;
12430  } else {
12431  return [column.column];
12432  }
12433  }
12434 
12435  function padVerticalColumnheaders() {
12436  headers.forEach(function (row, index) {
12437  row.forEach(function (header) {
12438  if (!header.children) {
12439  header.height = headers.length - index;
12440  }
12441  });
12442  });
12443  }
12444 
12445  function addCalcRow(calcs, selector, pos) {
12446  var calcData = calcs[selector];
12447 
12448  if (calcData) {
12449  if (pos) {
12450  calcData = calcData[pos];
12451  }
12452 
12453  if (Object.keys(calcData).length) {
12454  // calcRowIndexs.push(body.length);
12455  processRows([calcData]);
12456  }
12457  }
12458  }
12459 
12460  //create headers if needed
12461  if (config.columnHeaders) {
12462  if (config.columnHeaders == "groups") {
12463 
12464  var actualColumns = [];
12465 
12466  columns.forEach(function (column) {
12467  actualColumns = actualColumns.concat(parseColumnGroup(column, 0));
12468  });
12469 
12470  columns = actualColumns;
12471 
12472  padVerticalColumnheaders();
12473  generateHeaders(headers);
12474  } else {
12475  generateSimpleHeaders();
12476  }
12477  }
12478 
12479  // columns = this.table.columnManager.columnsByIndex;
12480 
12481  //create table body
12482  body = document.createElement("tbody");
12483 
12484  //lookup row styles
12485  if (window.getComputedStyle) {
12486  oddRow = this.table.element.querySelector(".tabulator-row-odd:not(.tabulator-group):not(.tabulator-calcs)");
12487  evenRow = this.table.element.querySelector(".tabulator-row-even:not(.tabulator-group):not(.tabulator-calcs)");
12488  calcRow = this.table.element.querySelector(".tabulator-row.tabulator-calcs");
12489  firstRow = this.table.element.querySelector(".tabulator-row:not(.tabulator-group):not(.tabulator-calcs)");
12490  firstGroup = this.table.element.getElementsByClassName("tabulator-group")[0];
12491 
12492  if (firstRow) {
12493  styleCells = firstRow.getElementsByClassName("tabulator-cell");
12494  firstCell = styleCells[0];
12495  lastCell = styleCells[styleCells.length - 1];
12496  }
12497  }
12498 
12499  function processRows(rowArray) {
12500  //add rows to table
12501  rowArray.forEach(function (row, i) {
12502  var rowEl = document.createElement("tr"),
12503  styleRow = firstRow,
12504  isCalc = false,
12505  rowData;
12506 
12507  if (row instanceof RowComponent) {
12508  rowData = row.getData("clipboard");
12509  } else {
12510  rowData = row;
12511  isCalc = true;
12512  }
12513 
12514  columns.forEach(function (column, j) {
12515  var cellEl = document.createElement("td"),
12516  value = column.getFieldValue(rowData);
12517 
12518  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
12519  case "object":
12520  value = JSON.stringify(value);
12521  break;
12522 
12523  case "undefined":
12524  case "null":
12525  value = "";
12526  break;
12527 
12528  default:
12529  value = value;
12530  }
12531 
12532  cellEl.innerHTML = value;
12533 
12534  if (column.definition.align) {
12535  cellEl.style.textAlign = column.definition.align;
12536  }
12537 
12538  if (j < columns.length - 1) {
12539  if (firstCell) {
12540  self.mapElementStyles(firstCell, cellEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size"]);
12541  }
12542  } else {
12543  if (firstCell) {
12544  self.mapElementStyles(firstCell, cellEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size"]);
12545  }
12546  }
12547 
12548  rowEl.appendChild(cellEl);
12549  });
12550 
12551  if (isCalc) {
12552  styleRow = calcRow;
12553  } else {
12554  if (!(i % 2) && oddRow) {
12555  styleRow = oddRow;
12556  }
12557 
12558  if (i % 2 && evenRow) {
12559  styleRow = evenRow;
12560  }
12561  }
12562 
12563  if (styleRow) {
12564  self.mapElementStyles(styleRow, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
12565  }
12566 
12567  body.appendChild(rowEl);
12568  });
12569  }
12570 
12571  function processGroup(group, calcObj) {
12572  var groupEl = document.createElement("tr"),
12573  groupCellEl = document.createElement("td");
12574 
12575  groupCellEl.colSpan = columns.length;
12576 
12577  groupCellEl.innerHTML = group.key;
12578 
12579  groupEl.appendChild(groupCellEl);
12580  body.appendChild(groupEl);
12581 
12582  self.mapElementStyles(firstGroup, groupEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
12583 
12584  if (group.subGroups) {
12585  group.subGroups.forEach(function (subGroup) {
12586  processGroup(subGroup, calcObj[group.key] ? calcObj[group.key].groups || {} : {});
12587  });
12588  } else {
12589  if (config.columnCalcs) {
12590  addCalcRow(calcObj, group.key, "top");
12591  }
12592 
12593  processRows(group.rows);
12594 
12595  if (config.columnCalcs) {
12596  addCalcRow(calcObj, group.key, "bottom");
12597  }
12598  }
12599  }
12600 
12601  if (config.rowGroups) {
12602  rows.forEach(function (group) {
12603  processGroup(group, calcs || {});
12604  });
12605  } else {
12606  if (config.columnCalcs) {
12607  addCalcRow(calcs, "top");
12608  }
12609 
12610  processRows(rows);
12611 
12612  if (config.columnCalcs) {
12613  addCalcRow(calcs, "bottom");
12614  }
12615  }
12616 
12617  this.htmlElement.appendChild(body);
12618  };
12619 
12620  Clipboard.prototype.mapElementStyles = function (from, to, props) {
12621 
12622  var lookup = {
12623  "background-color": "backgroundColor",
12624  "color": "fontColor",
12625  "font-weight": "fontWeight",
12626  "font-family": "fontFamily",
12627  "font-size": "fontSize",
12628  "border-top": "borderTop",
12629  "border-left": "borderLeft",
12630  "border-right": "borderRight",
12631  "border-bottom": "borderBottom"
12632  };
12633 
12634  if (window.getComputedStyle) {
12635  var fromStyle = window.getComputedStyle(from);
12636 
12637  props.forEach(function (prop) {
12638  to.style[lookup[prop]] = fromStyle.getPropertyValue(prop);
12639  });
12640  }
12641 
12642  // return window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(property) : element.style[property.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); })];
12643  };
12644 
12645  Clipboard.prototype.copySelectors = {
12646  userSelection: function userSelection(config, params) {
12647  return params;
12648  },
12649  selected: function selected(config, params) {
12650  var rows = [];
12651 
12652  if (this.table.modExists("selectRow", true)) {
12653  rows = this.table.modules.selectRow.getSelectedRows();
12654  }
12655 
12656  if (config.rowGroups) {
12657  console.warn("Clipboard Warning - select coptSelector does not support row groups");
12658  }
12659 
12660  return this.buildOutput(rows, config, params);
12661  },
12662  table: function table(config, params) {
12663  if (config.rowGroups) {
12664  console.warn("Clipboard Warning - table coptSelector does not support row groups");
12665  }
12666 
12667  return this.buildOutput(this.table.rowManager.getComponents(), config, params);
12668  },
12669  active: function active(config, params) {
12670  var rows;
12671 
12672  if (config.rowGroups) {
12673  rows = this.buildComplexRows(config);
12674  } else {
12675  rows = this.table.rowManager.getComponents("active");
12676  }
12677 
12678  return this.buildOutput(rows, config, params);
12679  },
12680  visible: function visible(config, params) {
12681  var rows;
12682 
12683  if (config.rowGroups) {
12684  rows = this.buildComplexRows(config);
12685  } else {
12686  rows = this.table.rowManager.getComponents("visible");
12687  }
12688 
12689  return this.buildOutput(rows, config, params);
12690  }
12691  };
12692 
12693  Clipboard.prototype.copyFormatters = {
12694  raw: function raw(data, params) {
12695  return data;
12696  },
12697  table: function table(data, params) {
12698  var output = [];
12699 
12700  data.forEach(function (row) {
12701  var newRow = [];
12702  row.forEach(function (value) {
12703  if (typeof value == "undefined") {
12704  value = "";
12705  }
12706 
12707  value = typeof value == "undefined" || value === null ? "" : value.toString();
12708 
12709  if (value.match(/\r|\n/)) {
12710  value = value.split('"').join('""');
12711  value = '"' + value + '"';
12712  }
12713  newRow.push(value);
12714  });
12715 
12716  output.push(newRow.join("\t"));
12717  });
12718 
12719  return output.join("\n");
12720  }
12721  };
12722 
12723  Clipboard.prototype.pasteParsers = {
12724  table: function table(clipboard) {
12725  var data = [],
12726  success = false,
12727  headerFindSuccess = true,
12728  columns = this.table.columnManager.columns,
12729  columnMap = [],
12730  rows = [];
12731 
12732  //get data from clipboard into array of columns and rows.
12733  clipboard = clipboard.split("\n");
12734 
12735  clipboard.forEach(function (row) {
12736  data.push(row.split("\t"));
12737  });
12738 
12739  if (data.length && !(data.length === 1 && data[0].length < 2)) {
12740  success = true;
12741 
12742  //check if headers are present by title
12743  data[0].forEach(function (value) {
12744  var column = columns.find(function (column) {
12745  return value && column.definition.title && value.trim() && column.definition.title.trim() === value.trim();
12746  });
12747 
12748  if (column) {
12749  columnMap.push(column);
12750  } else {
12751  headerFindSuccess = false;
12752  }
12753  });
12754 
12755  //check if column headers are present by field
12756  if (!headerFindSuccess) {
12757  headerFindSuccess = true;
12758  columnMap = [];
12759 
12760  data[0].forEach(function (value) {
12761  var column = columns.find(function (column) {
12762  return value && column.field && value.trim() && column.field.trim() === value.trim();
12763  });
12764 
12765  if (column) {
12766  columnMap.push(column);
12767  } else {
12768  headerFindSuccess = false;
12769  }
12770  });
12771 
12772  if (!headerFindSuccess) {
12773  columnMap = this.table.columnManager.columnsByIndex;
12774  }
12775  }
12776 
12777  //remove header row if found
12778  if (headerFindSuccess) {
12779  data.shift();
12780  }
12781 
12782  data.forEach(function (item) {
12783  var row = {};
12784 
12785  item.forEach(function (value, i) {
12786  if (columnMap[i]) {
12787  row[columnMap[i].field] = value;
12788  }
12789  });
12790 
12791  rows.push(row);
12792  });
12793 
12794  return rows;
12795  } else {
12796  return false;
12797  }
12798  }
12799  };
12800 
12801  Clipboard.prototype.pasteActions = {
12802  replace: function replace(rows) {
12803  return this.table.setData(rows);
12804  },
12805  update: function update(rows) {
12806  return this.table.updateOrAddData(rows);
12807  },
12808  insert: function insert(rows) {
12809  return this.table.addData(rows);
12810  }
12811  };
12812 
12813  Tabulator.prototype.registerModule("clipboard", Clipboard);
12814 
12815  var DataTree = function DataTree(table) {
12816  this.table = table;
12817  this.indent = 10;
12818  this.field = "";
12819  this.collapseEl = null;
12820  this.expandEl = null;
12821  this.branchEl = null;
12822  this.elementField = false;
12823 
12824  this.startOpen = function () {};
12825 
12826  this.displayIndex = 0;
12827  };
12828 
12829  DataTree.prototype.initialize = function () {
12830  var dummyEl = null,
12831  firstCol = this.table.columnManager.getFirstVisibileColumn(),
12832  options = this.table.options;
12833 
12834  this.field = options.dataTreeChildField;
12835  this.indent = options.dataTreeChildIndent;
12836  this.elementField = options.dataTreeElementColumn || (firstCol ? firstCol.field : false);
12837 
12838  if (options.dataTreeBranchElement) {
12839 
12840  if (options.dataTreeBranchElement === true) {
12841  this.branchEl = document.createElement("div");
12842  this.branchEl.classList.add("tabulator-data-tree-branch");
12843  } else {
12844  if (typeof options.dataTreeBranchElement === "string") {
12845  dummyEl = document.createElement("div");
12846  dummyEl.innerHTML = options.dataTreeBranchElement;
12847  this.branchEl = dummyEl.firstChild;
12848  } else {
12849  this.branchEl = options.dataTreeBranchElement;
12850  }
12851  }
12852  }
12853 
12854  if (options.dataTreeCollapseElement) {
12855  if (typeof options.dataTreeCollapseElement === "string") {
12856  dummyEl = document.createElement("div");
12857  dummyEl.innerHTML = options.dataTreeCollapseElement;
12858  this.collapseEl = dummyEl.firstChild;
12859  } else {
12860  this.collapseEl = options.dataTreeCollapseElement;
12861  }
12862  } else {
12863  this.collapseEl = document.createElement("div");
12864  this.collapseEl.classList.add("tabulator-data-tree-control");
12865  this.collapseEl.tabIndex = 0;
12866  this.collapseEl.innerHTML = "<div class='tabulator-data-tree-control-collapse'></div>";
12867  }
12868 
12869  if (options.dataTreeExpandElement) {
12870  if (typeof options.dataTreeExpandElement === "string") {
12871  dummyEl = document.createElement("div");
12872  dummyEl.innerHTML = options.dataTreeExpandElement;
12873  this.expandEl = dummyEl.firstChild;
12874  } else {
12875  this.expandEl = options.dataTreeExpandElement;
12876  }
12877  } else {
12878  this.expandEl = document.createElement("div");
12879  this.expandEl.classList.add("tabulator-data-tree-control");
12880  this.expandEl.tabIndex = 0;
12881  this.expandEl.innerHTML = "<div class='tabulator-data-tree-control-expand'></div>";
12882  }
12883 
12884  switch (_typeof(options.dataTreeStartExpanded)) {
12885  case "boolean":
12886  this.startOpen = function (row, index) {
12887  return options.dataTreeStartExpanded;
12888  };
12889  break;
12890 
12891  case "function":
12892  this.startOpen = options.dataTreeStartExpanded;
12893  break;
12894 
12895  default:
12896  this.startOpen = function (row, index) {
12897  return options.dataTreeStartExpanded[index];
12898  };
12899  break;
12900  }
12901  };
12902 
12903  DataTree.prototype.initializeRow = function (row) {
12904  var childArray = row.getData()[this.field];
12905  var isArray = Array.isArray(childArray);
12906 
12907  var children = isArray || !isArray && (typeof childArray === 'undefined' ? 'undefined' : _typeof(childArray)) === "object" && childArray !== null;
12908 
12909  row.modules.dataTree = {
12910  index: 0,
12911  open: children ? this.startOpen(row.getComponent(), 0) : false,
12912  controlEl: false,
12913  branchEl: false,
12914  parent: false,
12915  children: children
12916  };
12917  };
12918 
12919  DataTree.prototype.layoutRow = function (row) {
12920  var cell = this.elementField ? row.getCell(this.elementField) : row.getCells()[0],
12921  el = cell.getElement(),
12922  config = row.modules.dataTree;
12923 
12924  if (config.branchEl) {
12925  config.branchEl.parentNode.removeChild(config.branchEl);
12926  }
12927 
12928  this.generateControlElement(row, el);
12929 
12930  if (config.index) {
12931  if (this.branchEl) {
12932  config.branchEl = this.branchEl.cloneNode(true);
12933  el.insertBefore(config.branchEl, el.firstChild);
12934  config.branchEl.style.marginLeft = (config.branchEl.offsetWidth + config.branchEl.style.marginRight) * (config.index - 1) + config.index * this.indent + "px";
12935  } else {
12936  el.style.paddingLeft = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + config.index * this.indent + "px";
12937  }
12938  }
12939  };
12940 
12941  DataTree.prototype.generateControlElement = function (row, el) {
12942  var _this39 = this;
12943 
12944  var config = row.modules.dataTree,
12945  el = el || row.getCells()[0].getElement(),
12946  oldControl = config.controlEl;
12947 
12948  if (config.children !== false) {
12949 
12950  if (config.open) {
12951  config.controlEl = this.collapseEl.cloneNode(true);
12952  config.controlEl.addEventListener("click", function (e) {
12953  e.stopPropagation();
12954  _this39.collapseRow(row);
12955  });
12956  } else {
12957  config.controlEl = this.expandEl.cloneNode(true);
12958  config.controlEl.addEventListener("click", function (e) {
12959  e.stopPropagation();
12960  _this39.expandRow(row);
12961  });
12962  }
12963 
12964  config.controlEl.addEventListener("mousedown", function (e) {
12965  e.stopPropagation();
12966  });
12967 
12968  if (oldControl && oldControl.parentNode === el) {
12969  oldControl.parentNode.replaceChild(config.controlEl, oldControl);
12970  } else {
12971  el.insertBefore(config.controlEl, el.firstChild);
12972  }
12973  }
12974  };
12975 
12976  DataTree.prototype.setDisplayIndex = function (index) {
12977  this.displayIndex = index;
12978  };
12979 
12980  DataTree.prototype.getDisplayIndex = function () {
12981  return this.displayIndex;
12982  };
12983 
12984  DataTree.prototype.getRows = function (rows) {
12985  var _this40 = this;
12986 
12987  var output = [];
12988 
12989  rows.forEach(function (row, i) {
12990  var config, children;
12991 
12992  output.push(row);
12993 
12994  if (row instanceof Row) {
12995 
12996  config = row.modules.dataTree.children;
12997 
12998  if (!config.index && config.children !== false) {
12999  children = _this40.getChildren(row);
13000 
13001  children.forEach(function (child) {
13002  output.push(child);
13003  });
13004  }
13005  }
13006  });
13007 
13008  return output;
13009  };
13010 
13011  DataTree.prototype.getChildren = function (row) {
13012  var _this41 = this;
13013 
13014  var config = row.modules.dataTree,
13015  children = [],
13016  output = [];
13017 
13018  if (config.children !== false && config.open) {
13019  if (!Array.isArray(config.children)) {
13020  config.children = this.generateChildren(row);
13021  }
13022 
13023  if (this.table.modExists("filter")) {
13024  children = this.table.modules.filter.filter(config.children);
13025  } else {
13026  children = config.children;
13027  }
13028 
13029  if (this.table.modExists("sort")) {
13030  this.table.modules.sort.sort(children);
13031  }
13032 
13033  children.forEach(function (child) {
13034  output.push(child);
13035 
13036  var subChildren = _this41.getChildren(child);
13037 
13038  subChildren.forEach(function (sub) {
13039  output.push(sub);
13040  });
13041  });
13042  }
13043 
13044  return output;
13045  };
13046 
13047  DataTree.prototype.generateChildren = function (row) {
13048  var _this42 = this;
13049 
13050  var children = [];
13051 
13052  var childArray = row.getData()[this.field];
13053 
13054  if (!Array.isArray(childArray)) {
13055  childArray = [childArray];
13056  }
13057 
13058  childArray.forEach(function (childData) {
13059  var childRow = new Row(childData || {}, _this42.table.rowManager);
13060  childRow.modules.dataTree.index = row.modules.dataTree.index + 1;
13061  childRow.modules.dataTree.parent = row;
13062  if (childRow.modules.dataTree.children) {
13063  childRow.modules.dataTree.open = _this42.startOpen(childRow.getComponent(), childRow.modules.dataTree.index);
13064  }
13065  children.push(childRow);
13066  });
13067 
13068  return children;
13069  };
13070 
13071  DataTree.prototype.expandRow = function (row, silent) {
13072  var config = row.modules.dataTree;
13073 
13074  if (config.children !== false) {
13075  config.open = true;
13076 
13077  row.reinitialize();
13078 
13079  this.table.rowManager.refreshActiveData("tree", false, true);
13080 
13081  this.table.options.dataTreeRowExpanded(row.getComponent(), row.modules.dataTree.index);
13082  }
13083  };
13084 
13085  DataTree.prototype.collapseRow = function (row) {
13086  var config = row.modules.dataTree;
13087 
13088  if (config.children !== false) {
13089  config.open = false;
13090 
13091  row.reinitialize();
13092 
13093  this.table.rowManager.refreshActiveData("tree", false, true);
13094 
13095  this.table.options.dataTreeRowCollapsed(row.getComponent(), row.modules.dataTree.index);
13096  }
13097  };
13098 
13099  DataTree.prototype.toggleRow = function (row) {
13100  var config = row.modules.dataTree;
13101 
13102  if (config.children !== false) {
13103  if (config.open) {
13104  this.collapseRow(row);
13105  } else {
13106  this.expandRow(row);
13107  }
13108  }
13109  };
13110 
13111  DataTree.prototype.getTreeParent = function (row) {
13112  return row.modules.dataTree.parent ? row.modules.dataTree.parent.getComponent() : false;
13113  };
13114 
13115  DataTree.prototype.getTreeChildren = function (row) {
13116  var config = row.modules.dataTree,
13117  output = [];
13118 
13119  if (config.children) {
13120 
13121  if (!Array.isArray(config.children)) {
13122  config.children = this.generateChildren(row);
13123  }
13124 
13125  config.children.forEach(function (childRow) {
13126  if (childRow instanceof Row) {
13127  output.push(childRow.getComponent());
13128  }
13129  });
13130  }
13131 
13132  return output;
13133  };
13134 
13135  DataTree.prototype.checkForRestyle = function (cell) {
13136  if (!cell.row.cells.indexOf(cell)) {
13137  if (cell.row.modules.dataTree.children !== false) {
13138  cell.row.reinitialize();
13139  }
13140  }
13141  };
13142 
13143  DataTree.prototype.getChildField = function () {
13144  return this.field;
13145  };
13146 
13147  DataTree.prototype.redrawNeeded = function (data) {
13148  return (this.field ? typeof data[this.field] !== "undefined" : false) || (this.elementField ? typeof data[this.elementField] !== "undefined" : false);
13149  };
13150 
13151  Tabulator.prototype.registerModule("dataTree", DataTree);
13152  var Download = function Download(table) {
13153  this.table = table; //hold Tabulator object
13154  this.fields = {}; //hold filed multi dimension arrays
13155  this.columnsByIndex = []; //hold columns in their order in the table
13156  this.columnsByField = {}; //hold columns with lookup by field name
13157  this.config = {};
13158  this.active = false;
13159  };
13160 
13161  //trigger file download
13162  Download.prototype.download = function (type, filename, options, active, interceptCallback) {
13163  var self = this,
13164  downloadFunc = false;
13165  this.processConfig();
13166  this.active = active;
13167 
13168  function buildLink(data, mime) {
13169  if (interceptCallback) {
13170  if (interceptCallback === true) {
13171  self.triggerDownload(data, mime, type, filename, true);
13172  } else {
13173  interceptCallback(data);
13174  }
13175  } else {
13176  self.triggerDownload(data, mime, type, filename);
13177  }
13178  }
13179 
13180  if (typeof type == "function") {
13181  downloadFunc = type;
13182  } else {
13183  if (self.downloaders[type]) {
13184  downloadFunc = self.downloaders[type];
13185  } else {
13186  console.warn("Download Error - No such download type found: ", type);
13187  }
13188  }
13189 
13190  this.processColumns();
13191 
13192  if (downloadFunc) {
13193  downloadFunc.call(this, self.processDefinitions(), self.processData(active || "active"), options || {}, buildLink, this.config);
13194  }
13195  };
13196 
13197  Download.prototype.processConfig = function () {
13198  var config = { //download config
13199  columnGroups: true,
13200  rowGroups: true,
13201  columnCalcs: true
13202  };
13203 
13204  if (this.table.options.downloadConfig) {
13205  for (var key in this.table.options.downloadConfig) {
13206  config[key] = this.table.options.downloadConfig[key];
13207  }
13208  }
13209 
13210  if (config.rowGroups && this.table.options.groupBy && this.table.modExists("groupRows")) {
13211  this.config.rowGroups = true;
13212  }
13213 
13214  if (config.columnGroups && this.table.columnManager.columns.length != this.table.columnManager.columnsByIndex.length) {
13215  this.config.columnGroups = true;
13216  }
13217 
13218  if (config.columnCalcs && this.table.modExists("columnCalcs")) {
13219  this.config.columnCalcs = true;
13220  }
13221  };
13222 
13223  Download.prototype.processColumns = function () {
13224  var self = this;
13225 
13226  self.columnsByIndex = [];
13227  self.columnsByField = {};
13228 
13229  self.table.columnManager.columnsByIndex.forEach(function (column) {
13230 
13231  if (column.field && column.definition.download !== false && (column.visible || !column.visible && column.definition.download)) {
13232  self.columnsByIndex.push(column);
13233  self.columnsByField[column.field] = column;
13234  }
13235  });
13236  };
13237 
13238  Download.prototype.processDefinitions = function () {
13239  var self = this,
13240  processedDefinitions = [];
13241 
13242  if (this.config.columnGroups) {
13243  self.table.columnManager.columns.forEach(function (column) {
13244  var colData = self.processColumnGroup(column);
13245 
13246  if (colData) {
13247  processedDefinitions.push(colData);
13248  }
13249  });
13250  } else {
13251  self.columnsByIndex.forEach(function (column) {
13252  if (column.download !== false) {
13253  //isolate definiton from defintion object
13254  processedDefinitions.push(self.processDefinition(column));
13255  }
13256  });
13257  }
13258 
13259  return processedDefinitions;
13260  };
13261 
13262  Download.prototype.processColumnGroup = function (column) {
13263  var _this43 = this;
13264 
13265  var subGroups = column.columns,
13266  maxDepth = 0;
13267  var processedColumn = this.processDefinition(column);
13268  var groupData = {
13269  type: "group",
13270  title: processedColumn.title,
13271  depth: 1
13272  };
13273 
13274  if (subGroups.length) {
13275  groupData.subGroups = [];
13276  groupData.width = 0;
13277 
13278  subGroups.forEach(function (subGroup) {
13279  var subGroupData = _this43.processColumnGroup(subGroup);
13280 
13281  if (subGroupData.depth > maxDepth) {
13282  maxDepth = subGroupData.depth;
13283  }
13284 
13285  if (subGroupData) {
13286  groupData.width += subGroupData.width;
13287  groupData.subGroups.push(subGroupData);
13288  }
13289  });
13290 
13291  groupData.depth += maxDepth;
13292 
13293  if (!groupData.width) {
13294  return false;
13295  }
13296  } else {
13297  if (column.field && column.definition.download !== false && (column.visible || !column.visible && column.definition.download)) {
13298  groupData.width = 1;
13299  groupData.definition = processedColumn;
13300  } else {
13301  return false;
13302  }
13303  }
13304 
13305  return groupData;
13306  };
13307 
13308  Download.prototype.processDefinition = function (column) {
13309  var def = {};
13310 
13311  for (var key in column.definition) {
13312  def[key] = column.definition[key];
13313  }
13314 
13315  if (typeof column.definition.downloadTitle != "undefined") {
13316  def.title = column.definition.downloadTitle;
13317  }
13318 
13319  return def;
13320  };
13321 
13322  Download.prototype.processData = function (active) {
13323  var _this44 = this;
13324 
13325  var self = this,
13326  data = [],
13327  groups = [],
13328  rows = false,
13329  calcs = {};
13330 
13331  if (this.config.rowGroups) {
13332 
13333  if (active == "visible") {
13334 
13335  rows = self.table.rowManager.getRows(active);
13336 
13337  rows.forEach(function (row) {
13338  if (row.type == "row") {
13339  var group = row.getGroup();
13340 
13341  if (groups.indexOf(group) === -1) {
13342  groups.push(group);
13343  }
13344  }
13345  });
13346  } else {
13347  groups = this.table.modules.groupRows.getGroups();
13348  }
13349 
13350  groups.forEach(function (group) {
13351  data.push(_this44.processGroupData(group, rows));
13352  });
13353  } else {
13354  data = self.table.rowManager.getData(active, "download");
13355  }
13356 
13357  if (this.config.columnCalcs) {
13358  calcs = this.table.getCalcResults();
13359 
13360  data = {
13361  calcs: calcs,
13362  data: data
13363  };
13364  }
13365 
13366  //bulk data processing
13367  if (typeof self.table.options.downloadDataFormatter == "function") {
13368  data = self.table.options.downloadDataFormatter(data);
13369  }
13370 
13371  return data;
13372  };
13373 
13374  Download.prototype.processGroupData = function (group, visRows) {
13375  var _this45 = this;
13376 
13377  var subGroups = group.getSubGroups();
13378 
13379  var groupData = {
13380  type: "group",
13381  key: group.key
13382  };
13383 
13384  if (subGroups.length) {
13385  groupData.subGroups = [];
13386 
13387  subGroups.forEach(function (subGroup) {
13388  groupData.subGroups.push(_this45.processGroupData(subGroup, visRows));
13389  });
13390  } else {
13391  if (visRows) {
13392  groupData.rows = [];
13393 
13394  group.rows.forEach(function (row) {
13395  if (visRows.indexOf(row) > -1) {
13396  groupData.rows.push(row.getData("download"));
13397  }
13398  });
13399  } else {
13400  groupData.rows = group.getData(true, "download");
13401  }
13402  }
13403 
13404  return groupData;
13405  };
13406 
13407  Download.prototype.triggerDownload = function (data, mime, type, filename, newTab) {
13408  var element = document.createElement('a'),
13409  blob = new Blob([data], { type: mime }),
13410  filename = filename || "Tabulator." + (typeof type === "function" ? "txt" : type);
13411 
13412  blob = this.table.options.downloadReady.call(this.table, data, blob);
13413 
13414  if (blob) {
13415 
13416  if (newTab) {
13417  window.open(window.URL.createObjectURL(blob));
13418  } else {
13419  if (navigator.msSaveOrOpenBlob) {
13420  navigator.msSaveOrOpenBlob(blob, filename);
13421  } else {
13422  element.setAttribute('href', window.URL.createObjectURL(blob));
13423 
13424  //set file title
13425  element.setAttribute('download', filename);
13426 
13427  //trigger download
13428  element.style.display = 'none';
13429  document.body.appendChild(element);
13430  element.click();
13431 
13432  //remove temporary link element
13433  document.body.removeChild(element);
13434  }
13435  }
13436 
13437  if (this.table.options.downloadComplete) {
13438  this.table.options.downloadComplete();
13439  }
13440  }
13441  };
13442 
13443  //nested field lookup
13444  Download.prototype.getFieldValue = function (field, data) {
13445  var column = this.columnsByField[field];
13446 
13447  if (column) {
13448  return column.getFieldValue(data);
13449  }
13450 
13451  return false;
13452  };
13453 
13454  Download.prototype.commsReceived = function (table, action, data) {
13455  switch (action) {
13456  case "intercept":
13457  this.download(data.type, "", data.options, data.active, data.intercept);
13458  break;
13459  }
13460  };
13461 
13462  //downloaders
13463  Download.prototype.downloaders = {
13464  csv: function csv(columns, data, options, setFileContents, config) {
13465  var self = this,
13466  titles = [],
13467  fields = [],
13468  delimiter = options && options.delimiter ? options.delimiter : ",",
13469  fileContents,
13470  output;
13471 
13472  //build column headers
13473  function parseSimpleTitles() {
13474  columns.forEach(function (column) {
13475  titles.push('"' + String(column.title).split('"').join('""') + '"');
13476  fields.push(column.field);
13477  });
13478  }
13479 
13480  function parseColumnGroup(column, level) {
13481  if (column.subGroups) {
13482  column.subGroups.forEach(function (subGroup) {
13483  parseColumnGroup(subGroup, level + 1);
13484  });
13485  } else {
13486  titles.push('"' + String(column.title).split('"').join('""') + '"');
13487  fields.push(column.definition.field);
13488  }
13489  }
13490 
13491  if (config.columnGroups) {
13492  console.warn("Download Warning - CSV downloader cannot process column groups");
13493 
13494  columns.forEach(function (column) {
13495  parseColumnGroup(column, 0);
13496  });
13497  } else {
13498  parseSimpleTitles();
13499  }
13500 
13501  //generate header row
13502  fileContents = [titles.join(delimiter)];
13503 
13504  function parseRows(data) {
13505  //generate each row of the table
13506  data.forEach(function (row) {
13507  var rowData = [];
13508 
13509  fields.forEach(function (field) {
13510  var value = self.getFieldValue(field, row);
13511 
13512  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
13513  case "object":
13514  value = JSON.stringify(value);
13515  break;
13516 
13517  case "undefined":
13518  case "null":
13519  value = "";
13520  break;
13521 
13522  default:
13523  value = value;
13524  }
13525 
13526  //escape quotation marks
13527  rowData.push('"' + String(value).split('"').join('""') + '"');
13528  });
13529 
13530  fileContents.push(rowData.join(delimiter));
13531  });
13532  }
13533 
13534  function parseGroup(group) {
13535  if (group.subGroups) {
13536  group.subGroups.forEach(function (subGroup) {
13537  parseGroup(subGroup);
13538  });
13539  } else {
13540  parseRows(group.rows);
13541  }
13542  }
13543 
13544  if (config.columnCalcs) {
13545  console.warn("Download Warning - CSV downloader cannot process column calculations");
13546  data = data.data;
13547  }
13548 
13549  if (config.rowGroups) {
13550  console.warn("Download Warning - CSV downloader cannot process row groups");
13551 
13552  data.forEach(function (group) {
13553  parseGroup(group);
13554  });
13555  } else {
13556  parseRows(data);
13557  }
13558 
13559  output = fileContents.join("\n");
13560 
13561  if (options.bom) {
13562  output = '\uFEFF' + output;
13563  }
13564 
13565  setFileContents(output, "text/csv");
13566  },
13567 
13568  json: function json(columns, data, options, setFileContents, config) {
13569  var fileContents;
13570 
13571  if (config.columnCalcs) {
13572  console.warn("Download Warning - CSV downloader cannot process column calculations");
13573  data = data.data;
13574  }
13575 
13576  fileContents = JSON.stringify(data, null, '\t');
13577 
13578  setFileContents(fileContents, "application/json");
13579  },
13580 
13581  pdf: function pdf(columns, data, options, setFileContents, config) {
13582  var self = this,
13583  fields = [],
13584  header = [],
13585  body = [],
13586  calcs = {},
13587  headerDepth = 1,
13588  table = "",
13589  autoTableParams = {},
13590  rowGroupStyles = options.rowGroupStyles || {
13591  fontStyle: "bold",
13592  fontSize: 12,
13593  cellPadding: 6,
13594  fillColor: 220
13595  },
13596  rowCalcStyles = options.rowCalcStyles || {
13597  fontStyle: "bold",
13598  fontSize: 10,
13599  cellPadding: 4,
13600  fillColor: 232
13601  },
13602  jsPDFParams = options.jsPDF || {},
13603  title = options && options.title ? options.title : "";
13604 
13605  if (config.columnCalcs) {
13606  calcs = data.calcs;
13607  data = data.data;
13608  }
13609 
13610  if (!jsPDFParams.orientation) {
13611  jsPDFParams.orientation = options.orientation || "landscape";
13612  }
13613 
13614  if (!jsPDFParams.unit) {
13615  jsPDFParams.unit = "pt";
13616  }
13617 
13618  //build column headers
13619  function parseSimpleTitles() {
13620  columns.forEach(function (column) {
13621  if (column.field) {
13622  header.push(column.title || "");
13623  fields.push(column.field);
13624  }
13625  });
13626 
13627  header = [header];
13628  }
13629 
13630  function parseColumnGroup(column, level) {
13631  var colSpan = column.width,
13632  rowSpan = 1,
13633  col = {
13634  content: column.title || ""
13635  };
13636 
13637  if (column.subGroups) {
13638  column.subGroups.forEach(function (subGroup) {
13639  parseColumnGroup(subGroup, level + 1);
13640  });
13641  rowSpan = 1;
13642  } else {
13643  fields.push(column.definition.field);
13644  rowSpan = headerDepth - level;
13645  }
13646 
13647  col.rowSpan = rowSpan;
13648  // col.colSpan = colSpan;
13649 
13650  header[level].push(col);
13651 
13652  colSpan--;
13653 
13654  if (rowSpan > 1) {
13655  for (var i = level + 1; i < headerDepth; i++) {
13656  header[i].push("");
13657  }
13658  }
13659 
13660  for (var i = 0; i < colSpan; i++) {
13661  header[level].push("");
13662  }
13663  }
13664 
13665  if (config.columnGroups) {
13666  columns.forEach(function (column) {
13667  if (column.depth > headerDepth) {
13668  headerDepth = column.depth;
13669  }
13670  });
13671 
13672  for (var i = 0; i < headerDepth; i++) {
13673  header.push([]);
13674  }
13675 
13676  columns.forEach(function (column) {
13677  parseColumnGroup(column, 0);
13678  });
13679  } else {
13680  parseSimpleTitles();
13681  }
13682 
13683  function parseValue(value) {
13684  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
13685  case "object":
13686  value = JSON.stringify(value);
13687  break;
13688 
13689  case "undefined":
13690  case "null":
13691  value = "";
13692  break;
13693 
13694  default:
13695  value = value;
13696  }
13697 
13698  return value;
13699  }
13700 
13701  function parseRows(data) {
13702  //build table rows
13703  data.forEach(function (row) {
13704  body.push(parseRow(row));
13705  });
13706  }
13707 
13708  function parseRow(row, styles) {
13709  var rowData = [];
13710 
13711  fields.forEach(function (field) {
13712  var value = self.getFieldValue(field, row);
13713  value = parseValue(value);
13714 
13715  if (styles) {
13716  rowData.push({
13717  content: value,
13718  styles: styles
13719  });
13720  } else {
13721  rowData.push(value);
13722  }
13723  });
13724 
13725  return rowData;
13726  }
13727 
13728  function parseGroup(group, calcObj) {
13729  var groupData = [];
13730 
13731  groupData.push({ content: parseValue(group.key), colSpan: fields.length, styles: rowGroupStyles });
13732 
13733  body.push(groupData);
13734 
13735  if (group.subGroups) {
13736  group.subGroups.forEach(function (subGroup) {
13737  parseGroup(subGroup, calcObj[group.key] ? calcObj[group.key].groups || {} : {});
13738  });
13739  } else {
13740 
13741  if (config.columnCalcs) {
13742  addCalcRow(calcObj, group.key, "top");
13743  }
13744 
13745  parseRows(group.rows);
13746 
13747  if (config.columnCalcs) {
13748  addCalcRow(calcObj, group.key, "bottom");
13749  }
13750  }
13751  }
13752 
13753  function addCalcRow(calcs, selector, pos) {
13754  var calcData = calcs[selector];
13755 
13756  if (calcData) {
13757  if (pos) {
13758  calcData = calcData[pos];
13759  }
13760 
13761  if (Object.keys(calcData).length) {
13762  body.push(parseRow(calcData, rowCalcStyles));
13763  }
13764  }
13765  }
13766 
13767  if (config.rowGroups) {
13768  data.forEach(function (group) {
13769  parseGroup(group, calcs);
13770  });
13771  } else {
13772  if (config.columnCalcs) {
13773  addCalcRow(calcs, "top");
13774  }
13775 
13776  parseRows(data);
13777 
13778  if (config.columnCalcs) {
13779  addCalcRow(calcs, "bottom");
13780  }
13781  }
13782 
13783  var doc = new jsPDF(jsPDFParams); //set document to landscape, better for most tables
13784 
13785  if (options && options.autoTable) {
13786  if (typeof options.autoTable === "function") {
13787  autoTableParams = options.autoTable(doc) || {};
13788  } else {
13789  autoTableParams = options.autoTable;
13790  }
13791  }
13792 
13793  if (title) {
13794  autoTableParams.addPageContent = function (data) {
13795  doc.text(title, 40, 30);
13796  };
13797  }
13798 
13799  autoTableParams.head = header;
13800  autoTableParams.body = body;
13801 
13802  doc.autoTable(autoTableParams);
13803 
13804  if (options && options.documentProcessing) {
13805  options.documentProcessing(doc);
13806  }
13807 
13808  setFileContents(doc.output("arraybuffer"), "application/pdf");
13809  },
13810 
13811  xlsx: function xlsx(columns, data, options, setFileContents, config) {
13812  var self = this,
13813  sheetName = options.sheetName || "Sheet1",
13814  workbook = XLSX.utils.book_new(),
13815  calcs = {},
13816  groupRowIndexs = [],
13817  groupColumnIndexs = [],
13818  calcRowIndexs = [],
13819  output;
13820 
13821  workbook.SheetNames = [];
13822  workbook.Sheets = {};
13823 
13824  if (config.columnCalcs) {
13825  calcs = data.calcs;
13826  data = data.data;
13827  }
13828 
13829  function generateSheet() {
13830  var titles = [],
13831  fields = [],
13832  rows = [],
13833  worksheet;
13834 
13835  //convert rows to worksheet
13836  function rowsToSheet() {
13837  var sheet = {};
13838  var range = { s: { c: 0, r: 0 }, e: { c: fields.length, r: rows.length } };
13839 
13840  XLSX.utils.sheet_add_aoa(sheet, rows);
13841 
13842  sheet['!ref'] = XLSX.utils.encode_range(range);
13843 
13844  var merges = generateMerges();
13845 
13846  if (merges.length) {
13847  sheet["!merges"] = merges;
13848  }
13849 
13850  return sheet;
13851  }
13852 
13853  function parseSimpleTitles() {
13854  //get field lists
13855  columns.forEach(function (column) {
13856  titles.push(column.title);
13857  fields.push(column.field);
13858  });
13859 
13860  rows.push(titles);
13861  }
13862 
13863  function parseColumnGroup(column, level) {
13864 
13865  if (typeof titles[level] === "undefined") {
13866  titles[level] = [];
13867  }
13868 
13869  if (typeof groupColumnIndexs[level] === "undefined") {
13870  groupColumnIndexs[level] = [];
13871  }
13872 
13873  if (column.width > 1) {
13874 
13875  groupColumnIndexs[level].push({
13876  type: "hoz",
13877  start: titles[level].length,
13878  end: titles[level].length + column.width - 1
13879  });
13880  }
13881 
13882  titles[level].push(column.title);
13883 
13884  if (column.subGroups) {
13885  column.subGroups.forEach(function (subGroup) {
13886  parseColumnGroup(subGroup, level + 1);
13887  });
13888  } else {
13889  fields.push(column.definition.field);
13890  padColumnTitles(fields.length - 1, level);
13891 
13892  groupColumnIndexs[level].push({
13893  type: "vert",
13894  start: fields.length - 1
13895  });
13896  }
13897  }
13898 
13899  function padColumnTitles() {
13900  var max = 0;
13901 
13902  titles.forEach(function (title) {
13903  var len = title.length;
13904  if (len > max) {
13905  max = len;
13906  }
13907  });
13908 
13909  titles.forEach(function (title) {
13910  var len = title.length;
13911  if (len < max) {
13912  for (var i = len; i < max; i++) {
13913  title.push("");
13914  }
13915  }
13916  });
13917  }
13918 
13919  if (config.columnGroups) {
13920  columns.forEach(function (column) {
13921  parseColumnGroup(column, 0);
13922  });
13923 
13924  titles.forEach(function (title) {
13925  rows.push(title);
13926  });
13927  } else {
13928  parseSimpleTitles();
13929  }
13930 
13931  function generateMerges() {
13932  var output = [];
13933 
13934  groupRowIndexs.forEach(function (index) {
13935  output.push({ s: { r: index, c: 0 }, e: { r: index, c: fields.length - 1 } });
13936  });
13937 
13938  groupColumnIndexs.forEach(function (merges, level) {
13939  merges.forEach(function (merge) {
13940  if (merge.type === "hoz") {
13941  output.push({ s: { r: level, c: merge.start }, e: { r: level, c: merge.end } });
13942  } else {
13943  if (level != titles.length - 1) {
13944  output.push({ s: { r: level, c: merge.start }, e: { r: titles.length - 1, c: merge.start } });
13945  }
13946  }
13947  });
13948  });
13949 
13950  return output;
13951  }
13952 
13953  //generate each row of the table
13954  function parseRows(data) {
13955  data.forEach(function (row) {
13956  rows.push(parseRow(row));
13957  });
13958  }
13959 
13960  function parseRow(row) {
13961  var rowData = [];
13962 
13963  fields.forEach(function (field) {
13964  var value = self.getFieldValue(field, row);
13965  rowData.push(!(value instanceof Date) && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === "object" ? JSON.stringify(value) : value);
13966  });
13967 
13968  return rowData;
13969  }
13970 
13971  function addCalcRow(calcs, selector, pos) {
13972  var calcData = calcs[selector];
13973 
13974  if (calcData) {
13975  if (pos) {
13976  calcData = calcData[pos];
13977  }
13978 
13979  if (Object.keys(calcData).length) {
13980  calcRowIndexs.push(rows.length);
13981  rows.push(parseRow(calcData));
13982  }
13983  }
13984  }
13985 
13986  function parseGroup(group, calcObj) {
13987  var groupData = [];
13988 
13989  groupData.push(group.key);
13990 
13991  groupRowIndexs.push(rows.length);
13992 
13993  rows.push(groupData);
13994 
13995  if (group.subGroups) {
13996  group.subGroups.forEach(function (subGroup) {
13997  parseGroup(subGroup, calcObj[group.key] ? calcObj[group.key].groups || {} : {});
13998  });
13999  } else {
14000 
14001  if (config.columnCalcs) {
14002  addCalcRow(calcObj, group.key, "top");
14003  }
14004 
14005  parseRows(group.rows);
14006 
14007  if (config.columnCalcs) {
14008  addCalcRow(calcObj, group.key, "bottom");
14009  }
14010  }
14011  }
14012 
14013  if (config.rowGroups) {
14014  data.forEach(function (group) {
14015  parseGroup(group, calcs);
14016  });
14017  } else {
14018  if (config.columnCalcs) {
14019  addCalcRow(calcs, "top");
14020  }
14021 
14022  parseRows(data);
14023 
14024  if (config.columnCalcs) {
14025  addCalcRow(calcs, "bottom");
14026  }
14027  }
14028 
14029  worksheet = rowsToSheet();
14030 
14031  return worksheet;
14032  }
14033 
14034  if (options.sheetOnly) {
14035  setFileContents(generateSheet());
14036  return;
14037  }
14038 
14039  if (options.sheets) {
14040  for (var sheet in options.sheets) {
14041 
14042  if (options.sheets[sheet] === true) {
14043  workbook.SheetNames.push(sheet);
14044  workbook.Sheets[sheet] = generateSheet();
14045  } else {
14046 
14047  workbook.SheetNames.push(sheet);
14048 
14049  this.table.modules.comms.send(options.sheets[sheet], "download", "intercept", {
14050  type: "xlsx",
14051  options: { sheetOnly: true },
14052  active: self.active,
14053  intercept: function intercept(data) {
14054  workbook.Sheets[sheet] = data;
14055  }
14056  });
14057  }
14058  }
14059  } else {
14060  workbook.SheetNames.push(sheetName);
14061  workbook.Sheets[sheetName] = generateSheet();
14062  }
14063 
14064  if (options.documentProcessing) {
14065  workbook = options.documentProcessing(workbook);
14066  }
14067 
14068  //convert workbook to binary array
14069  function s2ab(s) {
14070  var buf = new ArrayBuffer(s.length);
14071  var view = new Uint8Array(buf);
14072  for (var i = 0; i != s.length; ++i) {
14073  view[i] = s.charCodeAt(i) & 0xFF;
14074  }return buf;
14075  }
14076 
14077  output = XLSX.write(workbook, { bookType: 'xlsx', bookSST: true, type: 'binary' });
14078 
14079  setFileContents(s2ab(output), "application/octet-stream");
14080  },
14081 
14082  html: function html(columns, data, options, setFileContents, config) {
14083  if (this.table.modExists("htmlTableExport", true)) {
14084  setFileContents(this.table.modules.htmlTableExport.getHtml(true, options.style, config), "text/html");
14085  }
14086  }
14087 
14088  };
14089 
14090  Tabulator.prototype.registerModule("download", Download);
14091 
14092  var Edit = function Edit(table) {
14093  this.table = table; //hold Tabulator object
14094  this.currentCell = false; //hold currently editing cell
14095  this.mouseClick = false; //hold mousedown state to prevent click binding being overriden by editor opening
14096  this.recursionBlock = false; //prevent focus recursion
14097  this.invalidEdit = false;
14098  };
14099 
14100  //initialize column editor
14101  Edit.prototype.initializeColumn = function (column) {
14102  var self = this,
14103  config = {
14104  editor: false,
14105  blocked: false,
14106  check: column.definition.editable,
14107  params: column.definition.editorParams || {}
14108  };
14109 
14110  //set column editor
14111  switch (_typeof(column.definition.editor)) {
14112  case "string":
14113 
14114  if (column.definition.editor === "tick") {
14115  column.definition.editor = "tickCross";
14116  console.warn("DEPRECATION WARNING - the tick editor has been deprecated, please use the tickCross editor");
14117  }
14118 
14119  if (self.editors[column.definition.editor]) {
14120  config.editor = self.editors[column.definition.editor];
14121  } else {
14122  console.warn("Editor Error - No such editor found: ", column.definition.editor);
14123  }
14124  break;
14125 
14126  case "function":
14127  config.editor = column.definition.editor;
14128  break;
14129 
14130  case "boolean":
14131 
14132  if (column.definition.editor === true) {
14133 
14134  if (typeof column.definition.formatter !== "function") {
14135 
14136  if (column.definition.formatter === "tick") {
14137  column.definition.formatter = "tickCross";
14138  console.warn("DEPRECATION WARNING - the tick editor has been deprecated, please use the tickCross editor");
14139  }
14140 
14141  if (self.editors[column.definition.formatter]) {
14142  config.editor = self.editors[column.definition.formatter];
14143  } else {
14144  config.editor = self.editors["input"];
14145  }
14146  } else {
14147  console.warn("Editor Error - Cannot auto lookup editor for a custom formatter: ", column.definition.formatter);
14148  }
14149  }
14150  break;
14151  }
14152 
14153  if (config.editor) {
14154  column.modules.edit = config;
14155  }
14156  };
14157 
14158  Edit.prototype.getCurrentCell = function () {
14159  return this.currentCell ? this.currentCell.getComponent() : false;
14160  };
14161 
14162  Edit.prototype.clearEditor = function () {
14163  var cell = this.currentCell,
14164  cellEl;
14165 
14166  this.invalidEdit = false;
14167 
14168  if (cell) {
14169  this.currentCell = false;
14170 
14171  cellEl = cell.getElement();
14172  cellEl.classList.remove("tabulator-validation-fail");
14173  cellEl.classList.remove("tabulator-editing");
14174  while (cellEl.firstChild) {
14175  cellEl.removeChild(cellEl.firstChild);
14176  }cell.row.getElement().classList.remove("tabulator-row-editing");
14177  }
14178  };
14179 
14180  Edit.prototype.cancelEdit = function () {
14181 
14182  if (this.currentCell) {
14183  var cell = this.currentCell;
14184  var component = this.currentCell.getComponent();
14185 
14186  this.clearEditor();
14187  cell.setValueActual(cell.getValue());
14188 
14189  if (cell.column.cellEvents.cellEditCancelled) {
14190  cell.column.cellEvents.cellEditCancelled.call(this.table, component);
14191  }
14192 
14193  this.table.options.cellEditCancelled.call(this.table, component);
14194  }
14195  };
14196 
14197  //return a formatted value for a cell
14198  Edit.prototype.bindEditor = function (cell) {
14199  var self = this,
14200  element = cell.getElement();
14201 
14202  element.setAttribute("tabindex", 0);
14203 
14204  element.addEventListener("click", function (e) {
14205  if (!element.classList.contains("tabulator-editing")) {
14206  element.focus();
14207  }
14208  });
14209 
14210  element.addEventListener("mousedown", function (e) {
14211  self.mouseClick = true;
14212  });
14213 
14214  element.addEventListener("focus", function (e) {
14215  if (!self.recursionBlock) {
14216  self.edit(cell, e, false);
14217  }
14218  });
14219  };
14220 
14221  Edit.prototype.focusCellNoEvent = function (cell, block) {
14222  this.recursionBlock = true;
14223  if (!(block && this.table.browser === "ie")) {
14224  cell.getElement().focus();
14225  }
14226  this.recursionBlock = false;
14227  };
14228 
14229  Edit.prototype.editCell = function (cell, forceEdit) {
14230  this.focusCellNoEvent(cell);
14231  this.edit(cell, false, forceEdit);
14232  };
14233 
14234  Edit.prototype.edit = function (cell, e, forceEdit) {
14235  var self = this,
14236  allowEdit = true,
14237  rendered = function rendered() {},
14238  element = cell.getElement(),
14239  cellEditor,
14240  component,
14241  params;
14242 
14243  //prevent editing if another cell is refusing to leave focus (eg. validation fail)
14244  if (this.currentCell) {
14245  if (!this.invalidEdit) {
14246  this.cancelEdit();
14247  }
14248  return;
14249  }
14250 
14251  //handle successfull value change
14252  function success(value) {
14253 
14254  if (self.currentCell === cell) {
14255  var valid = true;
14256 
14257  if (cell.column.modules.validate && self.table.modExists("validate")) {
14258  valid = self.table.modules.validate.validate(cell.column.modules.validate, cell.getComponent(), value);
14259  }
14260 
14261  if (valid === true) {
14262  self.clearEditor();
14263  cell.setValue(value, true);
14264 
14265  if (self.table.options.dataTree && self.table.modExists("dataTree")) {
14266  self.table.modules.dataTree.checkForRestyle(cell);
14267  }
14268 
14269  return true;
14270  } else {
14271  self.invalidEdit = true;
14272  element.classList.add("tabulator-validation-fail");
14273  self.focusCellNoEvent(cell, true);
14274  rendered();
14275  self.table.options.validationFailed.call(self.table, cell.getComponent(), value, valid);
14276 
14277  return false;
14278  }
14279  } else {
14280  // console.warn("Edit Success Error - cannot call success on a cell that is no longer being edited");
14281  }
14282  }
14283 
14284  //handle aborted edit
14285  function cancel() {
14286  if (self.currentCell === cell) {
14287  self.cancelEdit();
14288 
14289  if (self.table.options.dataTree && self.table.modExists("dataTree")) {
14290  self.table.modules.dataTree.checkForRestyle(cell);
14291  }
14292  } else {
14293  // console.warn("Edit Success Error - cannot call cancel on a cell that is no longer being edited");
14294  }
14295  }
14296 
14297  function onRendered(callback) {
14298  rendered = callback;
14299  }
14300 
14301  if (!cell.column.modules.edit.blocked) {
14302  if (e) {
14303  e.stopPropagation();
14304  }
14305 
14306  switch (_typeof(cell.column.modules.edit.check)) {
14307  case "function":
14308  allowEdit = cell.column.modules.edit.check(cell.getComponent());
14309  break;
14310 
14311  case "boolean":
14312  allowEdit = cell.column.modules.edit.check;
14313  break;
14314  }
14315 
14316  if (allowEdit || forceEdit) {
14317 
14318  self.cancelEdit();
14319 
14320  self.currentCell = cell;
14321 
14322  component = cell.getComponent();
14323 
14324  if (this.mouseClick) {
14325  this.mouseClick = false;
14326 
14327  if (cell.column.cellEvents.cellClick) {
14328  cell.column.cellEvents.cellClick.call(this.table, e, component);
14329  }
14330  }
14331 
14332  if (cell.column.cellEvents.cellEditing) {
14333  cell.column.cellEvents.cellEditing.call(this.table, component);
14334  }
14335 
14336  self.table.options.cellEditing.call(this.table, component);
14337 
14338  params = typeof cell.column.modules.edit.params === "function" ? cell.column.modules.edit.params(component) : cell.column.modules.edit.params;
14339 
14340  cellEditor = cell.column.modules.edit.editor.call(self, component, onRendered, success, cancel, params);
14341 
14342  //if editor returned, add to DOM, if false, abort edit
14343  if (cellEditor !== false) {
14344 
14345  if (cellEditor instanceof Node) {
14346  element.classList.add("tabulator-editing");
14347  cell.row.getElement().classList.add("tabulator-row-editing");
14348  while (element.firstChild) {
14349  element.removeChild(element.firstChild);
14350  }element.appendChild(cellEditor);
14351 
14352  //trigger onRendered Callback
14353  rendered();
14354 
14355  //prevent editing from triggering rowClick event
14356  var children = element.children;
14357 
14358  for (var i = 0; i < children.length; i++) {
14359  children[i].addEventListener("click", function (e) {
14360  e.stopPropagation();
14361  });
14362  }
14363  } else {
14364  console.warn("Edit Error - Editor should return an instance of Node, the editor returned:", cellEditor);
14365  element.blur();
14366  return false;
14367  }
14368  } else {
14369  element.blur();
14370  return false;
14371  }
14372 
14373  return true;
14374  } else {
14375  this.mouseClick = false;
14376  element.blur();
14377  return false;
14378  }
14379  } else {
14380  this.mouseClick = false;
14381  element.blur();
14382  return false;
14383  }
14384  };
14385 
14386  //default data editors
14387  Edit.prototype.editors = {
14388 
14389  //input element
14390  input: function input(cell, onRendered, success, cancel, editorParams) {
14391 
14392  //create and style input
14393  var cellValue = cell.getValue(),
14394  input = document.createElement("input");
14395 
14396  input.setAttribute("type", editorParams.search ? "search" : "text");
14397 
14398  input.style.padding = "4px";
14399  input.style.width = "100%";
14400  input.style.boxSizing = "border-box";
14401 
14402  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
14403  for (var key in editorParams.elementAttributes) {
14404  if (key.charAt(0) == "+") {
14405  key = key.slice(1);
14406  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
14407  } else {
14408  input.setAttribute(key, editorParams.elementAttributes[key]);
14409  }
14410  }
14411  }
14412 
14413  input.value = typeof cellValue !== "undefined" ? cellValue : "";
14414 
14415  onRendered(function () {
14416  input.focus();
14417  input.style.height = "100%";
14418  });
14419 
14420  function onChange(e) {
14421  if ((cellValue === null || typeof cellValue === "undefined") && input.value !== "" || input.value != cellValue) {
14422 
14423  if (success(input.value)) {
14424  cellValue = input.value; //persist value if successfully validated incase editor is used as header filter
14425  }
14426  } else {
14427  cancel();
14428  }
14429  }
14430 
14431  //submit new value on blur or change
14432  input.addEventListener("change", onChange);
14433  input.addEventListener("blur", onChange);
14434 
14435  //submit new value on enter
14436  input.addEventListener("keydown", function (e) {
14437  switch (e.keyCode) {
14438  case 13:
14439  onChange(e);
14440  break;
14441 
14442  case 27:
14443  cancel();
14444  break;
14445  }
14446  });
14447 
14448  return input;
14449  },
14450 
14451  //resizable text area element
14452  textarea: function textarea(cell, onRendered, success, cancel, editorParams) {
14453  var self = this,
14454  cellValue = cell.getValue(),
14455  vertNav = editorParams.verticalNavigation || "hybrid",
14456  value = String(cellValue !== null && typeof cellValue !== "undefined" ? cellValue : ""),
14457  count = (value.match(/(?:\r\n|\r|\n)/g) || []).length + 1,
14458  input = document.createElement("textarea"),
14459  scrollHeight = 0;
14460 
14461  //create and style input
14462  input.style.display = "block";
14463  input.style.padding = "2px";
14464  input.style.height = "100%";
14465  input.style.width = "100%";
14466  input.style.boxSizing = "border-box";
14467  input.style.whiteSpace = "pre-wrap";
14468  input.style.resize = "none";
14469 
14470  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
14471  for (var key in editorParams.elementAttributes) {
14472  if (key.charAt(0) == "+") {
14473  key = key.slice(1);
14474  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
14475  } else {
14476  input.setAttribute(key, editorParams.elementAttributes[key]);
14477  }
14478  }
14479  }
14480 
14481  input.value = value;
14482 
14483  onRendered(function () {
14484  input.focus();
14485  input.style.height = "100%";
14486  });
14487 
14488  function onChange(e) {
14489 
14490  if ((cellValue === null || typeof cellValue === "undefined") && input.value !== "" || input.value != cellValue) {
14491 
14492  if (success(input.value)) {
14493  cellValue = input.value; //persist value if successfully validated incase editor is used as header filter
14494  }
14495 
14496  setTimeout(function () {
14497  cell.getRow().normalizeHeight();
14498  }, 300);
14499  } else {
14500  cancel();
14501  }
14502  }
14503 
14504  //submit new value on blur or change
14505  input.addEventListener("change", onChange);
14506  input.addEventListener("blur", onChange);
14507 
14508  input.addEventListener("keyup", function () {
14509 
14510  input.style.height = "";
14511 
14512  var heightNow = input.scrollHeight;
14513 
14514  input.style.height = heightNow + "px";
14515 
14516  if (heightNow != scrollHeight) {
14517  scrollHeight = heightNow;
14518  cell.getRow().normalizeHeight();
14519  }
14520  });
14521 
14522  input.addEventListener("keydown", function (e) {
14523 
14524  switch (e.keyCode) {
14525  case 27:
14526  cancel();
14527  break;
14528 
14529  case 38:
14530  //up arrow
14531  if (vertNav == "editor" || vertNav == "hybrid" && input.selectionStart) {
14532  e.stopImmediatePropagation();
14533  e.stopPropagation();
14534  }
14535 
14536  break;
14537 
14538  case 40:
14539  //down arrow
14540  if (vertNav == "editor" || vertNav == "hybrid" && input.selectionStart !== input.value.length) {
14541  e.stopImmediatePropagation();
14542  e.stopPropagation();
14543  }
14544  break;
14545  }
14546  });
14547 
14548  return input;
14549  },
14550 
14551  //input element with type of number
14552  number: function number(cell, onRendered, success, cancel, editorParams) {
14553 
14554  var cellValue = cell.getValue(),
14555  vertNav = editorParams.verticalNavigation || "editor",
14556  input = document.createElement("input");
14557 
14558  input.setAttribute("type", "number");
14559 
14560  if (typeof editorParams.max != "undefined") {
14561  input.setAttribute("max", editorParams.max);
14562  }
14563 
14564  if (typeof editorParams.min != "undefined") {
14565  input.setAttribute("min", editorParams.min);
14566  }
14567 
14568  if (typeof editorParams.step != "undefined") {
14569  input.setAttribute("step", editorParams.step);
14570  }
14571 
14572  //create and style input
14573  input.style.padding = "4px";
14574  input.style.width = "100%";
14575  input.style.boxSizing = "border-box";
14576 
14577  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
14578  for (var key in editorParams.elementAttributes) {
14579  if (key.charAt(0) == "+") {
14580  key = key.slice(1);
14581  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
14582  } else {
14583  input.setAttribute(key, editorParams.elementAttributes[key]);
14584  }
14585  }
14586  }
14587 
14588  input.value = cellValue;
14589 
14590  var blurFunc = function blurFunc(e) {
14591  onChange();
14592  };
14593 
14594  onRendered(function () {
14595  //submit new value on blur
14596  input.removeEventListener("blur", blurFunc);
14597 
14598  input.focus();
14599  input.style.height = "100%";
14600 
14601  //submit new value on blur
14602  input.addEventListener("blur", blurFunc);
14603  });
14604 
14605  function onChange() {
14606  var value = input.value;
14607 
14608  if (!isNaN(value) && value !== "") {
14609  value = Number(value);
14610  }
14611 
14612  if (value != cellValue) {
14613  if (success(value)) {
14614  cellValue = value; //persist value if successfully validated incase editor is used as header filter
14615  }
14616  } else {
14617  cancel();
14618  }
14619  }
14620 
14621  //submit new value on enter
14622  input.addEventListener("keydown", function (e) {
14623  switch (e.keyCode) {
14624  case 13:
14625  // case 9:
14626  onChange();
14627  break;
14628 
14629  case 27:
14630  cancel();
14631  break;
14632 
14633  case 38: //up arrow
14634  case 40:
14635  //down arrow
14636  if (vertNav == "editor") {
14637  e.stopImmediatePropagation();
14638  e.stopPropagation();
14639  }
14640  break;
14641  }
14642  });
14643 
14644  return input;
14645  },
14646 
14647  //input element with type of number
14648  range: function range(cell, onRendered, success, cancel, editorParams) {
14649 
14650  var cellValue = cell.getValue(),
14651  input = document.createElement("input");
14652 
14653  input.setAttribute("type", "range");
14654 
14655  if (typeof editorParams.max != "undefined") {
14656  input.setAttribute("max", editorParams.max);
14657  }
14658 
14659  if (typeof editorParams.min != "undefined") {
14660  input.setAttribute("min", editorParams.min);
14661  }
14662 
14663  if (typeof editorParams.step != "undefined") {
14664  input.setAttribute("step", editorParams.step);
14665  }
14666 
14667  //create and style input
14668  input.style.padding = "4px";
14669  input.style.width = "100%";
14670  input.style.boxSizing = "border-box";
14671 
14672  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
14673  for (var key in editorParams.elementAttributes) {
14674  if (key.charAt(0) == "+") {
14675  key = key.slice(1);
14676  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
14677  } else {
14678  input.setAttribute(key, editorParams.elementAttributes[key]);
14679  }
14680  }
14681  }
14682 
14683  input.value = cellValue;
14684 
14685  onRendered(function () {
14686  input.focus();
14687  input.style.height = "100%";
14688  });
14689 
14690  function onChange() {
14691  var value = input.value;
14692 
14693  if (!isNaN(value) && value !== "") {
14694  value = Number(value);
14695  }
14696 
14697  if (value != cellValue) {
14698  if (success(value)) {
14699  cellValue = value; //persist value if successfully validated incase editor is used as header filter
14700  }
14701  } else {
14702  cancel();
14703  }
14704  }
14705 
14706  //submit new value on blur
14707  input.addEventListener("blur", function (e) {
14708  onChange();
14709  });
14710 
14711  //submit new value on enter
14712  input.addEventListener("keydown", function (e) {
14713  switch (e.keyCode) {
14714  case 13:
14715  case 9:
14716  onChange();
14717  break;
14718 
14719  case 27:
14720  cancel();
14721  break;
14722  }
14723  });
14724 
14725  return input;
14726  },
14727 
14728  //select
14729  select: function select(cell, onRendered, success, cancel, editorParams) {
14730  var self = this,
14731  cellEl = cell.getElement(),
14732  initialValue = cell.getValue(),
14733  vertNav = editorParams.verticalNavigation || "editor",
14734  initialDisplayValue = typeof initialValue !== "undefined" || initialValue === null ? initialValue : typeof editorParams.defaultValue !== "undefined" ? editorParams.defaultValue : "",
14735  input = document.createElement("input"),
14736  listEl = document.createElement("div"),
14737  dataItems = [],
14738  displayItems = [],
14739  currentItem = {},
14740  blurable = true;
14741 
14742  this.table.rowManager.element.addEventListener("scroll", cancelItem);
14743 
14744  if (Array.isArray(editorParams) || !Array.isArray(editorParams) && (typeof editorParams === 'undefined' ? 'undefined' : _typeof(editorParams)) === "object" && !editorParams.values) {
14745  console.warn("DEPRECATION WANRING - values for the select editor must now be passed into the values property of the editorParams object, not as the editorParams object");
14746  editorParams = { values: editorParams };
14747  }
14748 
14749  function getUniqueColumnValues(field) {
14750  var output = {},
14751  data = self.table.getData(),
14752  column;
14753 
14754  if (field) {
14755  column = self.table.columnManager.getColumnByField(field);
14756  } else {
14757  column = cell.getColumn()._getSelf();
14758  }
14759 
14760  if (column) {
14761  data.forEach(function (row) {
14762  var val = column.getFieldValue(row);
14763 
14764  if (val !== null && typeof val !== "undefined" && val !== "") {
14765  output[val] = true;
14766  }
14767  });
14768 
14769  if (editorParams.sortValuesList) {
14770  if (editorParams.sortValuesList == "asc") {
14771  output = Object.keys(output).sort();
14772  } else {
14773  output = Object.keys(output).sort().reverse();
14774  }
14775  } else {
14776  output = Object.keys(output);
14777  }
14778  } else {
14779  console.warn("unable to find matching column to create select lookup list:", field);
14780  }
14781 
14782  return output;
14783  }
14784 
14785  function parseItems(inputValues, curentValue) {
14786  var dataList = [];
14787  var displayList = [];
14788 
14789  function processComplexListItem(item) {
14790  var item = {
14791  label: editorParams.listItemFormatter ? editorParams.listItemFormatter(item.value, item.label) : item.label,
14792  value: item.value,
14793  element: false
14794  };
14795 
14796  if (item.value === curentValue || !isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue)) {
14797  setCurrentItem(item);
14798  }
14799 
14800  dataList.push(item);
14801  displayList.push(item);
14802 
14803  return item;
14804  }
14805 
14806  if (typeof inputValues == "function") {
14807  inputValues = inputValues(cell);
14808  }
14809 
14810  if (Array.isArray(inputValues)) {
14811  inputValues.forEach(function (value) {
14812  var item;
14813 
14814  if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === "object") {
14815 
14816  if (value.options) {
14817  item = {
14818  label: value.label,
14819  group: true,
14820  element: false
14821  };
14822 
14823  displayList.push(item);
14824 
14825  value.options.forEach(function (item) {
14826  processComplexListItem(item);
14827  });
14828  } else {
14829  processComplexListItem(value);
14830  }
14831  } else {
14832 
14833  item = {
14834  label: editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value,
14835  value: value,
14836  element: false
14837  };
14838 
14839  if (item.value === curentValue || !isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue)) {
14840  setCurrentItem(item);
14841  }
14842 
14843  dataList.push(item);
14844  displayList.push(item);
14845  }
14846  });
14847  } else {
14848  for (var key in inputValues) {
14849  var item = {
14850  label: editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key],
14851  value: key,
14852  element: false
14853  };
14854 
14855  if (item.value === curentValue || !isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue)) {
14856  setCurrentItem(item);
14857  }
14858 
14859  dataList.push(item);
14860  displayList.push(item);
14861  }
14862  }
14863 
14864  dataItems = dataList;
14865  displayItems = displayList;
14866 
14867  fillList();
14868  }
14869 
14870  function fillList() {
14871  while (listEl.firstChild) {
14872  listEl.removeChild(listEl.firstChild);
14873  }displayItems.forEach(function (item) {
14874  var el = item.element;
14875 
14876  if (!el) {
14877 
14878  if (item.group) {
14879  el = document.createElement("div");
14880  el.classList.add("tabulator-edit-select-list-group");
14881  el.tabIndex = 0;
14882  el.innerHTML = item.label === "" ? "&nbsp;" : item.label;
14883  } else {
14884  el = document.createElement("div");
14885  el.classList.add("tabulator-edit-select-list-item");
14886  el.tabIndex = 0;
14887  el.innerHTML = item.label === "" ? "&nbsp;" : item.label;
14888 
14889  el.addEventListener("click", function () {
14890  setCurrentItem(item);
14891  chooseItem();
14892  });
14893 
14894  if (item === currentItem) {
14895  el.classList.add("active");
14896  }
14897  }
14898 
14899  el.addEventListener("mousedown", function () {
14900  blurable = false;
14901 
14902  setTimeout(function () {
14903  blurable = true;
14904  }, 10);
14905  });
14906 
14907  item.element = el;
14908  }
14909 
14910  listEl.appendChild(el);
14911  });
14912  }
14913 
14914  function setCurrentItem(item) {
14915 
14916  if (currentItem && currentItem.element) {
14917  currentItem.element.classList.remove("active");
14918  }
14919 
14920  currentItem = item;
14921  input.value = item.label === "&nbsp;" ? "" : item.label;
14922 
14923  if (item.element) {
14924  item.element.classList.add("active");
14925  }
14926  }
14927 
14928  function chooseItem() {
14929  hideList();
14930 
14931  if (initialValue !== currentItem.value) {
14932  initialValue = currentItem.value;
14933  success(currentItem.value);
14934  } else {
14935  cancel();
14936  }
14937  }
14938 
14939  function cancelItem() {
14940  hideList();
14941  cancel();
14942  }
14943 
14944  function showList() {
14945  if (!listEl.parentNode) {
14946 
14947  if (editorParams.values === true) {
14948  parseItems(getUniqueColumnValues(), initialDisplayValue);
14949  } else if (typeof editorParams.values === "string") {
14950  parseItems(getUniqueColumnValues(editorParams.values), initialDisplayValue);
14951  } else {
14952  parseItems(editorParams.values || [], initialDisplayValue);
14953  }
14954 
14955  var offset = Tabulator.prototype.helpers.elOffset(cellEl);
14956 
14957  listEl.style.minWidth = cellEl.offsetWidth + "px";
14958 
14959  listEl.style.top = offset.top + cellEl.offsetHeight + "px";
14960  listEl.style.left = offset.left + "px";
14961  document.body.appendChild(listEl);
14962  }
14963  }
14964 
14965  function hideList() {
14966  if (listEl.parentNode) {
14967  listEl.parentNode.removeChild(listEl);
14968  }
14969 
14970  removeScrollListener();
14971  }
14972 
14973  function removeScrollListener() {
14974  self.table.rowManager.element.removeEventListener("scroll", cancelItem);
14975  }
14976 
14977  //style input
14978  input.setAttribute("type", "text");
14979 
14980  input.style.padding = "4px";
14981  input.style.width = "100%";
14982  input.style.boxSizing = "border-box";
14983  input.style.cursor = "default";
14984  input.readOnly = this.currentCell != false;
14985 
14986  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
14987  for (var key in editorParams.elementAttributes) {
14988  if (key.charAt(0) == "+") {
14989  key = key.slice(1);
14990  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
14991  } else {
14992  input.setAttribute(key, editorParams.elementAttributes[key]);
14993  }
14994  }
14995  }
14996 
14997  input.value = typeof initialValue !== "undefined" || initialValue === null ? initialValue : "";
14998 
14999  // if(editorParams.values === true){
15000  // parseItems(getUniqueColumnValues(), initialValue);
15001  // }else if(typeof editorParams.values === "string"){
15002  // parseItems(getUniqueColumnValues(editorParams.values), initialValue);
15003  // }else{
15004  // parseItems(editorParams.values || [], initialValue);
15005  // }
15006 
15007  //allow key based navigation
15008  input.addEventListener("keydown", function (e) {
15009  var index;
15010 
15011  switch (e.keyCode) {
15012  case 38:
15013  //up arrow
15014  index = dataItems.indexOf(currentItem);
15015 
15016  if (vertNav == "editor" || vertNav == "hybrid" && index) {
15017  e.stopImmediatePropagation();
15018  e.stopPropagation();
15019  e.preventDefault();
15020 
15021  if (index > 0) {
15022  setCurrentItem(dataItems[index - 1]);
15023  }
15024  }
15025  break;
15026 
15027  case 40:
15028  //down arrow
15029  index = dataItems.indexOf(currentItem);
15030 
15031  if (vertNav == "editor" || vertNav == "hybrid" && index < dataItems.length - 1) {
15032  e.stopImmediatePropagation();
15033  e.stopPropagation();
15034  e.preventDefault();
15035 
15036  if (index < dataItems.length - 1) {
15037  if (index == -1) {
15038  setCurrentItem(dataItems[0]);
15039  } else {
15040  setCurrentItem(dataItems[index + 1]);
15041  }
15042  }
15043  }
15044  break;
15045 
15046  case 37: //left arrow
15047  case 39:
15048  //right arrow
15049  e.stopImmediatePropagation();
15050  e.stopPropagation();
15051  e.preventDefault();
15052  break;
15053 
15054  case 13:
15055  //enter
15056  chooseItem();
15057  break;
15058 
15059  case 27:
15060  //escape
15061  cancelItem();
15062  break;
15063  }
15064  });
15065 
15066  input.addEventListener("blur", function (e) {
15067  if (blurable) {
15068  cancelItem();
15069  }
15070  });
15071 
15072  input.addEventListener("focus", function (e) {
15073  showList();
15074  });
15075 
15076  //style list element
15077  listEl = document.createElement("div");
15078  listEl.classList.add("tabulator-edit-select-list");
15079 
15080  onRendered(function () {
15081  input.style.height = "100%";
15082  input.focus();
15083  });
15084 
15085  return input;
15086  },
15087 
15088  //autocomplete
15089  autocomplete: function autocomplete(cell, onRendered, success, cancel, editorParams) {
15090  var self = this,
15091  cellEl = cell.getElement(),
15092  initialValue = cell.getValue(),
15093  vertNav = editorParams.verticalNavigation || "editor",
15094  initialDisplayValue = typeof initialValue !== "undefined" || initialValue === null ? initialValue : typeof editorParams.defaultValue !== "undefined" ? editorParams.defaultValue : "",
15095  input = document.createElement("input"),
15096  listEl = document.createElement("div"),
15097  allItems = [],
15098  displayItems = [],
15099  values = [],
15100  currentItem = {},
15101  blurable = true;
15102 
15103  this.table.rowManager.element.addEventListener("scroll", cancelItem);
15104 
15105  function getUniqueColumnValues(field) {
15106  var output = {},
15107  data = self.table.getData(),
15108  column;
15109 
15110  if (field) {
15111  column = self.table.columnManager.getColumnByField(field);
15112  } else {
15113  column = cell.getColumn()._getSelf();
15114  }
15115 
15116  if (column) {
15117  data.forEach(function (row) {
15118  var val = column.getFieldValue(row);
15119 
15120  if (val !== null && typeof val !== "undefined" && val !== "") {
15121  output[val] = true;
15122  }
15123  });
15124 
15125  if (editorParams.sortValuesList) {
15126  if (editorParams.sortValuesList == "asc") {
15127  output = Object.keys(output).sort();
15128  } else {
15129  output = Object.keys(output).sort().reverse();
15130  }
15131  } else {
15132  output = Object.keys(output);
15133  }
15134  } else {
15135  console.warn("unable to find matching column to create autocomplete lookup list:", field);
15136  }
15137 
15138  return output;
15139  }
15140 
15141  function parseItems(inputValues, curentValue) {
15142  var itemList = [];
15143 
15144  if (Array.isArray(inputValues)) {
15145  inputValues.forEach(function (value) {
15146  var item = {
15147  title: editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value,
15148  value: value,
15149  element: false
15150  };
15151 
15152  if (item.value === curentValue || !isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue)) {
15153  setCurrentItem(item);
15154  }
15155 
15156  itemList.push(item);
15157  });
15158  } else {
15159  for (var key in inputValues) {
15160  var item = {
15161  title: editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key],
15162  value: key,
15163  element: false
15164  };
15165 
15166  if (item.value === curentValue || !isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue)) {
15167  setCurrentItem(item);
15168  }
15169 
15170  itemList.push(item);
15171  }
15172  }
15173 
15174  if (editorParams.searchFunc) {
15175  itemList.forEach(function (item) {
15176  item.search = {
15177  title: item.title,
15178  value: item.value
15179  };
15180  });
15181  }
15182 
15183  allItems = itemList;
15184  }
15185 
15186  function filterList(term, intialLoad) {
15187  var matches = [],
15188  searchObjs = [],
15189  searchResults = [];
15190 
15191  if (editorParams.searchFunc) {
15192 
15193  allItems.forEach(function (item) {
15194  searchObjs.push(item.search);
15195  });
15196 
15197  searchResults = editorParams.searchFunc(term, searchObjs);
15198 
15199  searchResults.forEach(function (result) {
15200  var match = allItems.find(function (item) {
15201  return item.search === result;
15202  });
15203 
15204  if (match) {
15205  matches.push(match);
15206  }
15207  });
15208  } else {
15209  if (term === "") {
15210 
15211  if (editorParams.showListOnEmpty) {
15212  allItems.forEach(function (item) {
15213  matches.push(item);
15214  });
15215  }
15216  } else {
15217  allItems.forEach(function (item) {
15218 
15219  if (item.value !== null || typeof item.value !== "undefined") {
15220  if (String(item.value).toLowerCase().indexOf(String(term).toLowerCase()) > -1 || String(item.title).toLowerCase().indexOf(String(term).toLowerCase()) > -1) {
15221  matches.push(item);
15222  }
15223  }
15224  });
15225  }
15226  }
15227 
15228  displayItems = matches;
15229 
15230  fillList(intialLoad);
15231  }
15232 
15233  function fillList(intialLoad) {
15234  var current = false;
15235 
15236  while (listEl.firstChild) {
15237  listEl.removeChild(listEl.firstChild);
15238  }displayItems.forEach(function (item) {
15239  var el = item.element;
15240 
15241  if (!el) {
15242  el = document.createElement("div");
15243  el.classList.add("tabulator-edit-select-list-item");
15244  el.tabIndex = 0;
15245  el.innerHTML = item.title;
15246 
15247  el.addEventListener("click", function () {
15248  setCurrentItem(item);
15249  chooseItem();
15250  });
15251 
15252  el.addEventListener("mousedown", function () {
15253  blurable = false;
15254 
15255  setTimeout(function () {
15256  blurable = true;
15257  }, 10);
15258  });
15259 
15260  item.element = el;
15261 
15262  if (intialLoad && item.value == initialValue) {
15263  input.value = item.title;
15264  item.element.classList.add("active");
15265  current = true;
15266  }
15267 
15268  if (item === currentItem) {
15269  item.element.classList.add("active");
15270  current = true;
15271  }
15272  }
15273 
15274  listEl.appendChild(el);
15275  });
15276 
15277  if (!current) {
15278  setCurrentItem(false);
15279  }
15280  }
15281 
15282  function setCurrentItem(item, showInputValue) {
15283  if (currentItem && currentItem.element) {
15284  currentItem.element.classList.remove("active");
15285  }
15286 
15287  currentItem = item;
15288 
15289  if (item && item.element) {
15290  item.element.classList.add("active");
15291  }
15292  }
15293 
15294  function chooseItem() {
15295  hideList();
15296 
15297  if (currentItem) {
15298  if (initialValue !== currentItem.value) {
15299  initialValue = currentItem.value;
15300  input.value = currentItem.title;
15301  success(currentItem.value);
15302  } else {
15303  cancel();
15304  }
15305  } else {
15306  if (editorParams.freetext) {
15307  initialValue = input.value;
15308  success(input.value);
15309  } else {
15310  if (editorParams.allowEmpty && input.value === "") {
15311  initialValue = input.value;
15312  success(input.value);
15313  } else {
15314  cancel();
15315  }
15316  }
15317  }
15318  }
15319 
15320  function cancelItem() {
15321  hideList();
15322  cancel();
15323  }
15324 
15325  function showList() {
15326  if (!listEl.parentNode) {
15327  while (listEl.firstChild) {
15328  listEl.removeChild(listEl.firstChild);
15329  }if (editorParams.values === true) {
15330  values = getUniqueColumnValues();
15331  } else if (typeof editorParams.values === "string") {
15332  values = getUniqueColumnValues(editorParams.values);
15333  } else {
15334  values = editorParams.values || [];
15335  }
15336 
15337  parseItems(values, initialValue);
15338 
15339  var offset = Tabulator.prototype.helpers.elOffset(cellEl);
15340 
15341  listEl.style.minWidth = cellEl.offsetWidth + "px";
15342 
15343  listEl.style.top = offset.top + cellEl.offsetHeight + "px";
15344  listEl.style.left = offset.left + "px";
15345  document.body.appendChild(listEl);
15346  }
15347  }
15348 
15349  function hideList() {
15350  if (listEl.parentNode) {
15351  listEl.parentNode.removeChild(listEl);
15352  }
15353 
15354  removeScrollListener();
15355  }
15356 
15357  function removeScrollListener() {
15358  self.table.rowManager.element.removeEventListener("scroll", cancelItem);
15359  }
15360 
15361  //style input
15362  input.setAttribute("type", "search");
15363 
15364  input.style.padding = "4px";
15365  input.style.width = "100%";
15366  input.style.boxSizing = "border-box";
15367 
15368  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
15369  for (var key in editorParams.elementAttributes) {
15370  if (key.charAt(0) == "+") {
15371  key = key.slice(1);
15372  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
15373  } else {
15374  input.setAttribute(key, editorParams.elementAttributes[key]);
15375  }
15376  }
15377  }
15378 
15379  //allow key based navigation
15380  input.addEventListener("keydown", function (e) {
15381  var index;
15382 
15383  switch (e.keyCode) {
15384  case 38:
15385  //up arrow
15386  index = displayItems.indexOf(currentItem);
15387 
15388  if (vertNav == "editor" || vertNav == "hybrid" && index) {
15389  e.stopImmediatePropagation();
15390  e.stopPropagation();
15391  e.preventDefault();
15392 
15393  if (index > 0) {
15394  setCurrentItem(displayItems[index - 1]);
15395  } else {
15396  setCurrentItem(false);
15397  }
15398  }
15399  break;
15400 
15401  case 40:
15402  //down arrow
15403 
15404  index = displayItems.indexOf(currentItem);
15405 
15406  if (vertNav == "editor" || vertNav == "hybrid" && index < displayItems.length - 1) {
15407 
15408  e.stopImmediatePropagation();
15409  e.stopPropagation();
15410  e.preventDefault();
15411 
15412  if (index < displayItems.length - 1) {
15413  if (index == -1) {
15414  setCurrentItem(displayItems[0]);
15415  } else {
15416  setCurrentItem(displayItems[index + 1]);
15417  }
15418  }
15419  }
15420  break;
15421 
15422  case 37: //left arrow
15423  case 39:
15424  //right arrow
15425  e.stopImmediatePropagation();
15426  e.stopPropagation();
15427  e.preventDefault();
15428  break;
15429 
15430  case 13:
15431  //enter
15432  chooseItem();
15433  break;
15434 
15435  case 27:
15436  //escape
15437  cancelItem();
15438  break;
15439 
15440  case 36: //home
15441  case 35:
15442  //end
15443  //prevent table navigation while using input element
15444  e.stopImmediatePropagation();
15445  break;
15446  }
15447  });
15448 
15449  input.addEventListener("keyup", function (e) {
15450 
15451  switch (e.keyCode) {
15452  case 38: //up arrow
15453  case 37: //left arrow
15454  case 39: //up arrow
15455  case 40: //right arrow
15456  case 13: //enter
15457  case 27:
15458  //escape
15459  break;
15460 
15461  default:
15462  filterList(input.value);
15463  }
15464  });
15465 
15466  input.addEventListener("search", function (e) {
15467  filterList(input.value);
15468  });
15469 
15470  input.addEventListener("blur", function (e) {
15471  if (blurable) {
15472  chooseItem();
15473  }
15474  });
15475 
15476  input.addEventListener("focus", function (e) {
15477  var value = initialDisplayValue;
15478  showList();
15479  input.value = value;
15480  filterList(value, true);
15481  });
15482 
15483  //style list element
15484  listEl = document.createElement("div");
15485  listEl.classList.add("tabulator-edit-select-list");
15486 
15487  onRendered(function () {
15488  input.style.height = "100%";
15489  input.focus();
15490  });
15491 
15492  return input;
15493  },
15494 
15495  //start rating
15496  star: function star(cell, onRendered, success, cancel, editorParams) {
15497  var self = this,
15498  element = cell.getElement(),
15499  value = cell.getValue(),
15500  maxStars = element.getElementsByTagName("svg").length || 5,
15501  size = element.getElementsByTagName("svg")[0] ? element.getElementsByTagName("svg")[0].getAttribute("width") : 14,
15502  stars = [],
15503  starsHolder = document.createElement("div"),
15504  star = document.createElementNS('http://www.w3.org/2000/svg', "svg");
15505 
15506  //change star type
15507  function starChange(val) {
15508  stars.forEach(function (star, i) {
15509  if (i < val) {
15510  if (self.table.browser == "ie") {
15511  star.setAttribute("class", "tabulator-star-active");
15512  } else {
15513  star.classList.replace("tabulator-star-inactive", "tabulator-star-active");
15514  }
15515 
15516  star.innerHTML = '<polygon fill="#488CE9" stroke="#014AAE" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
15517  } else {
15518  if (self.table.browser == "ie") {
15519  star.setAttribute("class", "tabulator-star-inactive");
15520  } else {
15521  star.classList.replace("tabulator-star-active", "tabulator-star-inactive");
15522  }
15523 
15524  star.innerHTML = '<polygon fill="#010155" stroke="#686868" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
15525  }
15526  });
15527  }
15528 
15529  //build stars
15530  function buildStar(i) {
15531 
15532  var starHolder = document.createElement("span");
15533  var nextStar = star.cloneNode(true);
15534 
15535  stars.push(nextStar);
15536 
15537  starHolder.addEventListener("mouseenter", function (e) {
15538  e.stopPropagation();
15539  e.stopImmediatePropagation();
15540  starChange(i);
15541  });
15542 
15543  starHolder.addEventListener("mousemove", function (e) {
15544  e.stopPropagation();
15545  e.stopImmediatePropagation();
15546  });
15547 
15548  starHolder.addEventListener("click", function (e) {
15549  e.stopPropagation();
15550  e.stopImmediatePropagation();
15551  success(i);
15552  });
15553 
15554  starHolder.appendChild(nextStar);
15555  starsHolder.appendChild(starHolder);
15556  }
15557 
15558  //handle keyboard navigation value change
15559  function changeValue(val) {
15560  value = val;
15561  starChange(val);
15562  }
15563 
15564  //style cell
15565  element.style.whiteSpace = "nowrap";
15566  element.style.overflow = "hidden";
15567  element.style.textOverflow = "ellipsis";
15568 
15569  //style holding element
15570  starsHolder.style.verticalAlign = "middle";
15571  starsHolder.style.display = "inline-block";
15572  starsHolder.style.padding = "4px";
15573 
15574  //style star
15575  star.setAttribute("width", size);
15576  star.setAttribute("height", size);
15577  star.setAttribute("viewBox", "0 0 512 512");
15578  star.setAttribute("xml:space", "preserve");
15579  star.style.padding = "0 1px";
15580 
15581  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
15582  for (var key in editorParams.elementAttributes) {
15583  if (key.charAt(0) == "+") {
15584  key = key.slice(1);
15585  starsHolder.setAttribute(key, starsHolder.getAttribute(key) + editorParams.elementAttributes["+" + key]);
15586  } else {
15587  starsHolder.setAttribute(key, editorParams.elementAttributes[key]);
15588  }
15589  }
15590  }
15591 
15592  //create correct number of stars
15593  for (var i = 1; i <= maxStars; i++) {
15594  buildStar(i);
15595  }
15596 
15597  //ensure value does not exceed number of stars
15598  value = Math.min(parseInt(value), maxStars);
15599 
15600  // set initial styling of stars
15601  starChange(value);
15602 
15603  starsHolder.addEventListener("mousemove", function (e) {
15604  starChange(0);
15605  });
15606 
15607  starsHolder.addEventListener("click", function (e) {
15608  success(0);
15609  });
15610 
15611  element.addEventListener("blur", function (e) {
15612  cancel();
15613  });
15614 
15615  //allow key based navigation
15616  element.addEventListener("keydown", function (e) {
15617  switch (e.keyCode) {
15618  case 39:
15619  //right arrow
15620  changeValue(value + 1);
15621  break;
15622 
15623  case 37:
15624  //left arrow
15625  changeValue(value - 1);
15626  break;
15627 
15628  case 13:
15629  //enter
15630  success(value);
15631  break;
15632 
15633  case 27:
15634  //escape
15635  cancel();
15636  break;
15637  }
15638  });
15639 
15640  return starsHolder;
15641  },
15642 
15643  //draggable progress bar
15644  progress: function progress(cell, onRendered, success, cancel, editorParams) {
15645  var element = cell.getElement(),
15646  max = typeof editorParams.max === "undefined" ? element.getElementsByTagName("div")[0].getAttribute("max") || 100 : editorParams.max,
15647  min = typeof editorParams.min === "undefined" ? element.getElementsByTagName("div")[0].getAttribute("min") || 0 : editorParams.min,
15648  percent = (max - min) / 100,
15649  value = cell.getValue() || 0,
15650  handle = document.createElement("div"),
15651  bar = document.createElement("div"),
15652  mouseDrag,
15653  mouseDragWidth;
15654 
15655  //set new value
15656  function updateValue() {
15657  var calcVal = percent * Math.round(bar.offsetWidth / (element.clientWidth / 100)) + min;
15658  success(calcVal);
15659  element.setAttribute("aria-valuenow", calcVal);
15660  element.setAttribute("aria-label", value);
15661  }
15662 
15663  //style handle
15664  handle.style.position = "absolute";
15665  handle.style.right = "0";
15666  handle.style.top = "0";
15667  handle.style.bottom = "0";
15668  handle.style.width = "5px";
15669  handle.classList.add("tabulator-progress-handle");
15670 
15671  //style bar
15672  bar.style.display = "inline-block";
15673  bar.style.position = "relative";
15674  // bar.style.top = "8px";
15675  // bar.style.bottom = "8px";
15676  // bar.style.left = "4px";
15677  // bar.style.marginRight = "4px";
15678  bar.style.height = "100%";
15679  bar.style.backgroundColor = "#488CE9";
15680  bar.style.maxWidth = "100%";
15681  bar.style.minWidth = "0%";
15682 
15683  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
15684  for (var key in editorParams.elementAttributes) {
15685  if (key.charAt(0) == "+") {
15686  key = key.slice(1);
15687  bar.setAttribute(key, bar.getAttribute(key) + editorParams.elementAttributes["+" + key]);
15688  } else {
15689  bar.setAttribute(key, editorParams.elementAttributes[key]);
15690  }
15691  }
15692  }
15693 
15694  //style cell
15695  element.style.padding = "4px 4px";
15696 
15697  //make sure value is in range
15698  value = Math.min(parseFloat(value), max);
15699  value = Math.max(parseFloat(value), min);
15700 
15701  //workout percentage
15702  value = Math.round((value - min) / percent);
15703  // bar.style.right = value + "%";
15704  bar.style.width = value + "%";
15705 
15706  element.setAttribute("aria-valuemin", min);
15707  element.setAttribute("aria-valuemax", max);
15708 
15709  bar.appendChild(handle);
15710 
15711  handle.addEventListener("mousedown", function (e) {
15712  mouseDrag = e.screenX;
15713  mouseDragWidth = bar.offsetWidth;
15714  });
15715 
15716  handle.addEventListener("mouseover", function () {
15717  handle.style.cursor = "ew-resize";
15718  });
15719 
15720  element.addEventListener("mousemove", function (e) {
15721  if (mouseDrag) {
15722  bar.style.width = mouseDragWidth + e.screenX - mouseDrag + "px";
15723  }
15724  });
15725 
15726  element.addEventListener("mouseup", function (e) {
15727  if (mouseDrag) {
15728  e.stopPropagation();
15729  e.stopImmediatePropagation();
15730 
15731  mouseDrag = false;
15732  mouseDragWidth = false;
15733 
15734  updateValue();
15735  }
15736  });
15737 
15738  //allow key based navigation
15739  element.addEventListener("keydown", function (e) {
15740  switch (e.keyCode) {
15741  case 39:
15742  //right arrow
15743  bar.style.width = bar.clientWidth + element.clientWidth / 100 + "px";
15744  break;
15745 
15746  case 37:
15747  //left arrow
15748  bar.style.width = bar.clientWidth - element.clientWidth / 100 + "px";
15749  break;
15750 
15751  case 13:
15752  //enter
15753  updateValue();
15754  break;
15755 
15756  case 27:
15757  //escape
15758  cancel();
15759  break;
15760 
15761  }
15762  });
15763 
15764  element.addEventListener("blur", function () {
15765  cancel();
15766  });
15767 
15768  return bar;
15769  },
15770 
15771  //checkbox
15772  tickCross: function tickCross(cell, onRendered, success, cancel, editorParams) {
15773  var value = cell.getValue(),
15774  input = document.createElement("input"),
15775  tristate = editorParams.tristate,
15776  indetermValue = typeof editorParams.indeterminateValue === "undefined" ? null : editorParams.indeterminateValue,
15777  indetermState = false;
15778 
15779  input.setAttribute("type", "checkbox");
15780  input.style.marginTop = "5px";
15781  input.style.boxSizing = "border-box";
15782 
15783  if (editorParams.elementAttributes && _typeof(editorParams.elementAttributes) == "object") {
15784  for (var key in editorParams.elementAttributes) {
15785  if (key.charAt(0) == "+") {
15786  key = key.slice(1);
15787  input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
15788  } else {
15789  input.setAttribute(key, editorParams.elementAttributes[key]);
15790  }
15791  }
15792  }
15793 
15794  input.value = value;
15795 
15796  if (tristate && (typeof value === "undefined" || value === indetermValue || value === "")) {
15797  indetermState = true;
15798  input.indeterminate = true;
15799  }
15800 
15801  if (this.table.browser != "firefox") {
15802  //prevent blur issue on mac firefox
15803  onRendered(function () {
15804  input.focus();
15805  });
15806  }
15807 
15808  input.checked = value === true || value === "true" || value === "True" || value === 1;
15809 
15810  function setValue(blur) {
15811  if (tristate) {
15812  if (!blur) {
15813  if (input.checked && !indetermState) {
15814  input.checked = false;
15815  input.indeterminate = true;
15816  indetermState = true;
15817  return indetermValue;
15818  } else {
15819  indetermState = false;
15820  return input.checked;
15821  }
15822  } else {
15823  if (indetermState) {
15824  return indetermValue;
15825  } else {
15826  return input.checked;
15827  }
15828  }
15829  } else {
15830  return input.checked;
15831  }
15832  }
15833 
15834  //submit new value on blur
15835  input.addEventListener("change", function (e) {
15836  success(setValue());
15837  });
15838 
15839  input.addEventListener("blur", function (e) {
15840  success(setValue(true));
15841  });
15842 
15843  //submit new value on enter
15844  input.addEventListener("keydown", function (e) {
15845  if (e.keyCode == 13) {
15846  success(setValue());
15847  }
15848  if (e.keyCode == 27) {
15849  cancel();
15850  }
15851  });
15852 
15853  return input;
15854  }
15855  };
15856 
15857  Tabulator.prototype.registerModule("edit", Edit);
15858 
15859  var Filter = function Filter(table) {
15860 
15861  this.table = table; //hold Tabulator object
15862 
15863  this.filterList = []; //hold filter list
15864  this.headerFilters = {}; //hold column filters
15865  this.headerFilterColumns = []; //hold columns that use header filters
15866 
15867  this.changed = false; //has filtering changed since last render
15868  };
15869 
15870  //initialize column header filter
15871  Filter.prototype.initializeColumn = function (column, value) {
15872  var self = this,
15873  field = column.getField(),
15874  params;
15875 
15876  //handle successfull value change
15877  function success(value) {
15878  var filterType = column.modules.filter.tagType == "input" && column.modules.filter.attrType == "text" || column.modules.filter.tagType == "textarea" ? "partial" : "match",
15879  type = "",
15880  filterFunc;
15881 
15882  if (typeof column.modules.filter.prevSuccess === "undefined" || column.modules.filter.prevSuccess !== value) {
15883 
15884  column.modules.filter.prevSuccess = value;
15885 
15886  if (!column.modules.filter.emptyFunc(value)) {
15887  column.modules.filter.value = value;
15888 
15889  switch (_typeof(column.definition.headerFilterFunc)) {
15890  case "string":
15891  if (self.filters[column.definition.headerFilterFunc]) {
15892  type = column.definition.headerFilterFunc;
15893  filterFunc = function filterFunc(data) {
15894  var params = column.definition.headerFilterFuncParams || {};
15895  var fieldVal = column.getFieldValue(data);
15896 
15897  params = typeof params === "function" ? params(value, fieldVal, data) : params;
15898 
15899  return self.filters[column.definition.headerFilterFunc](value, fieldVal, data, params);
15900  };
15901  } else {
15902  console.warn("Header Filter Error - Matching filter function not found: ", column.definition.headerFilterFunc);
15903  }
15904  break;
15905 
15906  case "function":
15907  filterFunc = function filterFunc(data) {
15908  var params = column.definition.headerFilterFuncParams || {};
15909  var fieldVal = column.getFieldValue(data);
15910 
15911  params = typeof params === "function" ? params(value, fieldVal, data) : params;
15912 
15913  return column.definition.headerFilterFunc(value, fieldVal, data, params);
15914  };
15915 
15916  type = filterFunc;
15917  break;
15918  }
15919 
15920  if (!filterFunc) {
15921  switch (filterType) {
15922  case "partial":
15923  filterFunc = function filterFunc(data) {
15924  var colVal = column.getFieldValue(data);
15925 
15926  if (typeof colVal !== 'undefined' && colVal !== null) {
15927  return String(colVal).toLowerCase().indexOf(String(value).toLowerCase()) > -1;
15928  } else {
15929  return false;
15930  }
15931  };
15932  type = "like";
15933  break;
15934 
15935  default:
15936  filterFunc = function filterFunc(data) {
15937  return column.getFieldValue(data) == value;
15938  };
15939  type = "=";
15940  }
15941  }
15942 
15943  self.headerFilters[field] = { value: value, func: filterFunc, type: type };
15944  } else {
15945  delete self.headerFilters[field];
15946  }
15947 
15948  self.changed = true;
15949 
15950  self.table.rowManager.filterRefresh();
15951  }
15952 
15953  return true;
15954  }
15955 
15956  column.modules.filter = {
15957  success: success,
15958  attrType: false,
15959  tagType: false,
15960  emptyFunc: false
15961  };
15962 
15963  this.generateHeaderFilterElement(column);
15964  };
15965 
15966  Filter.prototype.generateHeaderFilterElement = function (column, initialValue, reinitialize) {
15967  var _this46 = this;
15968 
15969  var self = this,
15970  success = column.modules.filter.success,
15971  field = column.getField(),
15972  filterElement,
15973  editor,
15974  editorElement,
15975  cellWrapper,
15976  typingTimer,
15977  searchTrigger,
15978  params;
15979 
15980  //handle aborted edit
15981  function cancel() {}
15982 
15983  if (column.modules.filter.headerElement && column.modules.filter.headerElement.parentNode) {
15984  column.contentElement.removeChild(column.modules.filter.headerElement.parentNode);
15985  }
15986 
15987  if (field) {
15988 
15989  //set empty value function
15990  column.modules.filter.emptyFunc = column.definition.headerFilterEmptyCheck || function (value) {
15991  return !value && value !== "0";
15992  };
15993 
15994  filterElement = document.createElement("div");
15995  filterElement.classList.add("tabulator-header-filter");
15996 
15997  //set column editor
15998  switch (_typeof(column.definition.headerFilter)) {
15999  case "string":
16000  if (self.table.modules.edit.editors[column.definition.headerFilter]) {
16001  editor = self.table.modules.edit.editors[column.definition.headerFilter];
16002 
16003  if ((column.definition.headerFilter === "tick" || column.definition.headerFilter === "tickCross") && !column.definition.headerFilterEmptyCheck) {
16004  column.modules.filter.emptyFunc = function (value) {
16005  return value !== true && value !== false;
16006  };
16007  }
16008  } else {
16009  console.warn("Filter Error - Cannot build header filter, No such editor found: ", column.definition.editor);
16010  }
16011  break;
16012 
16013  case "function":
16014  editor = column.definition.headerFilter;
16015  break;
16016 
16017  case "boolean":
16018  if (column.modules.edit && column.modules.edit.editor) {
16019  editor = column.modules.edit.editor;
16020  } else {
16021  if (column.definition.formatter && self.table.modules.edit.editors[column.definition.formatter]) {
16022  editor = self.table.modules.edit.editors[column.definition.formatter];
16023 
16024  if ((column.definition.formatter === "tick" || column.definition.formatter === "tickCross") && !column.definition.headerFilterEmptyCheck) {
16025  column.modules.filter.emptyFunc = function (value) {
16026  return value !== true && value !== false;
16027  };
16028  }
16029  } else {
16030  editor = self.table.modules.edit.editors["input"];
16031  }
16032  }
16033  break;
16034  }
16035 
16036  if (editor) {
16037 
16038  cellWrapper = {
16039  getValue: function getValue() {
16040  return typeof initialValue !== "undefined" ? initialValue : "";
16041  },
16042  getField: function getField() {
16043  return column.definition.field;
16044  },
16045  getElement: function getElement() {
16046  return filterElement;
16047  },
16048  getColumn: function getColumn() {
16049  return column.getComponent();
16050  },
16051  getRow: function getRow() {
16052  return {
16053  normalizeHeight: function normalizeHeight() {}
16054  };
16055  }
16056  };
16057 
16058  params = column.definition.headerFilterParams || {};
16059 
16060  params = typeof params === "function" ? params.call(self.table) : params;
16061 
16062  editorElement = editor.call(this.table.modules.edit, cellWrapper, function () {}, success, cancel, params);
16063 
16064  if (!editorElement) {
16065  console.warn("Filter Error - Cannot add filter to " + field + " column, editor returned a value of false");
16066  return;
16067  }
16068 
16069  if (!(editorElement instanceof Node)) {
16070  console.warn("Filter Error - Cannot add filter to " + field + " column, editor should return an instance of Node, the editor returned:", editorElement);
16071  return;
16072  }
16073 
16074  //set Placeholder Text
16075  if (field) {
16076  self.table.modules.localize.bind("headerFilters|columns|" + column.definition.field, function (value) {
16077  editorElement.setAttribute("placeholder", typeof value !== "undefined" && value ? value : self.table.modules.localize.getText("headerFilters|default"));
16078  });
16079  } else {
16080  self.table.modules.localize.bind("headerFilters|default", function (value) {
16081  editorElement.setAttribute("placeholder", typeof self.column.definition.headerFilterPlaceholder !== "undefined" && self.column.definition.headerFilterPlaceholder ? self.column.definition.headerFilterPlaceholder : value);
16082  });
16083  }
16084 
16085  //focus on element on click
16086  editorElement.addEventListener("click", function (e) {
16087  e.stopPropagation();
16088  editorElement.focus();
16089  });
16090 
16091  editorElement.addEventListener("focus", function (e) {
16092  var left = _this46.table.columnManager.element.scrollLeft;
16093 
16094  if (left !== _this46.table.rowManager.element.scrollLeft) {
16095  _this46.table.rowManager.scrollHorizontal(left);
16096  _this46.table.columnManager.scrollHorizontal(left);
16097  }
16098  });
16099 
16100  //live update filters as user types
16101  typingTimer = false;
16102 
16103  searchTrigger = function searchTrigger(e) {
16104  if (typingTimer) {
16105  clearTimeout(typingTimer);
16106  }
16107 
16108  typingTimer = setTimeout(function () {
16109  success(editorElement.value);
16110  }, 300);
16111  };
16112 
16113  column.modules.filter.headerElement = editorElement;
16114  column.modules.filter.attrType = editorElement.hasAttribute("type") ? editorElement.getAttribute("type").toLowerCase() : "";
16115  column.modules.filter.tagType = editorElement.tagName.toLowerCase();
16116 
16117  if (column.definition.headerFilterLiveFilter !== false) {
16118 
16119  if (!(column.definition.headerFilter === 'autocomplete' || column.definition.headerFilter === 'tickCross' || (column.definition.editor === 'autocomplete' || column.definition.editor === 'tickCross') && column.definition.headerFilter === true)) {
16120  editorElement.addEventListener("keyup", searchTrigger);
16121  editorElement.addEventListener("search", searchTrigger);
16122 
16123  //update number filtered columns on change
16124  if (column.modules.filter.attrType == "number") {
16125  editorElement.addEventListener("change", function (e) {
16126  success(editorElement.value);
16127  });
16128  }
16129 
16130  //change text inputs to search inputs to allow for clearing of field
16131  if (column.modules.filter.attrType == "text" && this.table.browser !== "ie") {
16132  editorElement.setAttribute("type", "search");
16133  // editorElement.off("change blur"); //prevent blur from triggering filter and preventing selection click
16134  }
16135  }
16136 
16137  //prevent input and select elements from propegating click to column sorters etc
16138  if (column.modules.filter.tagType == "input" || column.modules.filter.tagType == "select" || column.modules.filter.tagType == "textarea") {
16139  editorElement.addEventListener("mousedown", function (e) {
16140  e.stopPropagation();
16141  });
16142  }
16143  }
16144 
16145  filterElement.appendChild(editorElement);
16146 
16147  column.contentElement.appendChild(filterElement);
16148 
16149  if (!reinitialize) {
16150  self.headerFilterColumns.push(column);
16151  }
16152  }
16153  } else {
16154  console.warn("Filter Error - Cannot add header filter, column has no field set:", column.definition.title);
16155  }
16156  };
16157 
16158  //hide all header filter elements (used to ensure correct column widths in "fitData" layout mode)
16159  Filter.prototype.hideHeaderFilterElements = function () {
16160  this.headerFilterColumns.forEach(function (column) {
16161  if (column.modules.filter && column.modules.filter.headerElement) {
16162  column.modules.filter.headerElement.style.display = 'none';
16163  }
16164  });
16165  };
16166 
16167  //show all header filter elements (used to ensure correct column widths in "fitData" layout mode)
16168  Filter.prototype.showHeaderFilterElements = function () {
16169  this.headerFilterColumns.forEach(function (column) {
16170  if (column.modules.filter && column.modules.filter.headerElement) {
16171  column.modules.filter.headerElement.style.display = '';
16172  }
16173  });
16174  };
16175 
16176  //programatically set value of header filter
16177  Filter.prototype.setHeaderFilterFocus = function (column) {
16178  if (column.modules.filter && column.modules.filter.headerElement) {
16179  column.modules.filter.headerElement.focus();
16180  } else {
16181  console.warn("Column Filter Focus Error - No header filter set on column:", column.getField());
16182  }
16183  };
16184 
16185  //programatically set value of header filter
16186  Filter.prototype.setHeaderFilterValue = function (column, value) {
16187  if (column) {
16188  if (column.modules.filter && column.modules.filter.headerElement) {
16189  this.generateHeaderFilterElement(column, value, true);
16190  column.modules.filter.success(value);
16191  } else {
16192  console.warn("Column Filter Error - No header filter set on column:", column.getField());
16193  }
16194  }
16195  };
16196 
16197  Filter.prototype.reloadHeaderFilter = function (column) {
16198  if (column) {
16199  if (column.modules.filter && column.modules.filter.headerElement) {
16200  this.generateHeaderFilterElement(column, column.modules.filter.value, true);
16201  } else {
16202  console.warn("Column Filter Error - No header filter set on column:", column.getField());
16203  }
16204  }
16205  };
16206 
16207  //check if the filters has changed since last use
16208  Filter.prototype.hasChanged = function () {
16209  var changed = this.changed;
16210  this.changed = false;
16211  return changed;
16212  };
16213 
16214  //set standard filters
16215  Filter.prototype.setFilter = function (field, type, value) {
16216  var self = this;
16217 
16218  self.filterList = [];
16219 
16220  if (!Array.isArray(field)) {
16221  field = [{ field: field, type: type, value: value }];
16222  }
16223 
16224  self.addFilter(field);
16225  };
16226 
16227  //add filter to array
16228  Filter.prototype.addFilter = function (field, type, value) {
16229  var self = this;
16230 
16231  if (!Array.isArray(field)) {
16232  field = [{ field: field, type: type, value: value }];
16233  }
16234 
16235  field.forEach(function (filter) {
16236 
16237  filter = self.findFilter(filter);
16238 
16239  if (filter) {
16240  self.filterList.push(filter);
16241 
16242  self.changed = true;
16243  }
16244  });
16245 
16246  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.filter) {
16247  this.table.modules.persistence.save("filter");
16248  }
16249  };
16250 
16251  Filter.prototype.findFilter = function (filter) {
16252  var self = this,
16253  column;
16254 
16255  if (Array.isArray(filter)) {
16256  return this.findSubFilters(filter);
16257  }
16258 
16259  var filterFunc = false;
16260 
16261  if (typeof filter.field == "function") {
16262  filterFunc = function filterFunc(data) {
16263  return filter.field(data, filter.type || {}); // pass params to custom filter function
16264  };
16265  } else {
16266 
16267  if (self.filters[filter.type]) {
16268 
16269  column = self.table.columnManager.getColumnByField(filter.field);
16270 
16271  if (column) {
16272  filterFunc = function filterFunc(data) {
16273  return self.filters[filter.type](filter.value, column.getFieldValue(data));
16274  };
16275  } else {
16276  filterFunc = function filterFunc(data) {
16277  return self.filters[filter.type](filter.value, data[filter.field]);
16278  };
16279  }
16280  } else {
16281  console.warn("Filter Error - No such filter type found, ignoring: ", filter.type);
16282  }
16283  }
16284 
16285  filter.func = filterFunc;
16286 
16287  return filter.func ? filter : false;
16288  };
16289 
16290  Filter.prototype.findSubFilters = function (filters) {
16291  var self = this,
16292  output = [];
16293 
16294  filters.forEach(function (filter) {
16295  filter = self.findFilter(filter);
16296 
16297  if (filter) {
16298  output.push(filter);
16299  }
16300  });
16301 
16302  return output.length ? output : false;
16303  };
16304 
16305  //get all filters
16306  Filter.prototype.getFilters = function (all, ajax) {
16307  var output = [];
16308 
16309  if (all) {
16310  output = this.getHeaderFilters();
16311  }
16312 
16313  if (ajax) {
16314  output.forEach(function (item) {
16315  if (typeof item.type == "function") {
16316  item.type = "function";
16317  }
16318  });
16319  }
16320 
16321  output = output.concat(this.filtersToArray(this.filterList, ajax));
16322 
16323  return output;
16324  };
16325 
16326  //filter to Object
16327  Filter.prototype.filtersToArray = function (filterList, ajax) {
16328  var _this47 = this;
16329 
16330  var output = [];
16331 
16332  filterList.forEach(function (filter) {
16333  var item;
16334 
16335  if (Array.isArray(filter)) {
16336  output.push(_this47.filtersToArray(filter, ajax));
16337  } else {
16338  item = { field: filter.field, type: filter.type, value: filter.value };
16339 
16340  if (ajax) {
16341  if (typeof item.type == "function") {
16342  item.type = "function";
16343  }
16344  }
16345 
16346  output.push(item);
16347  }
16348  });
16349 
16350  return output;
16351  };
16352 
16353  //get all filters
16354  Filter.prototype.getHeaderFilters = function () {
16355  var self = this,
16356  output = [];
16357 
16358  for (var key in this.headerFilters) {
16359  output.push({ field: key, type: this.headerFilters[key].type, value: this.headerFilters[key].value });
16360  }
16361 
16362  return output;
16363  };
16364 
16365  //remove filter from array
16366  Filter.prototype.removeFilter = function (field, type, value) {
16367  var self = this;
16368 
16369  if (!Array.isArray(field)) {
16370  field = [{ field: field, type: type, value: value }];
16371  }
16372 
16373  field.forEach(function (filter) {
16374  var index = -1;
16375 
16376  if (_typeof(filter.field) == "object") {
16377  index = self.filterList.findIndex(function (element) {
16378  return filter === element;
16379  });
16380  } else {
16381  index = self.filterList.findIndex(function (element) {
16382  return filter.field === element.field && filter.type === element.type && filter.value === element.value;
16383  });
16384  }
16385 
16386  if (index > -1) {
16387  self.filterList.splice(index, 1);
16388  self.changed = true;
16389  } else {
16390  console.warn("Filter Error - No matching filter type found, ignoring: ", filter.type);
16391  }
16392  });
16393 
16394  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.filter) {
16395  this.table.modules.persistence.save("filter");
16396  }
16397  };
16398 
16399  //clear filters
16400  Filter.prototype.clearFilter = function (all) {
16401  this.filterList = [];
16402 
16403  if (all) {
16404  this.clearHeaderFilter();
16405  }
16406 
16407  this.changed = true;
16408 
16409  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.filter) {
16410  this.table.modules.persistence.save("filter");
16411  }
16412  };
16413 
16414  //clear header filters
16415  Filter.prototype.clearHeaderFilter = function () {
16416  var self = this;
16417 
16418  this.headerFilters = {};
16419 
16420  this.headerFilterColumns.forEach(function (column) {
16421  column.modules.filter.value = null;
16422  column.modules.filter.prevSuccess = undefined;
16423  self.reloadHeaderFilter(column);
16424  });
16425 
16426  this.changed = true;
16427  };
16428 
16429  //search data and return matching rows
16430  Filter.prototype.search = function (searchType, field, type, value) {
16431  var self = this,
16432  activeRows = [],
16433  filterList = [];
16434 
16435  if (!Array.isArray(field)) {
16436  field = [{ field: field, type: type, value: value }];
16437  }
16438 
16439  field.forEach(function (filter) {
16440  filter = self.findFilter(filter);
16441 
16442  if (filter) {
16443  filterList.push(filter);
16444  }
16445  });
16446 
16447  this.table.rowManager.rows.forEach(function (row) {
16448  var match = true;
16449 
16450  filterList.forEach(function (filter) {
16451  if (!self.filterRecurse(filter, row.getData())) {
16452  match = false;
16453  }
16454  });
16455 
16456  if (match) {
16457  activeRows.push(searchType === "data" ? row.getData("data") : row.getComponent());
16458  }
16459  });
16460 
16461  return activeRows;
16462  };
16463 
16464  //filter row array
16465  Filter.prototype.filter = function (rowList, filters) {
16466  var self = this,
16467  activeRows = [],
16468  activeRowComponents = [];
16469 
16470  if (self.table.options.dataFiltering) {
16471  self.table.options.dataFiltering.call(self.table, self.getFilters());
16472  }
16473 
16474  if (!self.table.options.ajaxFiltering && (self.filterList.length || Object.keys(self.headerFilters).length)) {
16475 
16476  rowList.forEach(function (row) {
16477  if (self.filterRow(row)) {
16478  activeRows.push(row);
16479  }
16480  });
16481  } else {
16482  activeRows = rowList.slice(0);
16483  }
16484 
16485  if (self.table.options.dataFiltered) {
16486 
16487  activeRows.forEach(function (row) {
16488  activeRowComponents.push(row.getComponent());
16489  });
16490 
16491  self.table.options.dataFiltered.call(self.table, self.getFilters(), activeRowComponents);
16492  }
16493 
16494  return activeRows;
16495  };
16496 
16497  //filter individual row
16498  Filter.prototype.filterRow = function (row, filters) {
16499  var self = this,
16500  match = true,
16501  data = row.getData();
16502 
16503  self.filterList.forEach(function (filter) {
16504  if (!self.filterRecurse(filter, data)) {
16505  match = false;
16506  }
16507  });
16508 
16509  for (var field in self.headerFilters) {
16510  if (!self.headerFilters[field].func(data)) {
16511  match = false;
16512  }
16513  }
16514 
16515  return match;
16516  };
16517 
16518  Filter.prototype.filterRecurse = function (filter, data) {
16519  var self = this,
16520  match = false;
16521 
16522  if (Array.isArray(filter)) {
16523  filter.forEach(function (subFilter) {
16524  if (self.filterRecurse(subFilter, data)) {
16525  match = true;
16526  }
16527  });
16528  } else {
16529  match = filter.func(data);
16530  }
16531 
16532  return match;
16533  };
16534 
16535  //list of available filters
16536  Filter.prototype.filters = {
16537 
16538  //equal to
16539  "=": function _(filterVal, rowVal, rowData, filterParams) {
16540  return rowVal == filterVal ? true : false;
16541  },
16542 
16543  //less than
16544  "<": function _(filterVal, rowVal, rowData, filterParams) {
16545  return rowVal < filterVal ? true : false;
16546  },
16547 
16548  //less than or equal to
16549  "<=": function _(filterVal, rowVal, rowData, filterParams) {
16550  return rowVal <= filterVal ? true : false;
16551  },
16552 
16553  //greater than
16554  ">": function _(filterVal, rowVal, rowData, filterParams) {
16555  return rowVal > filterVal ? true : false;
16556  },
16557 
16558  //greater than or equal to
16559  ">=": function _(filterVal, rowVal, rowData, filterParams) {
16560  return rowVal >= filterVal ? true : false;
16561  },
16562 
16563  //not equal to
16564  "!=": function _(filterVal, rowVal, rowData, filterParams) {
16565  return rowVal != filterVal ? true : false;
16566  },
16567 
16568  "regex": function regex(filterVal, rowVal, rowData, filterParams) {
16569 
16570  if (typeof filterVal == "string") {
16571  filterVal = new RegExp(filterVal);
16572  }
16573 
16574  return filterVal.test(rowVal);
16575  },
16576 
16577  //contains the string
16578  "like": function like(filterVal, rowVal, rowData, filterParams) {
16579  if (filterVal === null || typeof filterVal === "undefined") {
16580  return rowVal === filterVal ? true : false;
16581  } else {
16582  if (typeof rowVal !== 'undefined' && rowVal !== null) {
16583  return String(rowVal).toLowerCase().indexOf(filterVal.toLowerCase()) > -1;
16584  } else {
16585  return false;
16586  }
16587  }
16588  },
16589 
16590  //in array
16591  "in": function _in(filterVal, rowVal, rowData, filterParams) {
16592  if (Array.isArray(filterVal)) {
16593  return filterVal.indexOf(rowVal) > -1;
16594  } else {
16595  console.warn("Filter Error - filter value is not an array:", filterVal);
16596  return false;
16597  }
16598  }
16599  };
16600 
16601  Tabulator.prototype.registerModule("filter", Filter);
16602  var Format = function Format(table) {
16603  this.table = table; //hold Tabulator object
16604  };
16605 
16606  //initialize column formatter
16607  Format.prototype.initializeColumn = function (column) {
16608  var self = this,
16609  config = { params: column.definition.formatterParams || {} };
16610 
16611  //set column formatter
16612  switch (_typeof(column.definition.formatter)) {
16613  case "string":
16614 
16615  if (column.definition.formatter === "tick") {
16616  column.definition.formatter = "tickCross";
16617 
16618  if (typeof config.params.crossElement == "undefined") {
16619  config.params.crossElement = false;
16620  }
16621 
16622  console.warn("DEPRECATION WARNING - the tick formatter has been deprecated, please use the tickCross formatter with the crossElement param set to false");
16623  }
16624 
16625  if (self.formatters[column.definition.formatter]) {
16626  config.formatter = self.formatters[column.definition.formatter];
16627  } else {
16628  console.warn("Formatter Error - No such formatter found: ", column.definition.formatter);
16629  config.formatter = self.formatters.plaintext;
16630  }
16631  break;
16632 
16633  case "function":
16634  config.formatter = column.definition.formatter;
16635  break;
16636 
16637  default:
16638  config.formatter = self.formatters.plaintext;
16639  break;
16640  }
16641 
16642  column.modules.format = config;
16643  };
16644 
16645  Format.prototype.cellRendered = function (cell) {
16646  if (cell.modules.format && cell.modules.format.renderedCallback) {
16647  cell.modules.format.renderedCallback();
16648  }
16649  };
16650 
16651  //return a formatted value for a cell
16652  Format.prototype.formatValue = function (cell) {
16653  var component = cell.getComponent(),
16654  params = typeof cell.column.modules.format.params === "function" ? cell.column.modules.format.params(component) : cell.column.modules.format.params;
16655 
16656  function onRendered(callback) {
16657  if (!cell.modules.format) {
16658  cell.modules.format = {};
16659  }
16660 
16661  cell.modules.format.renderedCallback = callback;
16662  }
16663 
16664  return cell.column.modules.format.formatter.call(this, component, params, onRendered);
16665  };
16666 
16667  Format.prototype.sanitizeHTML = function (value) {
16668  if (value) {
16669  var entityMap = {
16670  '&': '&amp;',
16671  '<': '&lt;',
16672  '>': '&gt;',
16673  '"': '&quot;',
16674  "'": '&#39;',
16675  '/': '&#x2F;',
16676  '`': '&#x60;',
16677  '=': '&#x3D;'
16678  };
16679 
16680  return String(value).replace(/[&<>"'`=\/]/g, function (s) {
16681  return entityMap[s];
16682  });
16683  } else {
16684  return value;
16685  }
16686  };
16687 
16688  Format.prototype.emptyToSpace = function (value) {
16689  return value === null || typeof value === "undefined" ? "&nbsp;" : value;
16690  };
16691 
16692  //get formatter for cell
16693  Format.prototype.getFormatter = function (formatter) {
16694  var formatter;
16695 
16696  switch (typeof formatter === 'undefined' ? 'undefined' : _typeof(formatter)) {
16697  case "string":
16698  if (this.formatters[formatter]) {
16699  formatter = this.formatters[formatter];
16700  } else {
16701  console.warn("Formatter Error - No such formatter found: ", formatter);
16702  formatter = this.formatters.plaintext;
16703  }
16704  break;
16705 
16706  case "function":
16707  formatter = formatter;
16708  break;
16709 
16710  default:
16711  formatter = this.formatters.plaintext;
16712  break;
16713  }
16714 
16715  return formatter;
16716  };
16717 
16718  //default data formatters
16719  Format.prototype.formatters = {
16720  //plain text value
16721  plaintext: function plaintext(cell, formatterParams, onRendered) {
16722  return this.emptyToSpace(this.sanitizeHTML(cell.getValue()));
16723  },
16724 
16725  //html text value
16726  html: function html(cell, formatterParams, onRendered) {
16727  return cell.getValue();
16728  },
16729 
16730  //multiline text area
16731  textarea: function textarea(cell, formatterParams, onRendered) {
16732  cell.getElement().style.whiteSpace = "pre-wrap";
16733  return this.emptyToSpace(this.sanitizeHTML(cell.getValue()));
16734  },
16735 
16736  //currency formatting
16737  money: function money(cell, formatterParams, onRendered) {
16738  var floatVal = parseFloat(cell.getValue()),
16739  number,
16740  integer,
16741  decimal,
16742  rgx;
16743 
16744  var decimalSym = formatterParams.decimal || ".";
16745  var thousandSym = formatterParams.thousand || ",";
16746  var symbol = formatterParams.symbol || "";
16747  var after = !!formatterParams.symbolAfter;
16748  var precision = typeof formatterParams.precision !== "undefined" ? formatterParams.precision : 2;
16749 
16750  if (isNaN(floatVal)) {
16751  return this.emptyToSpace(this.sanitizeHTML(cell.getValue()));
16752  }
16753 
16754  number = precision !== false ? floatVal.toFixed(precision) : floatVal;
16755  number = String(number).split(".");
16756 
16757  integer = number[0];
16758  decimal = number.length > 1 ? decimalSym + number[1] : "";
16759 
16760  rgx = /(\d+)(\d{3})/;
16761 
16762  while (rgx.test(integer)) {
16763  integer = integer.replace(rgx, "$1" + thousandSym + "$2");
16764  }
16765 
16766  return after ? integer + decimal + symbol : symbol + integer + decimal;
16767  },
16768 
16769  //clickable anchor tag
16770  link: function link(cell, formatterParams, onRendered) {
16771  var value = cell.getValue(),
16772  urlPrefix = formatterParams.urlPrefix || "",
16773  download = formatterParams.download,
16774  label = value,
16775  el = document.createElement("a"),
16776  data;
16777 
16778  if (formatterParams.labelField) {
16779  data = cell.getData();
16780  label = data[formatterParams.labelField];
16781  }
16782 
16783  if (formatterParams.label) {
16784  switch (_typeof(formatterParams.label)) {
16785  case "string":
16786  label = formatterParams.label;
16787  break;
16788 
16789  case "function":
16790  label = formatterParams.label(cell);
16791  break;
16792  }
16793  }
16794 
16795  if (label) {
16796  if (formatterParams.urlField) {
16797  data = cell.getData();
16798  value = data[formatterParams.urlField];
16799  }
16800 
16801  if (formatterParams.url) {
16802  switch (_typeof(formatterParams.url)) {
16803  case "string":
16804  value = formatterParams.url;
16805  break;
16806 
16807  case "function":
16808  value = formatterParams.url(cell);
16809  break;
16810  }
16811  }
16812 
16813  el.setAttribute("href", urlPrefix + value);
16814 
16815  if (formatterParams.target) {
16816  el.setAttribute("target", formatterParams.target);
16817  }
16818 
16819  if (formatterParams.download) {
16820 
16821  if (typeof download == "function") {
16822  download = download(cell);
16823  } else {
16824  download = download === true ? "" : download;
16825  }
16826 
16827  el.setAttribute("download", download);
16828  }
16829 
16830  el.innerHTML = this.emptyToSpace(this.sanitizeHTML(label));
16831 
16832  return el;
16833  } else {
16834  return "&nbsp;";
16835  }
16836  },
16837 
16838  //image element
16839  image: function image(cell, formatterParams, onRendered) {
16840  var el = document.createElement("img");
16841  el.setAttribute("src", cell.getValue());
16842 
16843  switch (_typeof(formatterParams.height)) {
16844  case "number":
16845  el.style.height = formatterParams.height + "px";
16846  break;
16847 
16848  case "string":
16849  el.style.height = formatterParams.height;
16850  break;
16851  }
16852 
16853  switch (_typeof(formatterParams.width)) {
16854  case "number":
16855  el.style.width = formatterParams.width + "px";
16856  break;
16857 
16858  case "string":
16859  el.style.width = formatterParams.width;
16860  break;
16861  }
16862 
16863  el.addEventListener("load", function () {
16864  cell.getRow().normalizeHeight();
16865  });
16866 
16867  return el;
16868  },
16869 
16870  //tick or cross
16871  tickCross: function tickCross(cell, formatterParams, onRendered) {
16872  var value = cell.getValue(),
16873  element = cell.getElement(),
16874  empty = formatterParams.allowEmpty,
16875  truthy = formatterParams.allowTruthy,
16876  tick = typeof formatterParams.tickElement !== "undefined" ? formatterParams.tickElement : '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#2DC214" clip-rule="evenodd" d="M21.652,3.211c-0.293-0.295-0.77-0.295-1.061,0L9.41,14.34 c-0.293,0.297-0.771,0.297-1.062,0L3.449,9.351C3.304,9.203,3.114,9.13,2.923,9.129C2.73,9.128,2.534,9.201,2.387,9.351 l-2.165,1.946C0.078,11.445,0,11.63,0,11.823c0,0.194,0.078,0.397,0.223,0.544l4.94,5.184c0.292,0.296,0.771,0.776,1.062,1.07 l2.124,2.141c0.292,0.293,0.769,0.293,1.062,0l14.366-14.34c0.293-0.294,0.293-0.777,0-1.071L21.652,3.211z" fill-rule="evenodd"/></svg>',
16877  cross = typeof formatterParams.crossElement !== "undefined" ? formatterParams.crossElement : '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#CE1515" d="M22.245,4.015c0.313,0.313,0.313,0.826,0,1.139l-6.276,6.27c-0.313,0.312-0.313,0.826,0,1.14l6.273,6.272 c0.313,0.313,0.313,0.826,0,1.14l-2.285,2.277c-0.314,0.312-0.828,0.312-1.142,0l-6.271-6.271c-0.313-0.313-0.828-0.313-1.141,0 l-6.276,6.267c-0.313,0.313-0.828,0.313-1.141,0l-2.282-2.28c-0.313-0.313-0.313-0.826,0-1.14l6.278-6.269 c0.313-0.312,0.313-0.826,0-1.14L1.709,5.147c-0.314-0.313-0.314-0.827,0-1.14l2.284-2.278C4.308,1.417,4.821,1.417,5.135,1.73 L11.405,8c0.314,0.314,0.828,0.314,1.141,0.001l6.276-6.267c0.312-0.312,0.826-0.312,1.141,0L22.245,4.015z"/></svg>';
16878 
16879  if (truthy && value || value === true || value === "true" || value === "True" || value === 1 || value === "1") {
16880  element.setAttribute("aria-checked", true);
16881  return tick || "";
16882  } else {
16883  if (empty && (value === "null" || value === "" || value === null || typeof value === "undefined")) {
16884  element.setAttribute("aria-checked", "mixed");
16885  return "";
16886  } else {
16887  element.setAttribute("aria-checked", false);
16888  return cross || "";
16889  }
16890  }
16891  },
16892 
16893  datetime: function datetime(cell, formatterParams, onRendered) {
16894  var inputFormat = formatterParams.inputFormat || "YYYY-MM-DD hh:mm:ss";
16895  var outputFormat = formatterParams.outputFormat || "DD/MM/YYYY hh:mm:ss";
16896  var invalid = typeof formatterParams.invalidPlaceholder !== "undefined" ? formatterParams.invalidPlaceholder : "";
16897  var value = cell.getValue();
16898 
16899  var newDatetime = moment(value, inputFormat);
16900 
16901  if (newDatetime.isValid()) {
16902  return newDatetime.format(outputFormat);
16903  } else {
16904 
16905  if (invalid === true) {
16906  return value;
16907  } else if (typeof invalid === "function") {
16908  return invalid(value);
16909  } else {
16910  return invalid;
16911  }
16912  }
16913  },
16914 
16915  datetimediff: function datetime(cell, formatterParams, onRendered) {
16916  var inputFormat = formatterParams.inputFormat || "YYYY-MM-DD hh:mm:ss";
16917  var invalid = typeof formatterParams.invalidPlaceholder !== "undefined" ? formatterParams.invalidPlaceholder : "";
16918  var suffix = typeof formatterParams.suffix !== "undefined" ? formatterParams.suffix : false;
16919  var unit = typeof formatterParams.unit !== "undefined" ? formatterParams.unit : undefined;
16920  var humanize = typeof formatterParams.humanize !== "undefined" ? formatterParams.humanize : false;
16921  var date = typeof formatterParams.date !== "undefined" ? formatterParams.date : moment();
16922  var value = cell.getValue();
16923 
16924  var newDatetime = moment(value, inputFormat);
16925 
16926  if (newDatetime.isValid()) {
16927  if (humanize) {
16928  return moment.duration(newDatetime.diff(date)).humanize(suffix);
16929  } else {
16930  return newDatetime.diff(date, unit) + (suffix ? " " + suffix : "");
16931  }
16932  } else {
16933 
16934  if (invalid === true) {
16935  return value;
16936  } else if (typeof invalid === "function") {
16937  return invalid(value);
16938  } else {
16939  return invalid;
16940  }
16941  }
16942  },
16943 
16944  //select
16945  lookup: function lookup(cell, formatterParams, onRendered) {
16946  var value = cell.getValue();
16947 
16948  if (typeof formatterParams[value] === "undefined") {
16949  console.warn('Missing display value for ' + value);
16950  return value;
16951  }
16952 
16953  return formatterParams[value];
16954  },
16955 
16956  //star rating
16957  star: function star(cell, formatterParams, onRendered) {
16958  var value = cell.getValue(),
16959  element = cell.getElement(),
16960  maxStars = formatterParams && formatterParams.stars ? formatterParams.stars : 5,
16961  stars = document.createElement("span"),
16962  star = document.createElementNS('http://www.w3.org/2000/svg', "svg"),
16963  starActive = '<polygon fill="#FFEA00" stroke="#C1AB60" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>',
16964  starInactive = '<polygon fill="#D2D2D2" stroke="#686868" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
16965 
16966  //style stars holder
16967  stars.style.verticalAlign = "middle";
16968 
16969  //style star
16970  star.setAttribute("width", "14");
16971  star.setAttribute("height", "14");
16972  star.setAttribute("viewBox", "0 0 512 512");
16973  star.setAttribute("xml:space", "preserve");
16974  star.style.padding = "0 1px";
16975 
16976  value = value && !isNaN(value) ? parseInt(value) : 0;
16977 
16978  value = Math.max(0, Math.min(value, maxStars));
16979 
16980  for (var i = 1; i <= maxStars; i++) {
16981  var nextStar = star.cloneNode(true);
16982  nextStar.innerHTML = i <= value ? starActive : starInactive;
16983 
16984  stars.appendChild(nextStar);
16985  }
16986 
16987  element.style.whiteSpace = "nowrap";
16988  element.style.overflow = "hidden";
16989  element.style.textOverflow = "ellipsis";
16990 
16991  element.setAttribute("aria-label", value);
16992 
16993  return stars;
16994  },
16995 
16996  traffic: function traffic(cell, formatterParams, onRendered) {
16997  var value = this.sanitizeHTML(cell.getValue()) || 0,
16998  el = document.createElement("span"),
16999  max = formatterParams && formatterParams.max ? formatterParams.max : 100,
17000  min = formatterParams && formatterParams.min ? formatterParams.min : 0,
17001  colors = formatterParams && typeof formatterParams.color !== "undefined" ? formatterParams.color : ["red", "orange", "green"],
17002  color = "#666666",
17003  percent,
17004  percentValue;
17005 
17006  if (isNaN(value) || typeof cell.getValue() === "undefined") {
17007  return;
17008  }
17009 
17010  el.classList.add("tabulator-traffic-light");
17011 
17012  //make sure value is in range
17013  percentValue = parseFloat(value) <= max ? parseFloat(value) : max;
17014  percentValue = parseFloat(percentValue) >= min ? parseFloat(percentValue) : min;
17015 
17016  //workout percentage
17017  percent = (max - min) / 100;
17018  percentValue = Math.round((percentValue - min) / percent);
17019 
17020  //set color
17021  switch (typeof colors === 'undefined' ? 'undefined' : _typeof(colors)) {
17022  case "string":
17023  color = colors;
17024  break;
17025  case "function":
17026  color = colors(value);
17027  break;
17028  case "object":
17029  if (Array.isArray(colors)) {
17030  var unit = 100 / colors.length;
17031  var index = Math.floor(percentValue / unit);
17032 
17033  index = Math.min(index, colors.length - 1);
17034  index = Math.max(index, 0);
17035  color = colors[index];
17036  break;
17037  }
17038  }
17039 
17040  el.style.backgroundColor = color;
17041 
17042  return el;
17043  },
17044 
17045  //progress bar
17046  progress: function progress(cell, formatterParams, onRendered) {
17047  //progress bar
17048  var value = this.sanitizeHTML(cell.getValue()) || 0,
17049  element = cell.getElement(),
17050  max = formatterParams && formatterParams.max ? formatterParams.max : 100,
17051  min = formatterParams && formatterParams.min ? formatterParams.min : 0,
17052  legendAlign = formatterParams && formatterParams.legendAlign ? formatterParams.legendAlign : "center",
17053  percent,
17054  percentValue,
17055  color,
17056  legend,
17057  legendColor,
17058  top,
17059  left,
17060  right,
17061  bottom;
17062 
17063  //make sure value is in range
17064  percentValue = parseFloat(value) <= max ? parseFloat(value) : max;
17065  percentValue = parseFloat(percentValue) >= min ? parseFloat(percentValue) : min;
17066 
17067  //workout percentage
17068  percent = (max - min) / 100;
17069  percentValue = Math.round((percentValue - min) / percent);
17070 
17071  //set bar color
17072  switch (_typeof(formatterParams.color)) {
17073  case "string":
17074  color = formatterParams.color;
17075  break;
17076  case "function":
17077  color = formatterParams.color(value);
17078  break;
17079  case "object":
17080  if (Array.isArray(formatterParams.color)) {
17081  var unit = 100 / formatterParams.color.length;
17082  var index = Math.floor(percentValue / unit);
17083 
17084  index = Math.min(index, formatterParams.color.length - 1);
17085  index = Math.max(index, 0);
17086  color = formatterParams.color[index];
17087  break;
17088  }
17089  default:
17090  color = "#2DC214";
17091  }
17092 
17093  //generate legend
17094  switch (_typeof(formatterParams.legend)) {
17095  case "string":
17096  legend = formatterParams.legend;
17097  break;
17098  case "function":
17099  legend = formatterParams.legend(value);
17100  break;
17101  case "boolean":
17102  legend = value;
17103  break;
17104  default:
17105  legend = false;
17106  }
17107 
17108  //set legend color
17109  switch (_typeof(formatterParams.legendColor)) {
17110  case "string":
17111  legendColor = formatterParams.legendColor;
17112  break;
17113  case "function":
17114  legendColor = formatterParams.legendColor(value);
17115  break;
17116  case "object":
17117  if (Array.isArray(formatterParams.legendColor)) {
17118  var unit = 100 / formatterParams.legendColor.length;
17119  var index = Math.floor(percentValue / unit);
17120 
17121  index = Math.min(index, formatterParams.legendColor.length - 1);
17122  index = Math.max(index, 0);
17123  legendColor = formatterParams.legendColor[index];
17124  }
17125  break;
17126  default:
17127  legendColor = "#000";
17128  }
17129 
17130  element.style.minWidth = "30px";
17131  element.style.position = "relative";
17132 
17133  element.setAttribute("aria-label", percentValue);
17134 
17135  var barEl = document.createElement("div");
17136  barEl.style.display = "inline-block";
17137  barEl.style.position = "relative";
17138  barEl.style.width = percentValue + "%";
17139  barEl.style.backgroundColor = color;
17140  barEl.style.height = "100%";
17141 
17142  barEl.setAttribute('data-max', max);
17143  barEl.setAttribute('data-min', min);
17144 
17145  if (legend) {
17146  var legendEl = document.createElement("div");
17147  legendEl.style.position = "absolute";
17148  legendEl.style.top = "4px";
17149  legendEl.style.left = 0;
17150  legendEl.style.textAlign = legendAlign;
17151  legendEl.style.width = "100%";
17152  legendEl.style.color = legendColor;
17153  legendEl.innerHTML = legend;
17154  }
17155 
17156  onRendered(function () {
17157  element.appendChild(barEl);
17158 
17159  if (legend) {
17160  element.appendChild(legendEl);
17161  }
17162  });
17163 
17164  return "";
17165  },
17166 
17167  //background color
17168  color: function color(cell, formatterParams, onRendered) {
17169  cell.getElement().style.backgroundColor = this.sanitizeHTML(cell.getValue());
17170  return "";
17171  },
17172 
17173  //tick icon
17174  buttonTick: function buttonTick(cell, formatterParams, onRendered) {
17175  return '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#2DC214" clip-rule="evenodd" d="M21.652,3.211c-0.293-0.295-0.77-0.295-1.061,0L9.41,14.34 c-0.293,0.297-0.771,0.297-1.062,0L3.449,9.351C3.304,9.203,3.114,9.13,2.923,9.129C2.73,9.128,2.534,9.201,2.387,9.351 l-2.165,1.946C0.078,11.445,0,11.63,0,11.823c0,0.194,0.078,0.397,0.223,0.544l4.94,5.184c0.292,0.296,0.771,0.776,1.062,1.07 l2.124,2.141c0.292,0.293,0.769,0.293,1.062,0l14.366-14.34c0.293-0.294,0.293-0.777,0-1.071L21.652,3.211z" fill-rule="evenodd"/></svg>';
17176  },
17177 
17178  //cross icon
17179  buttonCross: function buttonCross(cell, formatterParams, onRendered) {
17180  return '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#CE1515" d="M22.245,4.015c0.313,0.313,0.313,0.826,0,1.139l-6.276,6.27c-0.313,0.312-0.313,0.826,0,1.14l6.273,6.272 c0.313,0.313,0.313,0.826,0,1.14l-2.285,2.277c-0.314,0.312-0.828,0.312-1.142,0l-6.271-6.271c-0.313-0.313-0.828-0.313-1.141,0 l-6.276,6.267c-0.313,0.313-0.828,0.313-1.141,0l-2.282-2.28c-0.313-0.313-0.313-0.826,0-1.14l6.278-6.269 c0.313-0.312,0.313-0.826,0-1.14L1.709,5.147c-0.314-0.313-0.314-0.827,0-1.14l2.284-2.278C4.308,1.417,4.821,1.417,5.135,1.73 L11.405,8c0.314,0.314,0.828,0.314,1.141,0.001l6.276-6.267c0.312-0.312,0.826-0.312,1.141,0L22.245,4.015z"/></svg>';
17181  },
17182 
17183  //current row number
17184  rownum: function rownum(cell, formatterParams, onRendered) {
17185  return this.table.rowManager.activeRows.indexOf(cell.getRow()._getSelf()) + 1;
17186  },
17187 
17188  //row handle
17189  handle: function handle(cell, formatterParams, onRendered) {
17190  cell.getElement().classList.add("tabulator-row-handle");
17191  return "<div class='tabulator-row-handle-box'><div class='tabulator-row-handle-bar'></div><div class='tabulator-row-handle-bar'></div><div class='tabulator-row-handle-bar'></div></div>";
17192  },
17193 
17194  responsiveCollapse: function responsiveCollapse(cell, formatterParams, onRendered) {
17195  var self = this,
17196  open = false,
17197  el = document.createElement("div"),
17198  config = cell.getRow()._row.modules.responsiveLayout;
17199 
17200  el.classList.add("tabulator-responsive-collapse-toggle");
17201  el.innerHTML = "<span class='tabulator-responsive-collapse-toggle-open'>+</span><span class='tabulator-responsive-collapse-toggle-close'>-</span>";
17202 
17203  cell.getElement().classList.add("tabulator-row-handle");
17204 
17205  function toggleList(isOpen) {
17206  var collapseEl = config.element;
17207 
17208  config.open = isOpen;
17209 
17210  if (collapseEl) {
17211 
17212  if (config.open) {
17213  el.classList.add("open");
17214  collapseEl.style.display = '';
17215  } else {
17216  el.classList.remove("open");
17217  collapseEl.style.display = 'none';
17218  }
17219  }
17220  }
17221 
17222  el.addEventListener("click", function (e) {
17223  e.stopImmediatePropagation();
17224  toggleList(!config.open);
17225  });
17226 
17227  toggleList(config.open);
17228 
17229  return el;
17230  },
17231 
17232  rowSelection: function rowSelection(cell) {
17233  var _this48 = this;
17234 
17235  var checkbox = document.createElement("input");
17236 
17237  checkbox.type = 'checkbox';
17238 
17239  if (this.table.modExists("selectRow", true)) {
17240 
17241  checkbox.addEventListener("click", function (e) {
17242  e.stopPropagation();
17243  });
17244 
17245  if (typeof cell.getRow == 'function') {
17246  var row = cell.getRow();
17247 
17248  checkbox.addEventListener("change", function (e) {
17249  row.toggleSelect();
17250  });
17251 
17252  checkbox.checked = row.isSelected();
17253  this.table.modules.selectRow.registerRowSelectCheckbox(row, checkbox);
17254  } else {
17255  checkbox.addEventListener("change", function (e) {
17256  if (_this48.table.modules.selectRow.selectedRows.length) {
17257  _this48.table.deselectRow();
17258  } else {
17259  _this48.table.selectRow();
17260  }
17261  });
17262 
17263  this.table.modules.selectRow.registerHeaderSelectCheckbox(checkbox);
17264  }
17265  }
17266  return checkbox;
17267  }
17268  };
17269 
17270  Tabulator.prototype.registerModule("format", Format);
17271 
17272  var FrozenColumns = function FrozenColumns(table) {
17273  this.table = table; //hold Tabulator object
17274  this.leftColumns = [];
17275  this.rightColumns = [];
17276  this.leftMargin = 0;
17277  this.rightMargin = 0;
17278  this.rightPadding = 0;
17279  this.initializationMode = "left";
17280  this.active = false;
17281  this.scrollEndTimer = false;
17282  };
17283 
17284  //reset initial state
17285  FrozenColumns.prototype.reset = function () {
17286  this.initializationMode = "left";
17287  this.leftColumns = [];
17288  this.rightColumns = [];
17289  this.leftMargin = 0;
17290  this.rightMargin = 0;
17291  this.rightMargin = 0;
17292  this.active = false;
17293 
17294  this.table.columnManager.headersElement.style.marginLeft = 0;
17295  this.table.columnManager.element.style.paddingRight = 0;
17296  };
17297 
17298  //initialize specific column
17299  FrozenColumns.prototype.initializeColumn = function (column) {
17300  var config = { margin: 0, edge: false };
17301 
17302  if (column.definition.frozen) {
17303 
17304  if (!column.parent.isGroup) {
17305 
17306  if (!column.isGroup) {
17307  config.position = this.initializationMode;
17308 
17309  if (this.initializationMode == "left") {
17310  this.leftColumns.push(column);
17311  } else {
17312  this.rightColumns.unshift(column);
17313  }
17314 
17315  this.active = true;
17316 
17317  column.modules.frozen = config;
17318  } else {
17319  console.warn("Frozen Column Error - Column Groups cannot be frozen");
17320  }
17321  } else {
17322  console.warn("Frozen Column Error - Grouped columns cannot be frozen");
17323  }
17324  } else {
17325  this.initializationMode = "right";
17326  }
17327  };
17328 
17329  //quick layout to smooth horizontal scrolling
17330  FrozenColumns.prototype.scrollHorizontal = function () {
17331  var _this49 = this;
17332 
17333  var rows;
17334 
17335  if (this.active) {
17336  clearTimeout(this.scrollEndTimer);
17337 
17338  //layout all rows after scroll is complete
17339  this.scrollEndTimer = setTimeout(function () {
17340  _this49.layout();
17341  }, 100);
17342 
17343  rows = this.table.rowManager.getVisibleRows();
17344 
17345  this.calcMargins();
17346 
17347  this.layoutColumnPosition();
17348 
17349  this.layoutCalcRows();
17350 
17351  rows.forEach(function (row) {
17352  if (row.type === "row") {
17353  _this49.layoutRow(row);
17354  }
17355  });
17356 
17357  this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
17358  }
17359  };
17360 
17361  //calculate margins for rows
17362  FrozenColumns.prototype.calcMargins = function () {
17363  this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px";
17364  this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
17365 
17366  this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px";
17367  this.table.columnManager.element.style.paddingRight = this.rightMargin;
17368 
17369  //calculate right frozen columns
17370  this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft;
17371  };
17372 
17373  //layout calculation rows
17374  FrozenColumns.prototype.layoutCalcRows = function () {
17375  if (this.table.modExists("columnCalcs")) {
17376  if (this.table.modules.columnCalcs.topInitialized && this.table.modules.columnCalcs.topRow) {
17377  this.layoutRow(this.table.modules.columnCalcs.topRow);
17378  }
17379  if (this.table.modules.columnCalcs.botInitialized && this.table.modules.columnCalcs.botRow) {
17380  this.layoutRow(this.table.modules.columnCalcs.botRow);
17381  }
17382  }
17383  };
17384 
17385  //calculate column positions and layout headers
17386  FrozenColumns.prototype.layoutColumnPosition = function (allCells) {
17387  var _this50 = this;
17388 
17389  this.leftColumns.forEach(function (column, i) {
17390  column.modules.frozen.margin = _this50._calcSpace(_this50.leftColumns, i) + _this50.table.columnManager.scrollLeft + "px";
17391 
17392  if (i == _this50.leftColumns.length - 1) {
17393  column.modules.frozen.edge = true;
17394  } else {
17395  column.modules.frozen.edge = false;
17396  }
17397 
17398  _this50.layoutElement(column.getElement(), column);
17399 
17400  if (allCells) {
17401  column.cells.forEach(function (cell) {
17402  _this50.layoutElement(cell.getElement(), column);
17403  });
17404  }
17405  });
17406 
17407  this.rightColumns.forEach(function (column, i) {
17408  column.modules.frozen.margin = _this50.rightPadding - _this50._calcSpace(_this50.rightColumns, i + 1) + "px";
17409 
17410  if (i == _this50.rightColumns.length - 1) {
17411  column.modules.frozen.edge = true;
17412  } else {
17413  column.modules.frozen.edge = false;
17414  }
17415 
17416  _this50.layoutElement(column.getElement(), column);
17417 
17418  if (allCells) {
17419  column.cells.forEach(function (cell) {
17420  _this50.layoutElement(cell.getElement(), column);
17421  });
17422  }
17423  });
17424  };
17425 
17426  //layout columns appropropriatly
17427  FrozenColumns.prototype.layout = function () {
17428  var self = this,
17429  rightMargin = 0;
17430 
17431  if (self.active) {
17432 
17433  //calculate row padding
17434  this.calcMargins();
17435 
17436  // self.table.rowManager.activeRows.forEach(function(row){
17437  // self.layoutRow(row);
17438  // });
17439 
17440  // if(self.table.options.dataTree){
17441  self.table.rowManager.getDisplayRows().forEach(function (row) {
17442  if (row.type === "row") {
17443  self.layoutRow(row);
17444  }
17445  });
17446  // }
17447 
17448  this.layoutCalcRows();
17449 
17450  //calculate left columns
17451  this.layoutColumnPosition(true);
17452 
17453  // if(tableHolder.scrollHeight > tableHolder.clientHeight){
17454  // rightMargin -= tableHolder.offsetWidth - tableHolder.clientWidth;
17455  // }
17456 
17457  this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
17458  }
17459  };
17460 
17461  FrozenColumns.prototype.layoutRow = function (row) {
17462  var _this51 = this;
17463 
17464  var rowEl = row.getElement();
17465 
17466  rowEl.style.paddingLeft = this.leftMargin;
17467  // rowEl.style.paddingRight = this.rightMargin + "px";
17468 
17469  this.leftColumns.forEach(function (column) {
17470  var cell = row.getCell(column);
17471 
17472  if (cell) {
17473  _this51.layoutElement(cell.getElement(), column);
17474  }
17475  });
17476 
17477  this.rightColumns.forEach(function (column) {
17478  var cell = row.getCell(column);
17479 
17480  if (cell) {
17481  _this51.layoutElement(cell.getElement(), column);
17482  }
17483  });
17484  };
17485 
17486  FrozenColumns.prototype.layoutElement = function (element, column) {
17487 
17488  if (column.modules.frozen) {
17489  element.style.position = "absolute";
17490  element.style.left = column.modules.frozen.margin;
17491 
17492  element.classList.add("tabulator-frozen");
17493 
17494  if (column.modules.frozen.edge) {
17495  element.classList.add("tabulator-frozen-" + column.modules.frozen.position);
17496  }
17497  }
17498  };
17499 
17500  FrozenColumns.prototype._calcSpace = function (columns, index) {
17501  var width = 0;
17502 
17503  for (var i = 0; i < index; i++) {
17504  if (columns[i].visible) {
17505  width += columns[i].getWidth();
17506  }
17507  }
17508 
17509  return width;
17510  };
17511 
17512  Tabulator.prototype.registerModule("frozenColumns", FrozenColumns);
17513  var FrozenRows = function FrozenRows(table) {
17514  this.table = table; //hold Tabulator object
17515  this.topElement = document.createElement("div");
17516  this.rows = [];
17517  this.displayIndex = 0; //index in display pipeline
17518  };
17519 
17520  FrozenRows.prototype.initialize = function () {
17521  this.rows = [];
17522 
17523  this.topElement.classList.add("tabulator-frozen-rows-holder");
17524 
17525  // this.table.columnManager.element.append(this.topElement);
17526  this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
17527  };
17528 
17529  FrozenRows.prototype.setDisplayIndex = function (index) {
17530  this.displayIndex = index;
17531  };
17532 
17533  FrozenRows.prototype.getDisplayIndex = function () {
17534  return this.displayIndex;
17535  };
17536 
17537  FrozenRows.prototype.isFrozen = function () {
17538  return !!this.rows.length;
17539  };
17540 
17541  //filter frozen rows out of display data
17542  FrozenRows.prototype.getRows = function (rows) {
17543  var self = this,
17544  frozen = [],
17545  output = rows.slice(0);
17546 
17547  this.rows.forEach(function (row) {
17548  var index = output.indexOf(row);
17549 
17550  if (index > -1) {
17551  output.splice(index, 1);
17552  }
17553  });
17554 
17555  return output;
17556  };
17557 
17558  FrozenRows.prototype.freezeRow = function (row) {
17559  if (!row.modules.frozen) {
17560  row.modules.frozen = true;
17561  this.topElement.appendChild(row.getElement());
17562  row.initialize();
17563  row.normalizeHeight();
17564  this.table.rowManager.adjustTableSize();
17565 
17566  this.rows.push(row);
17567 
17568  this.table.rowManager.refreshActiveData("display");
17569 
17570  this.styleRows();
17571  } else {
17572  console.warn("Freeze Error - Row is already frozen");
17573  }
17574  };
17575 
17576  FrozenRows.prototype.unfreezeRow = function (row) {
17577  var index = this.rows.indexOf(row);
17578 
17579  if (row.modules.frozen) {
17580 
17581  row.modules.frozen = false;
17582 
17583  var rowEl = row.getElement();
17584  rowEl.parentNode.removeChild(rowEl);
17585 
17586  this.table.rowManager.adjustTableSize();
17587 
17588  this.rows.splice(index, 1);
17589 
17590  this.table.rowManager.refreshActiveData("display");
17591 
17592  if (this.rows.length) {
17593  this.styleRows();
17594  }
17595  } else {
17596  console.warn("Freeze Error - Row is already unfrozen");
17597  }
17598  };
17599 
17600  FrozenRows.prototype.styleRows = function (row) {
17601  var self = this;
17602 
17603  this.rows.forEach(function (row, i) {
17604  self.table.rowManager.styleRow(row, i);
17605  });
17606  };
17607 
17608  Tabulator.prototype.registerModule("frozenRows", FrozenRows);
17609 
17610  //public group object
17611  var GroupComponent = function GroupComponent(group) {
17612  this._group = group;
17613  this.type = "GroupComponent";
17614  };
17615 
17616  GroupComponent.prototype.getKey = function () {
17617  return this._group.key;
17618  };
17619 
17620  GroupComponent.prototype.getField = function () {
17621  return this._group.field;
17622  };
17623 
17624  GroupComponent.prototype.getElement = function () {
17625  return this._group.element;
17626  };
17627 
17628  GroupComponent.prototype.getRows = function () {
17629  return this._group.getRows(true);
17630  };
17631 
17632  GroupComponent.prototype.getSubGroups = function () {
17633  return this._group.getSubGroups(true);
17634  };
17635 
17636  GroupComponent.prototype.getParentGroup = function () {
17637  return this._group.parent ? this._group.parent.getComponent() : false;
17638  };
17639 
17640  GroupComponent.prototype.getVisibility = function () {
17641  return this._group.visible;
17642  };
17643 
17644  GroupComponent.prototype.show = function () {
17645  this._group.show();
17646  };
17647 
17648  GroupComponent.prototype.hide = function () {
17649  this._group.hide();
17650  };
17651 
17652  GroupComponent.prototype.toggle = function () {
17653  this._group.toggleVisibility();
17654  };
17655 
17656  GroupComponent.prototype._getSelf = function () {
17657  return this._group;
17658  };
17659 
17660  GroupComponent.prototype.getTable = function () {
17661  return this._group.groupManager.table;
17662  };
17663 
17667 
17668  var Group = function Group(groupManager, parent, level, key, field, generator, oldGroup) {
17669 
17670  this.groupManager = groupManager;
17671  this.parent = parent;
17672  this.key = key;
17673  this.level = level;
17674  this.field = field;
17675  this.hasSubGroups = level < groupManager.groupIDLookups.length - 1;
17676  this.addRow = this.hasSubGroups ? this._addRowToGroup : this._addRow;
17677  this.type = "group"; //type of element
17678  this.old = oldGroup;
17679  this.rows = [];
17680  this.groups = [];
17681  this.groupList = [];
17682  this.generator = generator;
17683  this.elementContents = false;
17684  this.height = 0;
17685  this.outerHeight = 0;
17686  this.initialized = false;
17687  this.calcs = {};
17688  this.initialized = false;
17689  this.modules = {};
17690  this.arrowElement = false;
17691 
17692  this.visible = oldGroup ? oldGroup.visible : typeof groupManager.startOpen[level] !== "undefined" ? groupManager.startOpen[level] : groupManager.startOpen[0];
17693 
17694  this.createElements();
17695  this.addBindings();
17696 
17697  this.createValueGroups();
17698  };
17699 
17700  Group.prototype.wipe = function () {
17701  if (this.groupList.length) {
17702  this.groupList.forEach(function (group) {
17703  group.wipe();
17704  });
17705  } else {
17706  this.element = false;
17707  this.arrowElement = false;
17708  this.elementContents = false;
17709  }
17710  };
17711 
17712  Group.prototype.createElements = function () {
17713  var arrow = document.createElement("div");
17714  arrow.classList.add("tabulator-arrow");
17715 
17716  this.element = document.createElement("div");
17717  this.element.classList.add("tabulator-row");
17718  this.element.classList.add("tabulator-group");
17719  this.element.classList.add("tabulator-group-level-" + this.level);
17720  this.element.setAttribute("role", "rowgroup");
17721 
17722  this.arrowElement = document.createElement("div");
17723  this.arrowElement.classList.add("tabulator-group-toggle");
17724  this.arrowElement.appendChild(arrow);
17725 
17726  //setup movable rows
17727  if (this.groupManager.table.options.movableRows !== false && this.groupManager.table.modExists("moveRow")) {
17728  this.groupManager.table.modules.moveRow.initializeGroupHeader(this);
17729  }
17730  };
17731 
17732  Group.prototype.createValueGroups = function () {
17733  var _this52 = this;
17734 
17735  var level = this.level + 1;
17736  if (this.groupManager.allowedValues && this.groupManager.allowedValues[level]) {
17737  this.groupManager.allowedValues[level].forEach(function (value) {
17738  _this52._createGroup(value, level);
17739  });
17740  }
17741  };
17742 
17743  Group.prototype.addBindings = function () {
17744  var self = this,
17745  dblTap,
17746  tapHold,
17747  tap,
17748  toggleElement;
17749 
17750  //handle group click events
17751  if (self.groupManager.table.options.groupClick) {
17752  self.element.addEventListener("click", function (e) {
17753  self.groupManager.table.options.groupClick.call(self.groupManager.table, e, self.getComponent());
17754  });
17755  }
17756 
17757  if (self.groupManager.table.options.groupDblClick) {
17758  self.element.addEventListener("dblclick", function (e) {
17759  self.groupManager.table.options.groupDblClick.call(self.groupManager.table, e, self.getComponent());
17760  });
17761  }
17762 
17763  if (self.groupManager.table.options.groupContext) {
17764  self.element.addEventListener("contextmenu", function (e) {
17765  self.groupManager.table.options.groupContext.call(self.groupManager.table, e, self.getComponent());
17766  });
17767  }
17768 
17769  if (self.groupManager.table.options.groupTap) {
17770 
17771  tap = false;
17772 
17773  self.element.addEventListener("touchstart", function (e) {
17774  tap = true;
17775  }, { passive: true });
17776 
17777  self.element.addEventListener("touchend", function (e) {
17778  if (tap) {
17779  self.groupManager.table.options.groupTap(e, self.getComponent());
17780  }
17781 
17782  tap = false;
17783  });
17784  }
17785 
17786  if (self.groupManager.table.options.groupDblTap) {
17787 
17788  dblTap = null;
17789 
17790  self.element.addEventListener("touchend", function (e) {
17791 
17792  if (dblTap) {
17793  clearTimeout(dblTap);
17794  dblTap = null;
17795 
17796  self.groupManager.table.options.groupDblTap(e, self.getComponent());
17797  } else {
17798 
17799  dblTap = setTimeout(function () {
17800  clearTimeout(dblTap);
17801  dblTap = null;
17802  }, 300);
17803  }
17804  });
17805  }
17806 
17807  if (self.groupManager.table.options.groupTapHold) {
17808 
17809  tapHold = null;
17810 
17811  self.element.addEventListener("touchstart", function (e) {
17812  clearTimeout(tapHold);
17813 
17814  tapHold = setTimeout(function () {
17815  clearTimeout(tapHold);
17816  tapHold = null;
17817  tap = false;
17818  self.groupManager.table.options.groupTapHold(e, self.getComponent());
17819  }, 1000);
17820  }, { passive: true });
17821 
17822  self.element.addEventListener("touchend", function (e) {
17823  clearTimeout(tapHold);
17824  tapHold = null;
17825  });
17826  }
17827 
17828  if (self.groupManager.table.options.groupToggleElement) {
17829  toggleElement = self.groupManager.table.options.groupToggleElement == "arrow" ? self.arrowElement : self.element;
17830 
17831  toggleElement.addEventListener("click", function (e) {
17832  e.stopPropagation();
17833  e.stopImmediatePropagation();
17834  self.toggleVisibility();
17835  });
17836  }
17837  };
17838 
17839  Group.prototype._createGroup = function (groupID, level) {
17840  var groupKey = level + "_" + groupID;
17841  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);
17842 
17843  this.groups[groupKey] = group;
17844  this.groupList.push(group);
17845  };
17846 
17847  Group.prototype._addRowToGroup = function (row) {
17848 
17849  var level = this.level + 1;
17850 
17851  if (this.hasSubGroups) {
17852  var groupID = this.groupManager.groupIDLookups[level].func(row.getData()),
17853  groupKey = level + "_" + groupID;
17854 
17855  if (this.groupManager.allowedValues && this.groupManager.allowedValues[level]) {
17856  if (this.groups[groupKey]) {
17857  this.groups[groupKey].addRow(row);
17858  }
17859  } else {
17860  if (!this.groups[groupKey]) {
17861  this._createGroup(groupID, level);
17862  }
17863 
17864  this.groups[groupKey].addRow(row);
17865  }
17866  }
17867  };
17868 
17869  Group.prototype._addRow = function (row) {
17870  this.rows.push(row);
17871  row.modules.group = this;
17872  };
17873 
17874  Group.prototype.insertRow = function (row, to, after) {
17875  var data = this.conformRowData({});
17876 
17877  row.updateData(data);
17878 
17879  var toIndex = this.rows.indexOf(to);
17880 
17881  if (toIndex > -1) {
17882  if (after) {
17883  this.rows.splice(toIndex + 1, 0, row);
17884  } else {
17885  this.rows.splice(toIndex, 0, row);
17886  }
17887  } else {
17888  if (after) {
17889  this.rows.push(row);
17890  } else {
17891  this.rows.unshift(row);
17892  }
17893  }
17894 
17895  row.modules.group = this;
17896 
17897  this.generateGroupHeaderContents();
17898 
17899  if (this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table") {
17900  this.groupManager.table.modules.columnCalcs.recalcGroup(this);
17901  }
17902 
17903  this.groupManager.updateGroupRows(true);
17904  };
17905 
17906  Group.prototype.scrollHeader = function (left) {
17907  this.arrowElement.style.marginLeft = left;
17908 
17909  this.groupList.forEach(function (child) {
17910  child.scrollHeader(left);
17911  });
17912  };
17913 
17914  Group.prototype.getRowIndex = function (row) {};
17915 
17916  //update row data to match grouping contraints
17917  Group.prototype.conformRowData = function (data) {
17918  if (this.field) {
17919  data[this.field] = this.key;
17920  } else {
17921  console.warn("Data Conforming Error - Cannot conform row data to match new group as groupBy is a function");
17922  }
17923 
17924  if (this.parent) {
17925  data = this.parent.conformRowData(data);
17926  }
17927 
17928  return data;
17929  };
17930 
17931  Group.prototype.removeRow = function (row) {
17932  var index = this.rows.indexOf(row);
17933  var el = row.getElement();
17934 
17935  if (index > -1) {
17936  this.rows.splice(index, 1);
17937  }
17938 
17939  if (!this.groupManager.table.options.groupValues && !this.rows.length) {
17940  if (this.parent) {
17941  this.parent.removeGroup(this);
17942  } else {
17943  this.groupManager.removeGroup(this);
17944  }
17945 
17946  this.groupManager.updateGroupRows(true);
17947  } else {
17948 
17949  if (el.parentNode) {
17950  el.parentNode.removeChild(el);
17951  }
17952 
17953  this.generateGroupHeaderContents();
17954 
17955  if (this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table") {
17956  this.groupManager.table.modules.columnCalcs.recalcGroup(this);
17957  }
17958  }
17959  };
17960 
17961  Group.prototype.removeGroup = function (group) {
17962  var groupKey = group.level + "_" + group.key,
17963  index;
17964 
17965  if (this.groups[groupKey]) {
17966  delete this.groups[groupKey];
17967 
17968  index = this.groupList.indexOf(group);
17969 
17970  if (index > -1) {
17971  this.groupList.splice(index, 1);
17972  }
17973 
17974  if (!this.groupList.length) {
17975  if (this.parent) {
17976  this.parent.removeGroup(this);
17977  } else {
17978  this.groupManager.removeGroup(this);
17979  }
17980  }
17981  }
17982  };
17983 
17984  Group.prototype.getHeadersAndRows = function (noCalc) {
17985  var output = [];
17986 
17987  output.push(this);
17988 
17989  this._visSet();
17990 
17991  if (this.visible) {
17992  if (this.groupList.length) {
17993  this.groupList.forEach(function (group) {
17994  output = output.concat(group.getHeadersAndRows(noCalc));
17995  });
17996  } else {
17997  if (!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()) {
17998  if (this.calcs.top) {
17999  this.calcs.top.detachElement();
18000  this.calcs.top.deleteCells();
18001  }
18002 
18003  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
18004  output.push(this.calcs.top);
18005  }
18006 
18007  output = output.concat(this.rows);
18008 
18009  if (!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()) {
18010  if (this.calcs.bottom) {
18011  this.calcs.bottom.detachElement();
18012  this.calcs.bottom.deleteCells();
18013  }
18014 
18015  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
18016  output.push(this.calcs.bottom);
18017  }
18018  }
18019  } else {
18020  if (!this.groupList.length && this.groupManager.table.options.columnCalcs != "table") {
18021 
18022  if (this.groupManager.table.modExists("columnCalcs")) {
18023 
18024  if (!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()) {
18025  if (this.calcs.top) {
18026  this.calcs.top.detachElement();
18027  this.calcs.top.deleteCells();
18028  }
18029 
18030  if (this.groupManager.table.options.groupClosedShowCalcs) {
18031  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
18032  output.push(this.calcs.top);
18033  }
18034  }
18035 
18036  if (!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()) {
18037  if (this.calcs.bottom) {
18038  this.calcs.bottom.detachElement();
18039  this.calcs.bottom.deleteCells();
18040  }
18041 
18042  if (this.groupManager.table.options.groupClosedShowCalcs) {
18043  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
18044  output.push(this.calcs.bottom);
18045  }
18046  }
18047  }
18048  }
18049  }
18050 
18051  return output;
18052  };
18053 
18054  Group.prototype.getData = function (visible, transform) {
18055  var self = this,
18056  output = [];
18057 
18058  this._visSet();
18059 
18060  if (!visible || visible && this.visible) {
18061  this.rows.forEach(function (row) {
18062  output.push(row.getData(transform || "data"));
18063  });
18064  }
18065 
18066  return output;
18067  };
18068 
18069  // Group.prototype.getRows = function(){
18070  // this._visSet();
18071 
18072  // return this.visible ? this.rows : [];
18073  // };
18074 
18075  Group.prototype.getRowCount = function () {
18076  var count = 0;
18077 
18078  if (this.groupList.length) {
18079  this.groupList.forEach(function (group) {
18080  count += group.getRowCount();
18081  });
18082  } else {
18083  count = this.rows.length;
18084  }
18085  return count;
18086  };
18087 
18088  Group.prototype.toggleVisibility = function () {
18089  if (this.visible) {
18090  this.hide();
18091  } else {
18092  this.show();
18093  }
18094  };
18095 
18096  Group.prototype.hide = function () {
18097  this.visible = false;
18098 
18099  if (this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination) {
18100 
18101  this.element.classList.remove("tabulator-group-visible");
18102 
18103  if (this.groupList.length) {
18104  this.groupList.forEach(function (group) {
18105 
18106  var rows = group.getHeadersAndRows();
18107 
18108  rows.forEach(function (row) {
18109  row.detachElement();
18110  });
18111  });
18112  } else {
18113  this.rows.forEach(function (row) {
18114  var rowEl = row.getElement();
18115  rowEl.parentNode.removeChild(rowEl);
18116  });
18117  }
18118 
18119  this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
18120 
18121  this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
18122  } else {
18123  this.groupManager.updateGroupRows(true);
18124  }
18125 
18126  this.groupManager.table.options.groupVisibilityChanged.call(this.table, this.getComponent(), false);
18127  };
18128 
18129  Group.prototype.show = function () {
18130  var self = this;
18131 
18132  self.visible = true;
18133 
18134  if (this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination) {
18135 
18136  this.element.classList.add("tabulator-group-visible");
18137 
18138  var prev = self.getElement();
18139 
18140  if (this.groupList.length) {
18141  this.groupList.forEach(function (group) {
18142  var rows = group.getHeadersAndRows();
18143 
18144  rows.forEach(function (row) {
18145  var rowEl = row.getElement();
18146  prev.parentNode.insertBefore(rowEl, prev.nextSibling);
18147  row.initialize();
18148  prev = rowEl;
18149  });
18150  });
18151  } else {
18152  self.rows.forEach(function (row) {
18153  var rowEl = row.getElement();
18154  prev.parentNode.insertBefore(rowEl, prev.nextSibling);
18155  row.initialize();
18156  prev = rowEl;
18157  });
18158  }
18159 
18160  this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
18161 
18162  this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
18163  } else {
18164  this.groupManager.updateGroupRows(true);
18165  }
18166 
18167  this.groupManager.table.options.groupVisibilityChanged.call(this.table, this.getComponent(), true);
18168  };
18169 
18170  Group.prototype._visSet = function () {
18171  var data = [];
18172 
18173  if (typeof this.visible == "function") {
18174 
18175  this.rows.forEach(function (row) {
18176  data.push(row.getData());
18177  });
18178 
18179  this.visible = this.visible(this.key, this.getRowCount(), data, this.getComponent());
18180  }
18181  };
18182 
18183  Group.prototype.getRowGroup = function (row) {
18184  var match = false;
18185  if (this.groupList.length) {
18186  this.groupList.forEach(function (group) {
18187  var result = group.getRowGroup(row);
18188 
18189  if (result) {
18190  match = result;
18191  }
18192  });
18193  } else {
18194  if (this.rows.find(function (item) {
18195  return item === row;
18196  })) {
18197  match = this;
18198  }
18199  }
18200 
18201  return match;
18202  };
18203 
18204  Group.prototype.getSubGroups = function (component) {
18205  var output = [];
18206 
18207  this.groupList.forEach(function (child) {
18208  output.push(component ? child.getComponent() : child);
18209  });
18210 
18211  return output;
18212  };
18213 
18214  Group.prototype.getRows = function (compoment) {
18215  var output = [];
18216 
18217  this.rows.forEach(function (row) {
18218  output.push(compoment ? row.getComponent() : row);
18219  });
18220 
18221  return output;
18222  };
18223 
18224  Group.prototype.generateGroupHeaderContents = function () {
18225  var data = [];
18226 
18227  this.rows.forEach(function (row) {
18228  data.push(row.getData());
18229  });
18230 
18231  this.elementContents = this.generator(this.key, this.getRowCount(), data, this.getComponent());
18232 
18233  while (this.element.firstChild) {
18234  this.element.removeChild(this.element.firstChild);
18235  }if (typeof this.elementContents === "string") {
18236  this.element.innerHTML = this.elementContents;
18237  } else {
18238  this.element.appendChild(this.elementContents);
18239  }
18240 
18241  this.element.insertBefore(this.arrowElement, this.element.firstChild);
18242  };
18243 
18245 
18246  Group.prototype.getElement = function () {
18247  this.addBindingsd = false;
18248 
18249  this._visSet();
18250 
18251  if (this.visible) {
18252  this.element.classList.add("tabulator-group-visible");
18253  } else {
18254  this.element.classList.remove("tabulator-group-visible");
18255  }
18256 
18257  for (var i = 0; i < this.element.childNodes.length; ++i) {
18258  this.element.childNodes[i].parentNode.removeChild(this.element.childNodes[i]);
18259  }
18260 
18261  this.generateGroupHeaderContents();
18262 
18263  // this.addBindings();
18264 
18265  return this.element;
18266  };
18267 
18268  Group.prototype.detachElement = function () {
18269  if (this.element && this.element.parentNode) {
18270  this.element.parentNode.removeChild(this.element);
18271  }
18272  };
18273 
18274  //normalize the height of elements in the row
18275  Group.prototype.normalizeHeight = function () {
18276  this.setHeight(this.element.clientHeight);
18277  };
18278 
18279  Group.prototype.initialize = function (force) {
18280  if (!this.initialized || force) {
18281  this.normalizeHeight();
18282  this.initialized = true;
18283  }
18284  };
18285 
18286  Group.prototype.reinitialize = function () {
18287  this.initialized = false;
18288  this.height = 0;
18289 
18290  if (Tabulator.prototype.helpers.elVisible(this.element)) {
18291  this.initialize(true);
18292  }
18293  };
18294 
18295  Group.prototype.setHeight = function (height) {
18296  if (this.height != height) {
18297  this.height = height;
18298  this.outerHeight = this.element.offsetHeight;
18299  }
18300  };
18301 
18302  //return rows outer height
18303  Group.prototype.getHeight = function () {
18304  return this.outerHeight;
18305  };
18306 
18307  Group.prototype.getGroup = function () {
18308  return this;
18309  };
18310 
18311  Group.prototype.reinitializeHeight = function () {};
18312  Group.prototype.calcHeight = function () {};
18313  Group.prototype.setCellHeight = function () {};
18314  Group.prototype.clearCellHeight = function () {};
18315 
18317  Group.prototype.getComponent = function () {
18318  return new GroupComponent(this);
18319  };
18320 
18324 
18325  var GroupRows = function GroupRows(table) {
18326 
18327  this.table = table; //hold Tabulator object
18328 
18329  this.groupIDLookups = false; //enable table grouping and set field to group by
18330  this.startOpen = [function () {
18331  return false;
18332  }]; //starting state of group
18333  this.headerGenerator = [function () {
18334  return "";
18335  }];
18336  this.groupList = []; //ordered list of groups
18337  this.allowedValues = false;
18338  this.groups = {}; //hold row groups
18339  this.displayIndex = 0; //index in display pipeline
18340  };
18341 
18342  //initialize group configuration
18343  GroupRows.prototype.initialize = function () {
18344  var self = this,
18345  groupBy = self.table.options.groupBy,
18346  startOpen = self.table.options.groupStartOpen,
18347  groupHeader = self.table.options.groupHeader;
18348 
18349  this.allowedValues = self.table.options.groupValues;
18350 
18351  if (Array.isArray(groupBy) && Array.isArray(groupHeader) && groupBy.length > groupHeader.length) {
18352  console.warn("Error creating group headers, groupHeader array is shorter than groupBy array");
18353  }
18354 
18355  self.headerGenerator = [function () {
18356  return "";
18357  }];
18358  this.startOpen = [function () {
18359  return false;
18360  }]; //starting state of group
18361 
18362  self.table.modules.localize.bind("groups|item", function (langValue, lang) {
18363  self.headerGenerator[0] = function (value, count, data) {
18364  //header layout function
18365  return (typeof value === "undefined" ? "" : value) + "<span>(" + count + " " + (count === 1 ? langValue : lang.groups.items) + ")</span>";
18366  };
18367  });
18368 
18369  this.groupIDLookups = [];
18370 
18371  if (Array.isArray(groupBy) || groupBy) {
18372  if (this.table.modExists("columnCalcs") && this.table.options.columnCalcs != "table" && this.table.options.columnCalcs != "both") {
18373  this.table.modules.columnCalcs.removeCalcs();
18374  }
18375  } else {
18376  if (this.table.modExists("columnCalcs") && this.table.options.columnCalcs != "group") {
18377 
18378  var cols = this.table.columnManager.getRealColumns();
18379 
18380  cols.forEach(function (col) {
18381  if (col.definition.topCalc) {
18382  self.table.modules.columnCalcs.initializeTopRow();
18383  }
18384 
18385  if (col.definition.bottomCalc) {
18386  self.table.modules.columnCalcs.initializeBottomRow();
18387  }
18388  });
18389  }
18390  }
18391 
18392  if (!Array.isArray(groupBy)) {
18393  groupBy = [groupBy];
18394  }
18395 
18396  groupBy.forEach(function (group, i) {
18397  var lookupFunc, column;
18398 
18399  if (typeof group == "function") {
18400  lookupFunc = group;
18401  } else {
18402  column = self.table.columnManager.getColumnByField(group);
18403 
18404  if (column) {
18405  lookupFunc = function lookupFunc(data) {
18406  return column.getFieldValue(data);
18407  };
18408  } else {
18409  lookupFunc = function lookupFunc(data) {
18410  return data[group];
18411  };
18412  }
18413  }
18414 
18415  self.groupIDLookups.push({
18416  field: typeof group === "function" ? false : group,
18417  func: lookupFunc,
18418  values: self.allowedValues ? self.allowedValues[i] : false
18419  });
18420  });
18421 
18422  if (startOpen) {
18423 
18424  if (!Array.isArray(startOpen)) {
18425  startOpen = [startOpen];
18426  }
18427 
18428  startOpen.forEach(function (level) {
18429  level = typeof level == "function" ? level : function () {
18430  return true;
18431  };
18432  });
18433 
18434  self.startOpen = startOpen;
18435  }
18436 
18437  if (groupHeader) {
18438  self.headerGenerator = Array.isArray(groupHeader) ? groupHeader : [groupHeader];
18439  }
18440 
18441  this.initialized = true;
18442  };
18443 
18444  GroupRows.prototype.setDisplayIndex = function (index) {
18445  this.displayIndex = index;
18446  };
18447 
18448  GroupRows.prototype.getDisplayIndex = function () {
18449  return this.displayIndex;
18450  };
18451 
18452  //return appropriate rows with group headers
18453  GroupRows.prototype.getRows = function (rows) {
18454  if (this.groupIDLookups.length) {
18455 
18456  this.table.options.dataGrouping.call(this.table);
18457 
18458  this.generateGroups(rows);
18459 
18460  if (this.table.options.dataGrouped) {
18461  this.table.options.dataGrouped.call(this.table, this.getGroups(true));
18462  }
18463 
18464  return this.updateGroupRows();
18465  } else {
18466  return rows.slice(0);
18467  }
18468  };
18469 
18470  GroupRows.prototype.getGroups = function (compoment) {
18471  var groupComponents = [];
18472 
18473  this.groupList.forEach(function (group) {
18474  groupComponents.push(compoment ? group.getComponent() : group);
18475  });
18476 
18477  return groupComponents;
18478  };
18479 
18480  GroupRows.prototype.wipe = function () {
18481  this.groupList.forEach(function (group) {
18482  group.wipe();
18483  });
18484  };
18485 
18486  GroupRows.prototype.pullGroupListData = function (groupList) {
18487  var self = this;
18488  var groupListData = [];
18489 
18490  groupList.forEach(function (group) {
18491  var groupHeader = {};
18492  groupHeader.level = 0;
18493  groupHeader.rowCount = 0;
18494  groupHeader.headerContent = "";
18495  var childData = [];
18496 
18497  if (group.hasSubGroups) {
18498  childData = self.pullGroupListData(group.groupList);
18499 
18500  groupHeader.level = group.level;
18501  groupHeader.rowCount = childData.length - group.groupList.length; // data length minus number of sub-headers
18502  groupHeader.headerContent = group.generator(group.key, groupHeader.rowCount, group.rows, group);
18503 
18504  groupListData.push(groupHeader);
18505  groupListData = groupListData.concat(childData);
18506  } else {
18507  groupHeader.level = group.level;
18508  groupHeader.headerContent = group.generator(group.key, group.rows.length, group.rows, group);
18509  groupHeader.rowCount = group.getRows().length;
18510 
18511  groupListData.push(groupHeader);
18512 
18513  group.getRows().forEach(function (row) {
18514  groupListData.push(row.getData("data"));
18515  });
18516  }
18517  });
18518 
18519  return groupListData;
18520  };
18521 
18522  GroupRows.prototype.getGroupedData = function () {
18523 
18524  return this.pullGroupListData(this.groupList);
18525  };
18526 
18527  GroupRows.prototype.getRowGroup = function (row) {
18528  var match = false;
18529 
18530  this.groupList.forEach(function (group) {
18531  var result = group.getRowGroup(row);
18532 
18533  if (result) {
18534  match = result;
18535  }
18536  });
18537 
18538  return match;
18539  };
18540 
18541  GroupRows.prototype.countGroups = function () {
18542  return this.groupList.length;
18543  };
18544 
18545  GroupRows.prototype.generateGroups = function (rows) {
18546  var self = this,
18547  oldGroups = self.groups;
18548 
18549  self.groups = {};
18550  self.groupList = [];
18551 
18552  if (this.allowedValues && this.allowedValues[0]) {
18553  this.allowedValues[0].forEach(function (value) {
18554  self.createGroup(value, 0, oldGroups);
18555  });
18556 
18557  rows.forEach(function (row) {
18558  self.assignRowToExistingGroup(row, oldGroups);
18559  });
18560  } else {
18561  rows.forEach(function (row) {
18562  self.assignRowToGroup(row, oldGroups);
18563  });
18564  }
18565  };
18566 
18567  GroupRows.prototype.createGroup = function (groupID, level, oldGroups) {
18568  var groupKey = level + "_" + groupID,
18569  group;
18570 
18571  oldGroups = oldGroups || [];
18572 
18573  group = new Group(this, false, level, groupID, this.groupIDLookups[0].field, this.headerGenerator[0], oldGroups[groupKey]);
18574 
18575  this.groups[groupKey] = group;
18576  this.groupList.push(group);
18577  };
18578 
18579  // GroupRows.prototype.assignRowToGroup = function(row, oldGroups){
18580  // var groupID = this.groupIDLookups[0].func(row.getData()),
18581  // groupKey = "0_" + groupID;
18582 
18583  // if(!this.groups[groupKey]){
18584  // this.createGroup(groupID, 0, oldGroups);
18585  // }
18586 
18587  // this.groups[groupKey].addRow(row);
18588  // };
18589 
18590  GroupRows.prototype.assignRowToExistingGroup = function (row, oldGroups) {
18591  var groupID = this.groupIDLookups[0].func(row.getData()),
18592  groupKey = "0_" + groupID;
18593 
18594  if (this.groups[groupKey]) {
18595  this.groups[groupKey].addRow(row);
18596  }
18597  };
18598 
18599  GroupRows.prototype.assignRowToGroup = function (row, oldGroups) {
18600  var groupID = this.groupIDLookups[0].func(row.getData()),
18601  newGroupNeeded = !this.groups["0_" + groupID];
18602 
18603  if (newGroupNeeded) {
18604  this.createGroup(groupID, 0, oldGroups);
18605  }
18606 
18607  this.groups["0_" + groupID].addRow(row);
18608 
18609  return !newGroupNeeded;
18610  };
18611 
18612  GroupRows.prototype.updateGroupRows = function (force) {
18613  var self = this,
18614  output = [],
18615  oldRowCount;
18616 
18617  self.groupList.forEach(function (group) {
18618  output = output.concat(group.getHeadersAndRows());
18619  });
18620 
18621  //force update of table display
18622  if (force) {
18623 
18624  var displayIndex = self.table.rowManager.setDisplayRows(output, this.getDisplayIndex());
18625 
18626  if (displayIndex !== true) {
18627  this.setDisplayIndex(displayIndex);
18628  }
18629 
18630  self.table.rowManager.refreshActiveData("group", true, true);
18631  }
18632 
18633  return output;
18634  };
18635 
18636  GroupRows.prototype.scrollHeaders = function (left) {
18637  left = left + "px";
18638 
18639  this.groupList.forEach(function (group) {
18640  group.scrollHeader(left);
18641  });
18642  };
18643 
18644  GroupRows.prototype.removeGroup = function (group) {
18645  var groupKey = group.level + "_" + group.key,
18646  index;
18647 
18648  if (this.groups[groupKey]) {
18649  delete this.groups[groupKey];
18650 
18651  index = this.groupList.indexOf(group);
18652 
18653  if (index > -1) {
18654  this.groupList.splice(index, 1);
18655  }
18656  }
18657  };
18658 
18659  Tabulator.prototype.registerModule("groupRows", GroupRows);
18660  var History = function History(table) {
18661  this.table = table; //hold Tabulator object
18662 
18663  this.history = [];
18664  this.index = -1;
18665  };
18666 
18667  History.prototype.clear = function () {
18668  this.history = [];
18669  this.index = -1;
18670  };
18671 
18672  History.prototype.action = function (type, component, data) {
18673 
18674  this.history = this.history.slice(0, this.index + 1);
18675 
18676  this.history.push({
18677  type: type,
18678  component: component,
18679  data: data
18680  });
18681 
18682  this.index++;
18683  };
18684 
18685  History.prototype.getHistoryUndoSize = function () {
18686  return this.index + 1;
18687  };
18688 
18689  History.prototype.getHistoryRedoSize = function () {
18690  return this.history.length - (this.index + 1);
18691  };
18692 
18693  History.prototype.undo = function () {
18694 
18695  if (this.index > -1) {
18696  var action = this.history[this.index];
18697 
18698  this.undoers[action.type].call(this, action);
18699 
18700  this.index--;
18701 
18702  this.table.options.historyUndo.call(this.table, action.type, action.component.getComponent(), action.data);
18703 
18704  return true;
18705  } else {
18706  console.warn("History Undo Error - No more history to undo");
18707  return false;
18708  }
18709  };
18710 
18711  History.prototype.redo = function () {
18712  if (this.history.length - 1 > this.index) {
18713 
18714  this.index++;
18715 
18716  var action = this.history[this.index];
18717 
18718  this.redoers[action.type].call(this, action);
18719 
18720  this.table.options.historyRedo.call(this.table, action.type, action.component.getComponent(), action.data);
18721 
18722  return true;
18723  } else {
18724  console.warn("History Redo Error - No more history to redo");
18725  return false;
18726  }
18727  };
18728 
18729  History.prototype.undoers = {
18730  cellEdit: function cellEdit(action) {
18731  action.component.setValueProcessData(action.data.oldValue);
18732  },
18733 
18734  rowAdd: function rowAdd(action) {
18735  action.component.deleteActual();
18736  },
18737 
18738  rowDelete: function rowDelete(action) {
18739  var newRow = this.table.rowManager.addRowActual(action.data.data, action.data.pos, action.data.index);
18740 
18741  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
18742  this.table.modules.groupRows.updateGroupRows(true);
18743  }
18744 
18745  this._rebindRow(action.component, newRow);
18746  },
18747 
18748  rowMove: function rowMove(action) {
18749  this.table.rowManager.moveRowActual(action.component, this.table.rowManager.rows[action.data.pos], false);
18750  this.table.rowManager.redraw();
18751  }
18752  };
18753 
18754  History.prototype.redoers = {
18755  cellEdit: function cellEdit(action) {
18756  action.component.setValueProcessData(action.data.newValue);
18757  },
18758 
18759  rowAdd: function rowAdd(action) {
18760  var newRow = this.table.rowManager.addRowActual(action.data.data, action.data.pos, action.data.index);
18761 
18762  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
18763  this.table.modules.groupRows.updateGroupRows(true);
18764  }
18765 
18766  this._rebindRow(action.component, newRow);
18767  },
18768 
18769  rowDelete: function rowDelete(action) {
18770  action.component.deleteActual();
18771  },
18772 
18773  rowMove: function rowMove(action) {
18774  this.table.rowManager.moveRowActual(action.component, this.table.rowManager.rows[action.data.pos], false);
18775  this.table.rowManager.redraw();
18776  }
18777  };
18778 
18779  //rebind rows to new element after deletion
18780  History.prototype._rebindRow = function (oldRow, newRow) {
18781  this.history.forEach(function (action) {
18782  if (action.component instanceof Row) {
18783  if (action.component === oldRow) {
18784  action.component = newRow;
18785  }
18786  } else if (action.component instanceof Cell) {
18787  if (action.component.row === oldRow) {
18788  var field = action.component.column.getField();
18789 
18790  if (field) {
18791  action.component = newRow.getCell(field);
18792  }
18793  }
18794  }
18795  });
18796  };
18797 
18798  Tabulator.prototype.registerModule("history", History);
18799  var HtmlTableImport = function HtmlTableImport(table) {
18800  this.table = table; //hold Tabulator object
18801  this.fieldIndex = [];
18802  this.hasIndex = false;
18803  };
18804 
18805  HtmlTableImport.prototype.parseTable = function () {
18806  var self = this,
18807  element = self.table.element,
18808  options = self.table.options,
18809  columns = options.columns,
18810  headers = element.getElementsByTagName("th"),
18811  rows = element.getElementsByTagName("tbody")[0],
18812  data = [],
18813  newTable;
18814 
18815  self.hasIndex = false;
18816 
18817  self.table.options.htmlImporting.call(this.table);
18818 
18819  rows = rows ? rows.getElementsByTagName("tr") : [];
18820 
18821  //check for tablator inline options
18822  self._extractOptions(element, options);
18823 
18824  if (headers.length) {
18825  self._extractHeaders(headers, rows);
18826  } else {
18827  self._generateBlankHeaders(headers, rows);
18828  }
18829 
18830  //iterate through table rows and build data set
18831  for (var index = 0; index < rows.length; index++) {
18832  var row = rows[index],
18833  cells = row.getElementsByTagName("td"),
18834  item = {};
18835 
18836  //create index if the dont exist in table
18837  if (!self.hasIndex) {
18838  item[options.index] = index;
18839  }
18840 
18841  for (var i = 0; i < cells.length; i++) {
18842  var cell = cells[i];
18843  if (typeof this.fieldIndex[i] !== "undefined") {
18844  item[this.fieldIndex[i]] = cell.innerHTML;
18845  }
18846  }
18847 
18848  //add row data to item
18849  data.push(item);
18850  }
18851 
18852  //create new element
18853  var newElement = document.createElement("div");
18854 
18855  //transfer attributes to new element
18856  var attributes = element.attributes;
18857 
18858  // loop through attributes and apply them on div
18859 
18860  for (var i in attributes) {
18861  if (_typeof(attributes[i]) == "object") {
18862  newElement.setAttribute(attributes[i].name, attributes[i].value);
18863  }
18864  }
18865 
18866  // replace table with div element
18867  element.parentNode.replaceChild(newElement, element);
18868 
18869  options.data = data;
18870 
18871  self.table.options.htmlImported.call(this.table);
18872 
18873  // // newElement.tabulator(options);
18874 
18875  this.table.element = newElement;
18876  };
18877 
18878  //extract tabulator attribute options
18879  HtmlTableImport.prototype._extractOptions = function (element, options, defaultOptions) {
18880  var attributes = element.attributes;
18881  var optionsArr = defaultOptions ? Object.assign([], defaultOptions) : Object.keys(options);
18882  var optionsList = {};
18883 
18884  optionsArr.forEach(function (item) {
18885  optionsList[item.toLowerCase()] = item;
18886  });
18887 
18888  for (var index in attributes) {
18889  var attrib = attributes[index];
18890  var name;
18891 
18892  if (attrib && (typeof attrib === 'undefined' ? 'undefined' : _typeof(attrib)) == "object" && attrib.name && attrib.name.indexOf("tabulator-") === 0) {
18893  name = attrib.name.replace("tabulator-", "");
18894 
18895  if (typeof optionsList[name] !== "undefined") {
18896  options[optionsList[name]] = this._attribValue(attrib.value);
18897  }
18898  }
18899  }
18900  };
18901 
18902  //get value of attribute
18903  HtmlTableImport.prototype._attribValue = function (value) {
18904  if (value === "true") {
18905  return true;
18906  }
18907 
18908  if (value === "false") {
18909  return false;
18910  }
18911 
18912  return value;
18913  };
18914 
18915  //find column if it has already been defined
18916  HtmlTableImport.prototype._findCol = function (title) {
18917  var match = this.table.options.columns.find(function (column) {
18918  return column.title === title;
18919  });
18920 
18921  return match || false;
18922  };
18923 
18924  //extract column from headers
18925  HtmlTableImport.prototype._extractHeaders = function (headers, rows) {
18926  for (var index = 0; index < headers.length; index++) {
18927  var header = headers[index],
18928  exists = false,
18929  col = this._findCol(header.textContent),
18930  width,
18931  attributes;
18932 
18933  if (col) {
18934  exists = true;
18935  } else {
18936  col = { title: header.textContent.trim() };
18937  }
18938 
18939  if (!col.field) {
18940  col.field = header.textContent.trim().toLowerCase().replace(" ", "_");
18941  }
18942 
18943  width = header.getAttribute("width");
18944 
18945  if (width && !col.width) {
18946  col.width = width;
18947  }
18948 
18949  //check for tablator inline options
18950  attributes = header.attributes;
18951 
18952  // //check for tablator inline options
18953  this._extractOptions(header, col, Column.prototype.defaultOptionList);
18954 
18955  for (var i in attributes) {
18956  var attrib = attributes[i],
18957  name;
18958 
18959  if (attrib && (typeof attrib === 'undefined' ? 'undefined' : _typeof(attrib)) == "object" && attrib.name && attrib.name.indexOf("tabulator-") === 0) {
18960 
18961  name = attrib.name.replace("tabulator-", "");
18962 
18963  col[name] = this._attribValue(attrib.value);
18964  }
18965  }
18966 
18967  this.fieldIndex[index] = col.field;
18968 
18969  if (col.field == this.table.options.index) {
18970  this.hasIndex = true;
18971  }
18972 
18973  if (!exists) {
18974  this.table.options.columns.push(col);
18975  }
18976  }
18977  };
18978 
18979  //generate blank headers
18980  HtmlTableImport.prototype._generateBlankHeaders = function (headers, rows) {
18981  for (var index = 0; index < headers.length; index++) {
18982  var header = headers[index],
18983  col = { title: "", field: "col" + index };
18984 
18985  this.fieldIndex[index] = col.field;
18986 
18987  var width = header.getAttribute("width");
18988 
18989  if (width) {
18990  col.width = width;
18991  }
18992 
18993  this.table.options.columns.push(col);
18994  }
18995  };
18996 
18997  Tabulator.prototype.registerModule("htmlTableImport", HtmlTableImport);
18998  var HtmlTableExport = function HtmlTableExport(table) {
18999  this.table = table; //hold Tabulator object
19000  this.config = {};
19001  this.cloneTableStyle = true;
19002  this.colVisProp = "";
19003  };
19004 
19005  HtmlTableExport.prototype.genereateTable = function (config, style, visible, colVisProp) {
19006  this.cloneTableStyle = style;
19007  this.config = config || {};
19008  this.colVisProp = colVisProp;
19009 
19010  var headers = this.generateHeaderElements();
19011  var body = this.generateBodyElements(visible);
19012 
19013  var table = document.createElement("table");
19014  table.classList.add("tabulator-print-table");
19015  table.appendChild(headers);
19016  table.appendChild(body);
19017 
19018  this.mapElementStyles(this.table.element, table, ["border-top", "border-left", "border-right", "border-bottom"]);
19019 
19020  return table;
19021  };
19022 
19023  HtmlTableExport.prototype.generateColumnGroupHeaders = function () {
19024  var _this53 = this;
19025 
19026  var output = [];
19027 
19028  var columns = this.config.columnGroups !== false ? this.table.columnManager.columns : this.table.columnManager.columnsByIndex;
19029 
19030  columns.forEach(function (column) {
19031  var colData = _this53.processColumnGroup(column);
19032 
19033  if (colData) {
19034  output.push(colData);
19035  }
19036  });
19037 
19038  return output;
19039  };
19040 
19041  HtmlTableExport.prototype.processColumnGroup = function (column) {
19042  var _this54 = this;
19043 
19044  var subGroups = column.columns,
19045  maxDepth = 0;
19046 
19047  var groupData = {
19048  title: column.definition.title,
19049  column: column,
19050  depth: 1
19051  };
19052 
19053  if (subGroups.length) {
19054  groupData.subGroups = [];
19055  groupData.width = 0;
19056 
19057  subGroups.forEach(function (subGroup) {
19058  var subGroupData = _this54.processColumnGroup(subGroup);
19059 
19060  if (subGroupData) {
19061  groupData.width += subGroupData.width;
19062  groupData.subGroups.push(subGroupData);
19063 
19064  if (subGroupData.depth > maxDepth) {
19065  maxDepth = subGroupData.depth;
19066  }
19067  }
19068  });
19069 
19070  groupData.depth += maxDepth;
19071 
19072  if (!groupData.width) {
19073  return false;
19074  }
19075  } else {
19076  if (this.columnVisCheck(column)) {
19077  groupData.width = 1;
19078  } else {
19079  return false;
19080  }
19081  }
19082 
19083  return groupData;
19084  };
19085 
19086  HtmlTableExport.prototype.groupHeadersToRows = function (columns) {
19087 
19088  var headers = [],
19089  headerDepth = 0;
19090 
19091  function parseColumnGroup(column, level) {
19092 
19093  var depth = headerDepth - level;
19094 
19095  if (typeof headers[level] === "undefined") {
19096  headers[level] = [];
19097  }
19098 
19099  column.height = column.subGroups ? 1 : depth - column.depth + 1;
19100 
19101  headers[level].push(column);
19102 
19103  if (column.subGroups) {
19104  column.subGroups.forEach(function (subGroup) {
19105  parseColumnGroup(subGroup, level + 1);
19106  });
19107  }
19108  }
19109 
19110  //calculate maximum header debth
19111  columns.forEach(function (column) {
19112  if (column.depth > headerDepth) {
19113  headerDepth = column.depth;
19114  }
19115  });
19116 
19117  columns.forEach(function (column) {
19118  parseColumnGroup(column, 0);
19119  });
19120 
19121  return headers;
19122  };
19123 
19124  HtmlTableExport.prototype.generateHeaderElements = function () {
19125  var _this55 = this;
19126 
19127  var headerEl = document.createElement("thead");
19128 
19129  var rows = this.groupHeadersToRows(this.generateColumnGroupHeaders());
19130 
19131  rows.forEach(function (row) {
19132  var rowEl = document.createElement("tr");
19133 
19134  _this55.mapElementStyles(_this55.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
19135 
19136  row.forEach(function (column) {
19137  var cellEl = document.createElement("th");
19138  var classNames = column.column.definition.cssClass ? column.column.definition.cssClass.split(" ") : [];
19139 
19140  cellEl.colSpan = column.width;
19141  cellEl.rowSpan = column.height;
19142 
19143  cellEl.innerHTML = column.column.definition.title;
19144 
19145  if (_this55.cloneTableStyle) {
19146  cellEl.style.boxSizing = "border-box";
19147  }
19148 
19149  classNames.forEach(function (className) {
19150  cellEl.classList.add(className);
19151  });
19152 
19153  _this55.mapElementStyles(column.column.getElement(), cellEl, ["text-align", "border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
19154  _this55.mapElementStyles(column.column.contentElement, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom"]);
19155 
19156  if (column.column.visible) {
19157  _this55.mapElementStyles(column.column.getElement(), cellEl, ["width"]);
19158  } else {
19159  if (column.column.definition.width) {
19160  cellEl.style.width = column.column.definition.width + "px";
19161  }
19162  }
19163 
19164  if (column.column.parent) {
19165  _this55.mapElementStyles(column.column.parent.groupElement, cellEl, ["border-top"]);
19166  }
19167 
19168  rowEl.appendChild(cellEl);
19169  });
19170 
19171  headerEl.appendChild(rowEl);
19172  });
19173 
19174  return headerEl;
19175  };
19176 
19177  HtmlTableExport.prototype.generateBodyElements = function (visible) {
19178  var _this56 = this;
19179 
19180  var oddRow, evenRow, calcRow, firstRow, firstCell, firstGroup, lastCell, styleCells, styleRow;
19181 
19182  //lookup row styles
19183  if (this.cloneTableStyle && window.getComputedStyle) {
19184  oddRow = this.table.element.querySelector(".tabulator-row-odd:not(.tabulator-group):not(.tabulator-calcs)");
19185  evenRow = this.table.element.querySelector(".tabulator-row-even:not(.tabulator-group):not(.tabulator-calcs)");
19186  calcRow = this.table.element.querySelector(".tabulator-row.tabulator-calcs");
19187  firstRow = this.table.element.querySelector(".tabulator-row:not(.tabulator-group):not(.tabulator-calcs)");
19188  firstGroup = this.table.element.getElementsByClassName("tabulator-group")[0];
19189 
19190  if (firstRow) {
19191  styleCells = firstRow.getElementsByClassName("tabulator-cell");
19192  firstCell = styleCells[0];
19193  lastCell = styleCells[styleCells.length - 1];
19194  }
19195  }
19196 
19197  var bodyEl = document.createElement("tbody");
19198 
19199  var rows = visible ? this.table.rowManager.getVisibleRows(true) : this.table.rowManager.getDisplayRows();
19200  var columns = [];
19201 
19202  if (this.config.columnCalcs !== false && this.table.modExists("columnCalcs")) {
19203  if (this.table.modules.columnCalcs.topInitialized) {
19204  rows.unshift(this.table.modules.columnCalcs.topRow);
19205  }
19206 
19207  if (this.table.modules.columnCalcs.botInitialized) {
19208  rows.push(this.table.modules.columnCalcs.botRow);
19209  }
19210  }
19211 
19212  this.table.columnManager.columnsByIndex.forEach(function (column) {
19213  if (_this56.columnVisCheck(column)) {
19214  columns.push(column);
19215  }
19216  });
19217 
19218  rows = rows.filter(function (row) {
19219  switch (row.type) {
19220  case "group":
19221  return _this56.config.rowGroups !== false;
19222  break;
19223 
19224  case "calc":
19225  return _this56.config.columnCalcs !== false;
19226  break;
19227  }
19228 
19229  return true;
19230  });
19231 
19232  if (rows.length > 1000) {
19233  console.warn("It may take a long time to render an HTML table with more than 1000 rows");
19234  }
19235 
19236  rows.forEach(function (row, i) {
19237  var rowData = row.getData();
19238 
19239  var rowEl = document.createElement("tr");
19240  rowEl.classList.add("tabulator-print-table-row");
19241 
19242  switch (row.type) {
19243  case "group":
19244  var cellEl = document.createElement("td");
19245  cellEl.colSpan = columns.length;
19246  cellEl.innerHTML = row.key;
19247 
19248  rowEl.classList.add("tabulator-print-table-group");
19249 
19250  _this56.mapElementStyles(firstGroup, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
19251  _this56.mapElementStyles(firstGroup, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom"]);
19252  rowEl.appendChild(cellEl);
19253  break;
19254 
19255  case "calc":
19256  rowEl.classList.add("tabulator-print-table-calcs");
19257 
19258  case "row":
19259  columns.forEach(function (column) {
19260  var cellEl = document.createElement("td");
19261 
19262  var value = column.getFieldValue(rowData);
19263 
19264  var cellWrapper = {
19265  modules: {},
19266  getValue: function getValue() {
19267  return value;
19268  },
19269  getField: function getField() {
19270  return column.definition.field;
19271  },
19272  getElement: function getElement() {
19273  return cellEl;
19274  },
19275  getColumn: function getColumn() {
19276  return column.getComponent();
19277  },
19278  getData: function getData() {
19279  return rowData;
19280  },
19281  getRow: function getRow() {
19282  return row.getComponent();
19283  },
19284  getComponent: function getComponent() {
19285  return cellWrapper;
19286  },
19287  column: column
19288  };
19289 
19290  var classNames = column.definition.cssClass ? column.definition.cssClass.split(" ") : [];
19291 
19292  classNames.forEach(function (className) {
19293  cellEl.classList.add(className);
19294  });
19295 
19296  if (_this56.table.modExists("format")) {
19297  value = _this56.table.modules.format.formatValue(cellWrapper);
19298  } else {
19299  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
19300  case "object":
19301  value = JSON.stringify(value);
19302  break;
19303 
19304  case "undefined":
19305  case "null":
19306  value = "";
19307  break;
19308 
19309  default:
19310  value = value;
19311  }
19312  }
19313 
19314  if (value instanceof Node) {
19315  cellEl.appendChild(value);
19316  } else {
19317  cellEl.innerHTML = value;
19318  }
19319 
19320  if (firstCell) {
19321  _this56.mapElementStyles(firstCell, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom", "border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "text-align"]);
19322  }
19323 
19324  rowEl.appendChild(cellEl);
19325  });
19326 
19327  styleRow = row.type == "calc" ? calcRow : i % 2 && evenRow ? evenRow : oddRow;
19328 
19329  _this56.mapElementStyles(styleRow, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
19330  break;
19331  }
19332 
19333  bodyEl.appendChild(rowEl);
19334  });
19335 
19336  return bodyEl;
19337  };
19338 
19339  HtmlTableExport.prototype.columnVisCheck = function (column) {
19340  return column.definition[this.colVisProp] !== false && (column.visible || !column.visible && column.definition[this.colVisProp]);
19341  };
19342 
19343  HtmlTableExport.prototype.getHtml = function (visible, style, config) {
19344  var holder = document.createElement("div");
19345 
19346  holder.appendChild(this.genereateTable(config || this.table.options.htmlOutputConfig, style, visible, "htmlOutput"));
19347 
19348  return holder.innerHTML;
19349  };
19350 
19351  HtmlTableExport.prototype.mapElementStyles = function (from, to, props) {
19352  if (this.cloneTableStyle && from && to) {
19353 
19354  var lookup = {
19355  "background-color": "backgroundColor",
19356  "color": "fontColor",
19357  "width": "width",
19358  "font-weight": "fontWeight",
19359  "font-family": "fontFamily",
19360  "font-size": "fontSize",
19361  "text-align": "textAlign",
19362  "border-top": "borderTop",
19363  "border-left": "borderLeft",
19364  "border-right": "borderRight",
19365  "border-bottom": "borderBottom",
19366  "padding-top": "paddingTop",
19367  "padding-left": "paddingLeft",
19368  "padding-right": "paddingRight",
19369  "padding-bottom": "paddingBottom"
19370  };
19371 
19372  if (window.getComputedStyle) {
19373  var fromStyle = window.getComputedStyle(from);
19374 
19375  props.forEach(function (prop) {
19376  to.style[lookup[prop]] = fromStyle.getPropertyValue(prop);
19377  });
19378  }
19379  }
19380  };
19381 
19382  Tabulator.prototype.registerModule("htmlTableExport", HtmlTableExport);
19383 
19384  var Keybindings = function Keybindings(table) {
19385  this.table = table; //hold Tabulator object
19386  this.watchKeys = null;
19387  this.pressedKeys = null;
19388  this.keyupBinding = false;
19389  this.keydownBinding = false;
19390  };
19391 
19392  Keybindings.prototype.initialize = function () {
19393  var bindings = this.table.options.keybindings,
19394  mergedBindings = {};
19395 
19396  this.watchKeys = {};
19397  this.pressedKeys = [];
19398 
19399  if (bindings !== false) {
19400 
19401  for (var key in this.bindings) {
19402  mergedBindings[key] = this.bindings[key];
19403  }
19404 
19405  if (Object.keys(bindings).length) {
19406 
19407  for (var _key in bindings) {
19408  mergedBindings[_key] = bindings[_key];
19409  }
19410  }
19411 
19412  this.mapBindings(mergedBindings);
19413  this.bindEvents();
19414  }
19415  };
19416 
19417  Keybindings.prototype.mapBindings = function (bindings) {
19418  var _this57 = this;
19419 
19420  var self = this;
19421 
19422  var _loop2 = function _loop2(key) {
19423 
19424  if (_this57.actions[key]) {
19425 
19426  if (bindings[key]) {
19427 
19428  if (_typeof(bindings[key]) !== "object") {
19429  bindings[key] = [bindings[key]];
19430  }
19431 
19432  bindings[key].forEach(function (binding) {
19433  self.mapBinding(key, binding);
19434  });
19435  }
19436  } else {
19437  console.warn("Key Binding Error - no such action:", key);
19438  }
19439  };
19440 
19441  for (var key in bindings) {
19442  _loop2(key);
19443  }
19444  };
19445 
19446  Keybindings.prototype.mapBinding = function (action, symbolsList) {
19447  var self = this;
19448 
19449  var binding = {
19450  action: this.actions[action],
19451  keys: [],
19452  ctrl: false,
19453  shift: false
19454  };
19455 
19456  var symbols = symbolsList.toString().toLowerCase().split(" ").join("").split("+");
19457 
19458  symbols.forEach(function (symbol) {
19459  switch (symbol) {
19460  case "ctrl":
19461  binding.ctrl = true;
19462  break;
19463 
19464  case "shift":
19465  binding.shift = true;
19466  break;
19467 
19468  default:
19469  symbol = parseInt(symbol);
19470  binding.keys.push(symbol);
19471 
19472  if (!self.watchKeys[symbol]) {
19473  self.watchKeys[symbol] = [];
19474  }
19475 
19476  self.watchKeys[symbol].push(binding);
19477  }
19478  });
19479  };
19480 
19481  Keybindings.prototype.bindEvents = function () {
19482  var self = this;
19483 
19484  this.keyupBinding = function (e) {
19485  var code = e.keyCode;
19486  var bindings = self.watchKeys[code];
19487 
19488  if (bindings) {
19489 
19490  self.pressedKeys.push(code);
19491 
19492  bindings.forEach(function (binding) {
19493  self.checkBinding(e, binding);
19494  });
19495  }
19496  };
19497 
19498  this.keydownBinding = function (e) {
19499  var code = e.keyCode;
19500  var bindings = self.watchKeys[code];
19501 
19502  if (bindings) {
19503 
19504  var index = self.pressedKeys.indexOf(code);
19505 
19506  if (index > -1) {
19507  self.pressedKeys.splice(index, 1);
19508  }
19509  }
19510  };
19511 
19512  this.table.element.addEventListener("keydown", this.keyupBinding);
19513 
19514  this.table.element.addEventListener("keyup", this.keydownBinding);
19515  };
19516 
19517  Keybindings.prototype.clearBindings = function () {
19518  if (this.keyupBinding) {
19519  this.table.element.removeEventListener("keydown", this.keyupBinding);
19520  }
19521 
19522  if (this.keydownBinding) {
19523  this.table.element.removeEventListener("keyup", this.keydownBinding);
19524  }
19525  };
19526 
19527  Keybindings.prototype.checkBinding = function (e, binding) {
19528  var self = this,
19529  match = true;
19530 
19531  if (e.ctrlKey == binding.ctrl && e.shiftKey == binding.shift) {
19532  binding.keys.forEach(function (key) {
19533  var index = self.pressedKeys.indexOf(key);
19534 
19535  if (index == -1) {
19536  match = false;
19537  }
19538  });
19539 
19540  if (match) {
19541  binding.action.call(self, e);
19542  }
19543 
19544  return true;
19545  }
19546 
19547  return false;
19548  };
19549 
19550  //default bindings
19551  Keybindings.prototype.bindings = {
19552  navPrev: "shift + 9",
19553  navNext: 9,
19554  navUp: 38,
19555  navDown: 40,
19556  scrollPageUp: 33,
19557  scrollPageDown: 34,
19558  scrollToStart: 36,
19559  scrollToEnd: 35,
19560  undo: "ctrl + 90",
19561  redo: "ctrl + 89",
19562  copyToClipboard: "ctrl + 67"
19563  };
19564 
19565  //default actions
19566  Keybindings.prototype.actions = {
19567  keyBlock: function keyBlock(e) {
19568  e.stopPropagation();
19569  e.preventDefault();
19570  },
19571  scrollPageUp: function scrollPageUp(e) {
19572  var rowManager = this.table.rowManager,
19573  newPos = rowManager.scrollTop - rowManager.height,
19574  scrollMax = rowManager.element.scrollHeight;
19575 
19576  e.preventDefault();
19577 
19578  if (rowManager.displayRowsCount) {
19579  if (newPos >= 0) {
19580  rowManager.element.scrollTop = newPos;
19581  } else {
19582  rowManager.scrollToRow(rowManager.getDisplayRows()[0]);
19583  }
19584  }
19585 
19586  this.table.element.focus();
19587  },
19588  scrollPageDown: function scrollPageDown(e) {
19589  var rowManager = this.table.rowManager,
19590  newPos = rowManager.scrollTop + rowManager.height,
19591  scrollMax = rowManager.element.scrollHeight;
19592 
19593  e.preventDefault();
19594 
19595  if (rowManager.displayRowsCount) {
19596  if (newPos <= scrollMax) {
19597  rowManager.element.scrollTop = newPos;
19598  } else {
19599  rowManager.scrollToRow(rowManager.getDisplayRows()[rowManager.displayRowsCount - 1]);
19600  }
19601  }
19602 
19603  this.table.element.focus();
19604  },
19605  scrollToStart: function scrollToStart(e) {
19606  var rowManager = this.table.rowManager;
19607 
19608  e.preventDefault();
19609 
19610  if (rowManager.displayRowsCount) {
19611  rowManager.scrollToRow(rowManager.getDisplayRows()[0]);
19612  }
19613 
19614  this.table.element.focus();
19615  },
19616  scrollToEnd: function scrollToEnd(e) {
19617  var rowManager = this.table.rowManager;
19618 
19619  e.preventDefault();
19620 
19621  if (rowManager.displayRowsCount) {
19622  rowManager.scrollToRow(rowManager.getDisplayRows()[rowManager.displayRowsCount - 1]);
19623  }
19624 
19625  this.table.element.focus();
19626  },
19627  navPrev: function navPrev(e) {
19628  var cell = false;
19629 
19630  if (this.table.modExists("edit")) {
19631  cell = this.table.modules.edit.currentCell;
19632 
19633  if (cell) {
19634  e.preventDefault();
19635  cell.nav().prev();
19636  }
19637  }
19638  },
19639 
19640  navNext: function navNext(e) {
19641  var cell = false;
19642  var newRow = this.table.options.tabEndNewRow;
19643  var nav;
19644 
19645  if (this.table.modExists("edit")) {
19646  cell = this.table.modules.edit.currentCell;
19647 
19648  if (cell) {
19649  e.preventDefault();
19650 
19651  nav = cell.nav();
19652 
19653  if (!nav.next()) {
19654  if (newRow) {
19655  if (newRow === true) {
19656  newRow = this.table.addRow({});
19657  } else {
19658  if (typeof newRow == "function") {
19659  newRow = this.table.addRow(newRow(cell.row.getComponent()));
19660  } else {
19661  newRow = this.table.addRow(newRow);
19662  }
19663  }
19664 
19665  newRow.then(function () {
19666  nav.next();
19667  });
19668  }
19669  }
19670  }
19671  }
19672  },
19673 
19674  navLeft: function navLeft(e) {
19675  var cell = false;
19676 
19677  if (this.table.modExists("edit")) {
19678  cell = this.table.modules.edit.currentCell;
19679 
19680  if (cell) {
19681  e.preventDefault();
19682  cell.nav().left();
19683  }
19684  }
19685  },
19686 
19687  navRight: function navRight(e) {
19688  var cell = false;
19689 
19690  if (this.table.modExists("edit")) {
19691  cell = this.table.modules.edit.currentCell;
19692 
19693  if (cell) {
19694  e.preventDefault();
19695  cell.nav().right();
19696  }
19697  }
19698  },
19699 
19700  navUp: function navUp(e) {
19701  var cell = false;
19702 
19703  if (this.table.modExists("edit")) {
19704  cell = this.table.modules.edit.currentCell;
19705 
19706  if (cell) {
19707  e.preventDefault();
19708  cell.nav().up();
19709  }
19710  }
19711  },
19712 
19713  navDown: function navDown(e) {
19714  var cell = false;
19715 
19716  if (this.table.modExists("edit")) {
19717  cell = this.table.modules.edit.currentCell;
19718 
19719  if (cell) {
19720  e.preventDefault();
19721  cell.nav().down();
19722  }
19723  }
19724  },
19725 
19726  undo: function undo(e) {
19727  var cell = false;
19728  if (this.table.options.history && this.table.modExists("history") && this.table.modExists("edit")) {
19729 
19730  cell = this.table.modules.edit.currentCell;
19731 
19732  if (!cell) {
19733  e.preventDefault();
19734  this.table.modules.history.undo();
19735  }
19736  }
19737  },
19738 
19739  redo: function redo(e) {
19740  var cell = false;
19741  if (this.table.options.history && this.table.modExists("history") && this.table.modExists("edit")) {
19742 
19743  cell = this.table.modules.edit.currentCell;
19744 
19745  if (!cell) {
19746  e.preventDefault();
19747  this.table.modules.history.redo();
19748  }
19749  }
19750  },
19751 
19752  copyToClipboard: function copyToClipboard(e) {
19753  if (!this.table.modules.edit.currentCell) {
19754  if (this.table.modExists("clipboard", true)) {
19755  this.table.modules.clipboard.copy(!this.table.options.selectable || this.table.options.selectable == "highlight" ? "active" : "selected", null, null, null, true);
19756  }
19757  }
19758  }
19759  };
19760 
19761  Tabulator.prototype.registerModule("keybindings", Keybindings);
19762  var MoveColumns = function MoveColumns(table) {
19763  this.table = table; //hold Tabulator object
19764  this.placeholderElement = this.createPlaceholderElement();
19765  this.hoverElement = false; //floating column header element
19766  this.checkTimeout = false; //click check timeout holder
19767  this.checkPeriod = 250; //period to wait on mousedown to consider this a move and not a click
19768  this.moving = false; //currently moving column
19769  this.toCol = false; //destination column
19770  this.toColAfter = false; //position of moving column relative to the desitnation column
19771  this.startX = 0; //starting position within header element
19772  this.autoScrollMargin = 40; //auto scroll on edge when within margin
19773  this.autoScrollStep = 5; //auto scroll distance in pixels
19774  this.autoScrollTimeout = false; //auto scroll timeout
19775  this.touchMove = false;
19776 
19777  this.moveHover = this.moveHover.bind(this);
19778  this.endMove = this.endMove.bind(this);
19779  };
19780 
19781  MoveColumns.prototype.createPlaceholderElement = function () {
19782  var el = document.createElement("div");
19783 
19784  el.classList.add("tabulator-col");
19785  el.classList.add("tabulator-col-placeholder");
19786 
19787  return el;
19788  };
19789 
19790  MoveColumns.prototype.initializeColumn = function (column) {
19791  var self = this,
19792  config = {},
19793  colEl;
19794 
19795  if (!column.modules.frozen) {
19796 
19797  colEl = column.getElement();
19798 
19799  config.mousemove = function (e) {
19800  if (column.parent === self.moving.parent) {
19801  if ((self.touchMove ? e.touches[0].pageX : e.pageX) - Tabulator.prototype.helpers.elOffset(colEl).left + self.table.columnManager.element.scrollLeft > column.getWidth() / 2) {
19802  if (self.toCol !== column || !self.toColAfter) {
19803  colEl.parentNode.insertBefore(self.placeholderElement, colEl.nextSibling);
19804  self.moveColumn(column, true);
19805  }
19806  } else {
19807  if (self.toCol !== column || self.toColAfter) {
19808  colEl.parentNode.insertBefore(self.placeholderElement, colEl);
19809  self.moveColumn(column, false);
19810  }
19811  }
19812  }
19813  }.bind(self);
19814 
19815  colEl.addEventListener("mousedown", function (e) {
19816  self.touchMove = false;
19817  if (e.which === 1) {
19818  self.checkTimeout = setTimeout(function () {
19819  self.startMove(e, column);
19820  }, self.checkPeriod);
19821  }
19822  });
19823 
19824  colEl.addEventListener("mouseup", function (e) {
19825  if (e.which === 1) {
19826  if (self.checkTimeout) {
19827  clearTimeout(self.checkTimeout);
19828  }
19829  }
19830  });
19831 
19832  self.bindTouchEvents(column);
19833  }
19834 
19835  column.modules.moveColumn = config;
19836  };
19837 
19838  MoveColumns.prototype.bindTouchEvents = function (column) {
19839  var self = this,
19840  colEl = column.getElement(),
19841  startXMove = false,
19842  //shifting center position of the cell
19843  dir = false,
19844  currentCol,
19845  nextCol,
19846  prevCol,
19847  nextColWidth,
19848  prevColWidth,
19849  nextColWidthLast,
19850  prevColWidthLast;
19851 
19852  colEl.addEventListener("touchstart", function (e) {
19853  self.checkTimeout = setTimeout(function () {
19854  self.touchMove = true;
19855  currentCol = column;
19856  nextCol = column.nextColumn();
19857  nextColWidth = nextCol ? nextCol.getWidth() / 2 : 0;
19858  prevCol = column.prevColumn();
19859  prevColWidth = prevCol ? prevCol.getWidth() / 2 : 0;
19860  nextColWidthLast = 0;
19861  prevColWidthLast = 0;
19862  startXMove = false;
19863 
19864  self.startMove(e, column);
19865  }, self.checkPeriod);
19866  }, { passive: true });
19867 
19868  colEl.addEventListener("touchmove", function (e) {
19869  var halfCol, diff, moveToCol;
19870 
19871  if (self.moving) {
19872  self.moveHover(e);
19873 
19874  if (!startXMove) {
19875  startXMove = e.touches[0].pageX;
19876  }
19877 
19878  diff = e.touches[0].pageX - startXMove;
19879 
19880  if (diff > 0) {
19881  if (nextCol && diff - nextColWidthLast > nextColWidth) {
19882  moveToCol = nextCol;
19883 
19884  if (moveToCol !== column) {
19885  startXMove = e.touches[0].pageX;
19886  moveToCol.getElement().parentNode.insertBefore(self.placeholderElement, moveToCol.getElement().nextSibling);
19887  self.moveColumn(moveToCol, true);
19888  }
19889  }
19890  } else {
19891  if (prevCol && -diff - prevColWidthLast > prevColWidth) {
19892  moveToCol = prevCol;
19893 
19894  if (moveToCol !== column) {
19895  startXMove = e.touches[0].pageX;
19896  moveToCol.getElement().parentNode.insertBefore(self.placeholderElement, moveToCol.getElement());
19897  self.moveColumn(moveToCol, false);
19898  }
19899  }
19900  }
19901 
19902  if (moveToCol) {
19903  currentCol = moveToCol;
19904  nextCol = moveToCol.nextColumn();
19905  nextColWidthLast = nextColWidth;
19906  nextColWidth = nextCol ? nextCol.getWidth() / 2 : 0;
19907  prevCol = moveToCol.prevColumn();
19908  prevColWidthLast = prevColWidth;
19909  prevColWidth = prevCol ? prevCol.getWidth() / 2 : 0;
19910  }
19911  }
19912  }, { passive: true });
19913 
19914  colEl.addEventListener("touchend", function (e) {
19915  if (self.checkTimeout) {
19916  clearTimeout(self.checkTimeout);
19917  }
19918  if (self.moving) {
19919  self.endMove(e);
19920  }
19921  });
19922  };
19923 
19924  MoveColumns.prototype.startMove = function (e, column) {
19925  var element = column.getElement();
19926 
19927  this.moving = column;
19928  this.startX = (this.touchMove ? e.touches[0].pageX : e.pageX) - Tabulator.prototype.helpers.elOffset(element).left;
19929 
19930  this.table.element.classList.add("tabulator-block-select");
19931 
19932  //create placeholder
19933  this.placeholderElement.style.width = column.getWidth() + "px";
19934  this.placeholderElement.style.height = column.getHeight() + "px";
19935 
19936  element.parentNode.insertBefore(this.placeholderElement, element);
19937  element.parentNode.removeChild(element);
19938 
19939  //create hover element
19940  this.hoverElement = element.cloneNode(true);
19941  this.hoverElement.classList.add("tabulator-moving");
19942 
19943  this.table.columnManager.getElement().appendChild(this.hoverElement);
19944 
19945  this.hoverElement.style.left = "0";
19946  this.hoverElement.style.bottom = "0";
19947 
19948  if (!this.touchMove) {
19949  this._bindMouseMove();
19950 
19951  document.body.addEventListener("mousemove", this.moveHover);
19952  document.body.addEventListener("mouseup", this.endMove);
19953  }
19954 
19955  this.moveHover(e);
19956  };
19957 
19958  MoveColumns.prototype._bindMouseMove = function () {
19959  this.table.columnManager.columnsByIndex.forEach(function (column) {
19960  if (column.modules.moveColumn.mousemove) {
19961  column.getElement().addEventListener("mousemove", column.modules.moveColumn.mousemove);
19962  }
19963  });
19964  };
19965 
19966  MoveColumns.prototype._unbindMouseMove = function () {
19967  this.table.columnManager.columnsByIndex.forEach(function (column) {
19968  if (column.modules.moveColumn.mousemove) {
19969  column.getElement().removeEventListener("mousemove", column.modules.moveColumn.mousemove);
19970  }
19971  });
19972  };
19973 
19974  MoveColumns.prototype.moveColumn = function (column, after) {
19975  var movingCells = this.moving.getCells();
19976 
19977  this.toCol = column;
19978  this.toColAfter = after;
19979 
19980  if (after) {
19981  column.getCells().forEach(function (cell, i) {
19982  var cellEl = cell.getElement();
19983  cellEl.parentNode.insertBefore(movingCells[i].getElement(), cellEl.nextSibling);
19984  });
19985  } else {
19986  column.getCells().forEach(function (cell, i) {
19987  var cellEl = cell.getElement();
19988  cellEl.parentNode.insertBefore(movingCells[i].getElement(), cellEl);
19989  });
19990  }
19991  };
19992 
19993  MoveColumns.prototype.endMove = function (e) {
19994  if (e.which === 1 || this.touchMove) {
19995  this._unbindMouseMove();
19996 
19997  this.placeholderElement.parentNode.insertBefore(this.moving.getElement(), this.placeholderElement.nextSibling);
19998  this.placeholderElement.parentNode.removeChild(this.placeholderElement);
19999  this.hoverElement.parentNode.removeChild(this.hoverElement);
20000 
20001  this.table.element.classList.remove("tabulator-block-select");
20002 
20003  if (this.toCol) {
20004  this.table.columnManager.moveColumnActual(this.moving, this.toCol, this.toColAfter);
20005  }
20006 
20007  this.moving = false;
20008  this.toCol = false;
20009  this.toColAfter = false;
20010 
20011  if (!this.touchMove) {
20012  document.body.removeEventListener("mousemove", this.moveHover);
20013  document.body.removeEventListener("mouseup", this.endMove);
20014  }
20015  }
20016  };
20017 
20018  MoveColumns.prototype.moveHover = function (e) {
20019  var self = this,
20020  columnHolder = self.table.columnManager.getElement(),
20021  scrollLeft = columnHolder.scrollLeft,
20022  xPos = (self.touchMove ? e.touches[0].pageX : e.pageX) - Tabulator.prototype.helpers.elOffset(columnHolder).left + scrollLeft,
20023  scrollPos;
20024 
20025  self.hoverElement.style.left = xPos - self.startX + "px";
20026 
20027  if (xPos - scrollLeft < self.autoScrollMargin) {
20028  if (!self.autoScrollTimeout) {
20029  self.autoScrollTimeout = setTimeout(function () {
20030  scrollPos = Math.max(0, scrollLeft - 5);
20031  self.table.rowManager.getElement().scrollLeft = scrollPos;
20032  self.autoScrollTimeout = false;
20033  }, 1);
20034  }
20035  }
20036 
20037  if (scrollLeft + columnHolder.clientWidth - xPos < self.autoScrollMargin) {
20038  if (!self.autoScrollTimeout) {
20039  self.autoScrollTimeout = setTimeout(function () {
20040  scrollPos = Math.min(columnHolder.clientWidth, scrollLeft + 5);
20041  self.table.rowManager.getElement().scrollLeft = scrollPos;
20042  self.autoScrollTimeout = false;
20043  }, 1);
20044  }
20045  }
20046  };
20047 
20048  Tabulator.prototype.registerModule("moveColumn", MoveColumns);
20049 
20050  var MoveRows = function MoveRows(table) {
20051 
20052  this.table = table; //hold Tabulator object
20053  this.placeholderElement = this.createPlaceholderElement();
20054  this.hoverElement = false; //floating row header element
20055  this.checkTimeout = false; //click check timeout holder
20056  this.checkPeriod = 150; //period to wait on mousedown to consider this a move and not a click
20057  this.moving = false; //currently moving row
20058  this.toRow = false; //destination row
20059  this.toRowAfter = false; //position of moving row relative to the desitnation row
20060  this.hasHandle = false; //row has handle instead of fully movable row
20061  this.startY = 0; //starting Y position within header element
20062  this.startX = 0; //starting X position within header element
20063 
20064  this.moveHover = this.moveHover.bind(this);
20065  this.endMove = this.endMove.bind(this);
20066  this.tableRowDropEvent = false;
20067 
20068  this.touchMove = false;
20069 
20070  this.connection = false;
20071  this.connections = [];
20072 
20073  this.connectedTable = false;
20074  this.connectedRow = false;
20075  };
20076 
20077  MoveRows.prototype.createPlaceholderElement = function () {
20078  var el = document.createElement("div");
20079 
20080  el.classList.add("tabulator-row");
20081  el.classList.add("tabulator-row-placeholder");
20082 
20083  return el;
20084  };
20085 
20086  MoveRows.prototype.initialize = function (handle) {
20087  this.connection = this.table.options.movableRowsConnectedTables;
20088  };
20089 
20090  MoveRows.prototype.setHandle = function (handle) {
20091  this.hasHandle = handle;
20092  };
20093 
20094  MoveRows.prototype.initializeGroupHeader = function (group) {
20095  var self = this,
20096  config = {},
20097  rowEl;
20098 
20099  //inter table drag drop
20100  config.mouseup = function (e) {
20101  self.tableRowDrop(e, row);
20102  }.bind(self);
20103 
20104  //same table drag drop
20105  config.mousemove = function (e) {
20106  if (e.pageY - Tabulator.prototype.helpers.elOffset(group.element).top + self.table.rowManager.element.scrollTop > group.getHeight() / 2) {
20107  if (self.toRow !== group || !self.toRowAfter) {
20108  var rowEl = group.getElement();
20109  rowEl.parentNode.insertBefore(self.placeholderElement, rowEl.nextSibling);
20110  self.moveRow(group, true);
20111  }
20112  } else {
20113  if (self.toRow !== group || self.toRowAfter) {
20114  var rowEl = group.getElement();
20115  if (rowEl.previousSibling) {
20116  rowEl.parentNode.insertBefore(self.placeholderElement, rowEl);
20117  self.moveRow(group, false);
20118  }
20119  }
20120  }
20121  }.bind(self);
20122 
20123  group.modules.moveRow = config;
20124  };
20125 
20126  MoveRows.prototype.initializeRow = function (row) {
20127  var self = this,
20128  config = {},
20129  rowEl;
20130 
20131  //inter table drag drop
20132  config.mouseup = function (e) {
20133  self.tableRowDrop(e, row);
20134  }.bind(self);
20135 
20136  //same table drag drop
20137  config.mousemove = function (e) {
20138  if (e.pageY - Tabulator.prototype.helpers.elOffset(row.element).top + self.table.rowManager.element.scrollTop > row.getHeight() / 2) {
20139  if (self.toRow !== row || !self.toRowAfter) {
20140  var rowEl = row.getElement();
20141  rowEl.parentNode.insertBefore(self.placeholderElement, rowEl.nextSibling);
20142  self.moveRow(row, true);
20143  }
20144  } else {
20145  if (self.toRow !== row || self.toRowAfter) {
20146  var rowEl = row.getElement();
20147  rowEl.parentNode.insertBefore(self.placeholderElement, rowEl);
20148  self.moveRow(row, false);
20149  }
20150  }
20151  }.bind(self);
20152 
20153  if (!this.hasHandle) {
20154 
20155  rowEl = row.getElement();
20156 
20157  rowEl.addEventListener("mousedown", function (e) {
20158  if (e.which === 1) {
20159  self.checkTimeout = setTimeout(function () {
20160  self.startMove(e, row);
20161  }, self.checkPeriod);
20162  }
20163  });
20164 
20165  rowEl.addEventListener("mouseup", function (e) {
20166  if (e.which === 1) {
20167  if (self.checkTimeout) {
20168  clearTimeout(self.checkTimeout);
20169  }
20170  }
20171  });
20172 
20173  this.bindTouchEvents(row, row.getElement());
20174  }
20175 
20176  row.modules.moveRow = config;
20177  };
20178 
20179  MoveRows.prototype.initializeCell = function (cell) {
20180  var self = this,
20181  cellEl = cell.getElement();
20182 
20183  cellEl.addEventListener("mousedown", function (e) {
20184  if (e.which === 1) {
20185  self.checkTimeout = setTimeout(function () {
20186  self.startMove(e, cell.row);
20187  }, self.checkPeriod);
20188  }
20189  });
20190 
20191  cellEl.addEventListener("mouseup", function (e) {
20192  if (e.which === 1) {
20193  if (self.checkTimeout) {
20194  clearTimeout(self.checkTimeout);
20195  }
20196  }
20197  });
20198 
20199  this.bindTouchEvents(cell.row, cell.getElement());
20200  };
20201 
20202  MoveRows.prototype.bindTouchEvents = function (row, element) {
20203  var self = this,
20204  startYMove = false,
20205  //shifting center position of the cell
20206  dir = false,
20207  currentRow,
20208  nextRow,
20209  prevRow,
20210  nextRowHeight,
20211  prevRowHeight,
20212  nextRowHeightLast,
20213  prevRowHeightLast;
20214 
20215  element.addEventListener("touchstart", function (e) {
20216  self.checkTimeout = setTimeout(function () {
20217  self.touchMove = true;
20218  currentRow = row;
20219  nextRow = row.nextRow();
20220  nextRowHeight = nextRow ? nextRow.getHeight() / 2 : 0;
20221  prevRow = row.prevRow();
20222  prevRowHeight = prevRow ? prevRow.getHeight() / 2 : 0;
20223  nextRowHeightLast = 0;
20224  prevRowHeightLast = 0;
20225  startYMove = false;
20226 
20227  self.startMove(e, row);
20228  }, self.checkPeriod);
20229  }, { passive: true });
20230  this.moving, this.toRow, this.toRowAfter;
20231  element.addEventListener("touchmove", function (e) {
20232 
20233  var halfCol, diff, moveToRow;
20234 
20235  if (self.moving) {
20236  e.preventDefault();
20237 
20238  self.moveHover(e);
20239 
20240  if (!startYMove) {
20241  startYMove = e.touches[0].pageY;
20242  }
20243 
20244  diff = e.touches[0].pageY - startYMove;
20245 
20246  if (diff > 0) {
20247  if (nextRow && diff - nextRowHeightLast > nextRowHeight) {
20248  moveToRow = nextRow;
20249 
20250  if (moveToRow !== row) {
20251  startYMove = e.touches[0].pageY;
20252  moveToRow.getElement().parentNode.insertBefore(self.placeholderElement, moveToRow.getElement().nextSibling);
20253  self.moveRow(moveToRow, true);
20254  }
20255  }
20256  } else {
20257  if (prevRow && -diff - prevRowHeightLast > prevRowHeight) {
20258  moveToRow = prevRow;
20259 
20260  if (moveToRow !== row) {
20261  startYMove = e.touches[0].pageY;
20262  moveToRow.getElement().parentNode.insertBefore(self.placeholderElement, moveToRow.getElement());
20263  self.moveRow(moveToRow, false);
20264  }
20265  }
20266  }
20267 
20268  if (moveToRow) {
20269  currentRow = moveToRow;
20270  nextRow = moveToRow.nextRow();
20271  nextRowHeightLast = nextRowHeight;
20272  nextRowHeight = nextRow ? nextRow.getHeight() / 2 : 0;
20273  prevRow = moveToRow.prevRow();
20274  prevRowHeightLast = prevRowHeight;
20275  prevRowHeight = prevRow ? prevRow.getHeight() / 2 : 0;
20276  }
20277  }
20278  });
20279 
20280  element.addEventListener("touchend", function (e) {
20281  if (self.checkTimeout) {
20282  clearTimeout(self.checkTimeout);
20283  }
20284  if (self.moving) {
20285  self.endMove(e);
20286  self.touchMove = false;
20287  }
20288  });
20289  };
20290 
20291  MoveRows.prototype._bindMouseMove = function () {
20292  var self = this;
20293 
20294  self.table.rowManager.getDisplayRows().forEach(function (row) {
20295  if ((row.type === "row" || row.type === "group") && row.modules.moveRow.mousemove) {
20296  row.getElement().addEventListener("mousemove", row.modules.moveRow.mousemove);
20297  }
20298  });
20299  };
20300 
20301  MoveRows.prototype._unbindMouseMove = function () {
20302  var self = this;
20303 
20304  self.table.rowManager.getDisplayRows().forEach(function (row) {
20305  if ((row.type === "row" || row.type === "group") && row.modules.moveRow.mousemove) {
20306  row.getElement().removeEventListener("mousemove", row.modules.moveRow.mousemove);
20307  }
20308  });
20309  };
20310 
20311  MoveRows.prototype.startMove = function (e, row) {
20312  var element = row.getElement();
20313 
20314  this.setStartPosition(e, row);
20315 
20316  this.moving = row;
20317 
20318  this.table.element.classList.add("tabulator-block-select");
20319 
20320  //create placeholder
20321  this.placeholderElement.style.width = row.getWidth() + "px";
20322  this.placeholderElement.style.height = row.getHeight() + "px";
20323 
20324  if (!this.connection) {
20325  element.parentNode.insertBefore(this.placeholderElement, element);
20326  element.parentNode.removeChild(element);
20327  } else {
20328  this.table.element.classList.add("tabulator-movingrow-sending");
20329  this.connectToTables(row);
20330  }
20331 
20332  //create hover element
20333  this.hoverElement = element.cloneNode(true);
20334  this.hoverElement.classList.add("tabulator-moving");
20335 
20336  if (this.connection) {
20337  document.body.appendChild(this.hoverElement);
20338  this.hoverElement.style.left = "0";
20339  this.hoverElement.style.top = "0";
20340  this.hoverElement.style.width = this.table.element.clientWidth + "px";
20341  this.hoverElement.style.whiteSpace = "nowrap";
20342  this.hoverElement.style.overflow = "hidden";
20343  this.hoverElement.style.pointerEvents = "none";
20344  } else {
20345  this.table.rowManager.getTableElement().appendChild(this.hoverElement);
20346 
20347  this.hoverElement.style.left = "0";
20348  this.hoverElement.style.top = "0";
20349 
20350  this._bindMouseMove();
20351  }
20352 
20353  document.body.addEventListener("mousemove", this.moveHover);
20354  document.body.addEventListener("mouseup", this.endMove);
20355 
20356  this.moveHover(e);
20357  };
20358 
20359  MoveRows.prototype.setStartPosition = function (e, row) {
20360  var pageX = this.touchMove ? e.touches[0].pageX : e.pageX,
20361  pageY = this.touchMove ? e.touches[0].pageY : e.pageY,
20362  element,
20363  position;
20364 
20365  element = row.getElement();
20366  if (this.connection) {
20367  position = element.getBoundingClientRect();
20368 
20369  this.startX = position.left - pageX + window.pageXOffset;
20370  this.startY = position.top - pageY + window.pageYOffset;
20371  } else {
20372  this.startY = pageY - element.getBoundingClientRect().top;
20373  }
20374  };
20375 
20376  MoveRows.prototype.endMove = function (e) {
20377  if (!e || e.which === 1 || this.touchMove) {
20378  this._unbindMouseMove();
20379 
20380  if (!this.connection) {
20381  this.placeholderElement.parentNode.insertBefore(this.moving.getElement(), this.placeholderElement.nextSibling);
20382  this.placeholderElement.parentNode.removeChild(this.placeholderElement);
20383  }
20384 
20385  this.hoverElement.parentNode.removeChild(this.hoverElement);
20386 
20387  this.table.element.classList.remove("tabulator-block-select");
20388 
20389  if (this.toRow) {
20390  this.table.rowManager.moveRow(this.moving, this.toRow, this.toRowAfter);
20391  }
20392 
20393  this.moving = false;
20394  this.toRow = false;
20395  this.toRowAfter = false;
20396 
20397  document.body.removeEventListener("mousemove", this.moveHover);
20398  document.body.removeEventListener("mouseup", this.endMove);
20399 
20400  if (this.connection) {
20401  this.table.element.classList.remove("tabulator-movingrow-sending");
20402  this.disconnectFromTables();
20403  }
20404  }
20405  };
20406 
20407  MoveRows.prototype.moveRow = function (row, after) {
20408  this.toRow = row;
20409  this.toRowAfter = after;
20410  };
20411 
20412  MoveRows.prototype.moveHover = function (e) {
20413  if (this.connection) {
20414  this.moveHoverConnections.call(this, e);
20415  } else {
20416  this.moveHoverTable.call(this, e);
20417  }
20418  };
20419 
20420  MoveRows.prototype.moveHoverTable = function (e) {
20421  var rowHolder = this.table.rowManager.getElement(),
20422  scrollTop = rowHolder.scrollTop,
20423  yPos = (this.touchMove ? e.touches[0].pageY : e.pageY) - rowHolder.getBoundingClientRect().top + scrollTop,
20424  scrollPos;
20425 
20426  this.hoverElement.style.top = yPos - this.startY + "px";
20427  };
20428 
20429  MoveRows.prototype.moveHoverConnections = function (e) {
20430  this.hoverElement.style.left = this.startX + (this.touchMove ? e.touches[0].pageX : e.pageX) + "px";
20431  this.hoverElement.style.top = this.startY + (this.touchMove ? e.touches[0].pageY : e.pageY) + "px";
20432  };
20433 
20434  //establish connection with other tables
20435  MoveRows.prototype.connectToTables = function (row) {
20436  var self = this,
20437  connections = this.table.modules.comms.getConnections(this.connection);
20438 
20439  this.table.options.movableRowsSendingStart.call(this.table, connections);
20440 
20441  this.table.modules.comms.send(this.connection, "moveRow", "connect", {
20442  row: row
20443  });
20444  };
20445 
20446  //disconnect from other tables
20447  MoveRows.prototype.disconnectFromTables = function () {
20448  var self = this,
20449  connections = this.table.modules.comms.getConnections(this.connection);
20450 
20451  this.table.options.movableRowsSendingStop.call(this.table, connections);
20452 
20453  this.table.modules.comms.send(this.connection, "moveRow", "disconnect");
20454  };
20455 
20456  //accept incomming connection
20457  MoveRows.prototype.connect = function (table, row) {
20458  var self = this;
20459  if (!this.connectedTable) {
20460  this.connectedTable = table;
20461  this.connectedRow = row;
20462 
20463  this.table.element.classList.add("tabulator-movingrow-receiving");
20464 
20465  self.table.rowManager.getDisplayRows().forEach(function (row) {
20466  if (row.type === "row" && row.modules.moveRow && row.modules.moveRow.mouseup) {
20467  row.getElement().addEventListener("mouseup", row.modules.moveRow.mouseup);
20468  }
20469  });
20470 
20471  self.tableRowDropEvent = self.tableRowDrop.bind(self);
20472 
20473  self.table.element.addEventListener("mouseup", self.tableRowDropEvent);
20474 
20475  this.table.options.movableRowsReceivingStart.call(this.table, row, table);
20476 
20477  return true;
20478  } else {
20479  console.warn("Move Row Error - Table cannot accept connection, already connected to table:", this.connectedTable);
20480  return false;
20481  }
20482  };
20483 
20484  //close incomming connection
20485  MoveRows.prototype.disconnect = function (table) {
20486  var self = this;
20487  if (table === this.connectedTable) {
20488  this.connectedTable = false;
20489  this.connectedRow = false;
20490 
20491  this.table.element.classList.remove("tabulator-movingrow-receiving");
20492 
20493  self.table.rowManager.getDisplayRows().forEach(function (row) {
20494  if (row.type === "row" && row.modules.moveRow && row.modules.moveRow.mouseup) {
20495  row.getElement().removeEventListener("mouseup", row.modules.moveRow.mouseup);
20496  }
20497  });
20498 
20499  self.table.element.removeEventListener("mouseup", self.tableRowDropEvent);
20500 
20501  this.table.options.movableRowsReceivingStop.call(this.table, table);
20502  } else {
20503  console.warn("Move Row Error - trying to disconnect from non connected table");
20504  }
20505  };
20506 
20507  MoveRows.prototype.dropComplete = function (table, row, success) {
20508  var sender = false;
20509 
20510  if (success) {
20511 
20512  switch (_typeof(this.table.options.movableRowsSender)) {
20513  case "string":
20514  sender = this.senders[this.table.options.movableRowsSender];
20515  break;
20516 
20517  case "function":
20518  sender = this.table.options.movableRowsSender;
20519  break;
20520  }
20521 
20522  if (sender) {
20523  sender.call(this, this.moving.getComponent(), row ? row.getComponent() : undefined, table);
20524  } else {
20525  if (this.table.options.movableRowsSender) {
20526  console.warn("Mover Row Error - no matching sender found:", this.table.options.movableRowsSender);
20527  }
20528  }
20529 
20530  this.table.options.movableRowsSent.call(this.table, this.moving.getComponent(), row ? row.getComponent() : undefined, table);
20531  } else {
20532  this.table.options.movableRowsSentFailed.call(this.table, this.moving.getComponent(), row ? row.getComponent() : undefined, table);
20533  }
20534 
20535  this.endMove();
20536  };
20537 
20538  MoveRows.prototype.tableRowDrop = function (e, row) {
20539  var receiver = false,
20540  success = false;
20541 
20542  e.stopImmediatePropagation();
20543 
20544  switch (_typeof(this.table.options.movableRowsReceiver)) {
20545  case "string":
20546  receiver = this.receivers[this.table.options.movableRowsReceiver];
20547  break;
20548 
20549  case "function":
20550  receiver = this.table.options.movableRowsReceiver;
20551  break;
20552  }
20553 
20554  if (receiver) {
20555  success = receiver.call(this, this.connectedRow.getComponent(), row ? row.getComponent() : undefined, this.connectedTable);
20556  } else {
20557  console.warn("Mover Row Error - no matching receiver found:", this.table.options.movableRowsReceiver);
20558  }
20559 
20560  if (success) {
20561  this.table.options.movableRowsReceived.call(this.table, this.connectedRow.getComponent(), row ? row.getComponent() : undefined, this.connectedTable);
20562  } else {
20563  this.table.options.movableRowsReceivedFailed.call(this.table, this.connectedRow.getComponent(), row ? row.getComponent() : undefined, this.connectedTable);
20564  }
20565 
20566  this.table.modules.comms.send(this.connectedTable, "moveRow", "dropcomplete", {
20567  row: row,
20568  success: success
20569  });
20570  };
20571 
20572  MoveRows.prototype.receivers = {
20573  insert: function insert(fromRow, toRow, fromTable) {
20574  this.table.addRow(fromRow.getData(), undefined, toRow);
20575  return true;
20576  },
20577 
20578  add: function add(fromRow, toRow, fromTable) {
20579  this.table.addRow(fromRow.getData());
20580  return true;
20581  },
20582 
20583  update: function update(fromRow, toRow, fromTable) {
20584  if (toRow) {
20585  toRow.update(fromRow.getData());
20586  return true;
20587  }
20588 
20589  return false;
20590  },
20591 
20592  replace: function replace(fromRow, toRow, fromTable) {
20593  if (toRow) {
20594  this.table.addRow(fromRow.getData(), undefined, toRow);
20595  toRow.delete();
20596  return true;
20597  }
20598 
20599  return false;
20600  }
20601  };
20602 
20603  MoveRows.prototype.senders = {
20604  delete: function _delete(fromRow, toRow, toTable) {
20605  fromRow.delete();
20606  }
20607  };
20608 
20609  MoveRows.prototype.commsReceived = function (table, action, data) {
20610  switch (action) {
20611  case "connect":
20612  return this.connect(table, data.row);
20613  break;
20614 
20615  case "disconnect":
20616  return this.disconnect(table);
20617  break;
20618 
20619  case "dropcomplete":
20620  return this.dropComplete(table, data.row, data.success);
20621  break;
20622  }
20623  };
20624 
20625  Tabulator.prototype.registerModule("moveRow", MoveRows);
20626  var Mutator = function Mutator(table) {
20627  this.table = table; //hold Tabulator object
20628  this.allowedTypes = ["", "data", "edit", "clipboard"]; //list of muatation types
20629  this.enabled = true;
20630  };
20631 
20632  //initialize column mutator
20633  Mutator.prototype.initializeColumn = function (column) {
20634  var self = this,
20635  match = false,
20636  config = {};
20637 
20638  this.allowedTypes.forEach(function (type) {
20639  var key = "mutator" + (type.charAt(0).toUpperCase() + type.slice(1)),
20640  mutator;
20641 
20642  if (column.definition[key]) {
20643  mutator = self.lookupMutator(column.definition[key]);
20644 
20645  if (mutator) {
20646  match = true;
20647 
20648  config[key] = {
20649  mutator: mutator,
20650  params: column.definition[key + "Params"] || {}
20651  };
20652  }
20653  }
20654  });
20655 
20656  if (match) {
20657  column.modules.mutate = config;
20658  }
20659  };
20660 
20661  Mutator.prototype.lookupMutator = function (value) {
20662  var mutator = false;
20663 
20664  //set column mutator
20665  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
20666  case "string":
20667  if (this.mutators[value]) {
20668  mutator = this.mutators[value];
20669  } else {
20670  console.warn("Mutator Error - No such mutator found, ignoring: ", value);
20671  }
20672  break;
20673 
20674  case "function":
20675  mutator = value;
20676  break;
20677  }
20678 
20679  return mutator;
20680  };
20681 
20682  //apply mutator to row
20683  Mutator.prototype.transformRow = function (data, type, updatedData) {
20684  var self = this,
20685  key = "mutator" + (type.charAt(0).toUpperCase() + type.slice(1)),
20686  value;
20687 
20688  if (this.enabled) {
20689 
20690  self.table.columnManager.traverse(function (column) {
20691  var mutator, params, component;
20692 
20693  if (column.modules.mutate) {
20694  mutator = column.modules.mutate[key] || column.modules.mutate.mutator || false;
20695 
20696  if (mutator && updatedData) {
20697  value = column.getFieldValue(updatedData);
20698 
20699  if (type == "data" || typeof value !== "undefined") {
20700  component = column.getComponent();
20701  params = typeof mutator.params === "function" ? mutator.params(value, data, type, component) : mutator.params;
20702  column.setFieldValue(data, mutator.mutator(value, data, type, params, component));
20703  }
20704  }
20705  }
20706  });
20707  }
20708 
20709  return data;
20710  };
20711 
20712  //apply mutator to new cell value
20713  Mutator.prototype.transformCell = function (cell, value) {
20714  var mutator = cell.column.modules.mutate.mutatorEdit || cell.column.modules.mutate.mutator || false,
20715  tempData = {};
20716 
20717  if (mutator) {
20718  tempData = Object.assign(tempData, cell.row.getData());
20719  cell.column.setFieldValue(tempData, value);
20720  return mutator.mutator(value, tempData, "edit", mutator.params, cell.getComponent());
20721  } else {
20722  return value;
20723  }
20724  };
20725 
20726  Mutator.prototype.enable = function () {
20727  this.enabled = true;
20728  };
20729 
20730  Mutator.prototype.disable = function () {
20731  this.enabled = false;
20732  };
20733 
20734  //default mutators
20735  Mutator.prototype.mutators = {};
20736 
20737  Tabulator.prototype.registerModule("mutator", Mutator);
20738  var Page = function Page(table) {
20739 
20740  this.table = table; //hold Tabulator object
20741 
20742  this.mode = "local";
20743  this.progressiveLoad = false;
20744 
20745  this.size = 0;
20746  this.page = 1;
20747  this.count = 5;
20748  this.max = 1;
20749 
20750  this.displayIndex = 0; //index in display pipeline
20751 
20752  this.pageSizes = [];
20753 
20754  this.createElements();
20755  };
20756 
20757  Page.prototype.createElements = function () {
20758 
20759  var button;
20760 
20761  this.element = document.createElement("span");
20762  this.element.classList.add("tabulator-paginator");
20763 
20764  this.pagesElement = document.createElement("span");
20765  this.pagesElement.classList.add("tabulator-pages");
20766 
20767  button = document.createElement("button");
20768  button.classList.add("tabulator-page");
20769  button.setAttribute("type", "button");
20770  button.setAttribute("role", "button");
20771  button.setAttribute("aria-label", "");
20772  button.setAttribute("title", "");
20773 
20774  this.firstBut = button.cloneNode(true);
20775  this.firstBut.setAttribute("data-page", "first");
20776 
20777  this.prevBut = button.cloneNode(true);
20778  this.prevBut.setAttribute("data-page", "prev");
20779 
20780  this.nextBut = button.cloneNode(true);
20781  this.nextBut.setAttribute("data-page", "next");
20782 
20783  this.lastBut = button.cloneNode(true);
20784  this.lastBut.setAttribute("data-page", "last");
20785 
20786  if (this.table.options.paginationSizeSelector) {
20787  this.pageSizeSelect = document.createElement("select");
20788  this.pageSizeSelect.classList.add("tabulator-page-size");
20789  }
20790  };
20791 
20792  Page.prototype.generatePageSizeSelectList = function () {
20793  var _this58 = this;
20794 
20795  var pageSizes = [];
20796 
20797  if (this.pageSizeSelect) {
20798 
20799  if (Array.isArray(this.table.options.paginationSizeSelector)) {
20800  pageSizes = this.table.options.paginationSizeSelector;
20801  this.pageSizes = pageSizes;
20802 
20803  if (this.pageSizes.indexOf(this.size) == -1) {
20804  pageSizes.unshift(this.size);
20805  }
20806  } else {
20807 
20808  if (this.pageSizes.indexOf(this.size) == -1) {
20809  pageSizes = [];
20810 
20811  for (var i = 1; i < 5; i++) {
20812  pageSizes.push(this.size * i);
20813  }
20814 
20815  this.pageSizes = pageSizes;
20816  } else {
20817  pageSizes = this.pageSizes;
20818  }
20819  }
20820 
20821  while (this.pageSizeSelect.firstChild) {
20822  this.pageSizeSelect.removeChild(this.pageSizeSelect.firstChild);
20823  }pageSizes.forEach(function (item) {
20824  var itemEl = document.createElement("option");
20825  itemEl.value = item;
20826  itemEl.innerHTML = item;
20827 
20828  _this58.pageSizeSelect.appendChild(itemEl);
20829  });
20830 
20831  this.pageSizeSelect.value = this.size;
20832  }
20833  };
20834 
20835  //setup pageination
20836  Page.prototype.initialize = function (hidden) {
20837  var self = this,
20838  pageSelectLabel;
20839 
20840  //update param names
20841  for (var key in self.table.options.paginationDataSent) {
20842  self.paginationDataSentNames[key] = self.table.options.paginationDataSent[key];
20843  }
20844 
20845  for (var _key2 in self.table.options.paginationDataReceived) {
20846  self.paginationDataReceivedNames[_key2] = self.table.options.paginationDataReceived[_key2];
20847  }
20848 
20849  //build pagination element
20850 
20851  //bind localizations
20852  self.table.modules.localize.bind("pagination|first", function (value) {
20853  self.firstBut.innerHTML = value;
20854  });
20855 
20856  self.table.modules.localize.bind("pagination|first_title", function (value) {
20857  self.firstBut.setAttribute("aria-label", value);
20858  self.firstBut.setAttribute("title", value);
20859  });
20860 
20861  self.table.modules.localize.bind("pagination|prev", function (value) {
20862  self.prevBut.innerHTML = value;
20863  });
20864 
20865  self.table.modules.localize.bind("pagination|prev_title", function (value) {
20866  self.prevBut.setAttribute("aria-label", value);
20867  self.prevBut.setAttribute("title", value);
20868  });
20869 
20870  self.table.modules.localize.bind("pagination|next", function (value) {
20871  self.nextBut.innerHTML = value;
20872  });
20873 
20874  self.table.modules.localize.bind("pagination|next_title", function (value) {
20875  self.nextBut.setAttribute("aria-label", value);
20876  self.nextBut.setAttribute("title", value);
20877  });
20878 
20879  self.table.modules.localize.bind("pagination|last", function (value) {
20880  self.lastBut.innerHTML = value;
20881  });
20882 
20883  self.table.modules.localize.bind("pagination|last_title", function (value) {
20884  self.lastBut.setAttribute("aria-label", value);
20885  self.lastBut.setAttribute("title", value);
20886  });
20887 
20888  //click bindings
20889  self.firstBut.addEventListener("click", function () {
20890  self.setPage(1);
20891  });
20892 
20893  self.prevBut.addEventListener("click", function () {
20894  self.previousPage();
20895  });
20896 
20897  self.nextBut.addEventListener("click", function () {
20898  self.nextPage().then(function () {}).catch(function () {});
20899  });
20900 
20901  self.lastBut.addEventListener("click", function () {
20902  self.setPage(self.max);
20903  });
20904 
20905  if (self.table.options.paginationElement) {
20906  self.element = self.table.options.paginationElement;
20907  }
20908 
20909  if (this.pageSizeSelect) {
20910  pageSelectLabel = document.createElement("label");
20911 
20912  self.table.modules.localize.bind("pagination|page_size", function (value) {
20913  self.pageSizeSelect.setAttribute("aria-label", value);
20914  self.pageSizeSelect.setAttribute("title", value);
20915  pageSelectLabel.innerHTML = value;
20916  });
20917 
20918  self.element.appendChild(pageSelectLabel);
20919  self.element.appendChild(self.pageSizeSelect);
20920 
20921  self.pageSizeSelect.addEventListener("change", function (e) {
20922  self.setPageSize(self.pageSizeSelect.value);
20923  self.setPage(1).then(function () {}).catch(function () {});
20924  });
20925  }
20926 
20927  //append to DOM
20928  self.element.appendChild(self.firstBut);
20929  self.element.appendChild(self.prevBut);
20930  self.element.appendChild(self.pagesElement);
20931  self.element.appendChild(self.nextBut);
20932  self.element.appendChild(self.lastBut);
20933 
20934  if (!self.table.options.paginationElement && !hidden) {
20935  self.table.footerManager.append(self.element, self);
20936  }
20937 
20938  //set default values
20939  self.mode = self.table.options.pagination;
20940 
20941  self.size = self.table.options.paginationSize || Math.floor(self.table.rowManager.getElement().clientHeight / 24);
20942  // self.page = self.table.options.paginationInitialPage || 1;
20943  self.count = self.table.options.paginationButtonCount;
20944 
20945  self.generatePageSizeSelectList();
20946  };
20947 
20948  Page.prototype.initializeProgressive = function (mode) {
20949  this.initialize(true);
20950  this.mode = "progressive_" + mode;
20951  this.progressiveLoad = true;
20952  };
20953 
20954  Page.prototype.setDisplayIndex = function (index) {
20955  this.displayIndex = index;
20956  };
20957 
20958  Page.prototype.getDisplayIndex = function () {
20959  return this.displayIndex;
20960  };
20961 
20962  //calculate maximum page from number of rows
20963  Page.prototype.setMaxRows = function (rowCount) {
20964  if (!rowCount) {
20965  this.max = 1;
20966  } else {
20967  this.max = Math.ceil(rowCount / this.size);
20968  }
20969 
20970  if (this.page > this.max) {
20971  this.page = this.max;
20972  }
20973  };
20974 
20975  //reset to first page without triggering action
20976  Page.prototype.reset = function (force) {
20977  if (this.mode == "local" || force) {
20978  this.page = 1;
20979  }
20980  return true;
20981  };
20982 
20983  //set the maxmum page
20984  Page.prototype.setMaxPage = function (max) {
20985 
20986  max = parseInt(max);
20987 
20988  this.max = max || 1;
20989 
20990  if (this.page > this.max) {
20991  this.page = this.max;
20992  this.trigger();
20993  }
20994  };
20995 
20996  //set current page number
20997  Page.prototype.setPage = function (page) {
20998  var _this59 = this;
20999 
21000  var self = this;
21001 
21002  return new Promise(function (resolve, reject) {
21003 
21004  page = parseInt(page);
21005 
21006  if (page > 0 && page <= _this59.max) {
21007  _this59.page = page;
21008  _this59.trigger().then(function () {
21009  resolve();
21010  }).catch(function () {
21011  reject();
21012  });
21013 
21014  if (self.table.options.persistence && self.table.modExists("persistence", true) && self.table.modules.persistence.config.page) {
21015  self.table.modules.persistence.save("page");
21016  }
21017  } else {
21018  console.warn("Pagination Error - Requested page is out of range of 1 - " + _this59.max + ":", page);
21019  reject();
21020  }
21021  });
21022  };
21023 
21024  Page.prototype.setPageToRow = function (row) {
21025  var _this60 = this;
21026 
21027  return new Promise(function (resolve, reject) {
21028 
21029  var rows = _this60.table.rowManager.getDisplayRows(_this60.displayIndex - 1);
21030  var index = rows.indexOf(row);
21031 
21032  if (index > -1) {
21033  var page = Math.ceil((index + 1) / _this60.size);
21034 
21035  _this60.setPage(page).then(function () {
21036  resolve();
21037  }).catch(function () {
21038  reject();
21039  });
21040  } else {
21041  console.warn("Pagination Error - Requested row is not visible");
21042  reject();
21043  }
21044  });
21045  };
21046 
21047  Page.prototype.setPageSize = function (size) {
21048  size = parseInt(size);
21049 
21050  if (size > 0) {
21051  this.size = size;
21052  }
21053 
21054  if (this.pageSizeSelect) {
21055  // this.pageSizeSelect.value = size;
21056  this.generatePageSizeSelectList();
21057  }
21058 
21059  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.page) {
21060  this.table.modules.persistence.save("page");
21061  }
21062  };
21063 
21064  //setup the pagination buttons
21065  Page.prototype._setPageButtons = function () {
21066  var self = this;
21067 
21068  var leftSize = Math.floor((this.count - 1) / 2);
21069  var rightSize = Math.ceil((this.count - 1) / 2);
21070  var min = this.max - this.page + leftSize + 1 < this.count ? this.max - this.count + 1 : Math.max(this.page - leftSize, 1);
21071  var max = this.page <= rightSize ? Math.min(this.count, this.max) : Math.min(this.page + rightSize, this.max);
21072 
21073  while (self.pagesElement.firstChild) {
21074  self.pagesElement.removeChild(self.pagesElement.firstChild);
21075  }if (self.page == 1) {
21076  self.firstBut.disabled = true;
21077  self.prevBut.disabled = true;
21078  } else {
21079  self.firstBut.disabled = false;
21080  self.prevBut.disabled = false;
21081  }
21082 
21083  if (self.page == self.max) {
21084  self.lastBut.disabled = true;
21085  self.nextBut.disabled = true;
21086  } else {
21087  self.lastBut.disabled = false;
21088  self.nextBut.disabled = false;
21089  }
21090 
21091  for (var i = min; i <= max; i++) {
21092  if (i > 0 && i <= self.max) {
21093  self.pagesElement.appendChild(self._generatePageButton(i));
21094  }
21095  }
21096 
21097  this.footerRedraw();
21098  };
21099 
21100  Page.prototype._generatePageButton = function (page) {
21101  var self = this,
21102  button = document.createElement("button");
21103 
21104  button.classList.add("tabulator-page");
21105  if (page == self.page) {
21106  button.classList.add("active");
21107  }
21108 
21109  button.setAttribute("type", "button");
21110  button.setAttribute("role", "button");
21111  button.setAttribute("aria-label", "Show Page " + page);
21112  button.setAttribute("title", "Show Page " + page);
21113  button.setAttribute("data-page", page);
21114  button.textContent = page;
21115 
21116  button.addEventListener("click", function (e) {
21117  self.setPage(page);
21118  });
21119 
21120  return button;
21121  };
21122 
21123  //previous page
21124  Page.prototype.previousPage = function () {
21125  var _this61 = this;
21126 
21127  return new Promise(function (resolve, reject) {
21128  if (_this61.page > 1) {
21129  _this61.page--;
21130  _this61.trigger().then(function () {
21131  resolve();
21132  }).catch(function () {
21133  reject();
21134  });
21135  } else {
21136  console.warn("Pagination Error - Previous page would be less than page 1:", 0);
21137  reject();
21138  }
21139  });
21140  };
21141 
21142  //next page
21143  Page.prototype.nextPage = function () {
21144  var _this62 = this;
21145 
21146  return new Promise(function (resolve, reject) {
21147  if (_this62.page < _this62.max) {
21148  _this62.page++;
21149  _this62.trigger().then(function () {
21150  resolve();
21151  }).catch(function () {
21152  reject();
21153  });
21154  } else {
21155  if (!_this62.progressiveLoad) {
21156  console.warn("Pagination Error - Next page would be greater than maximum page of " + _this62.max + ":", _this62.max + 1);
21157  }
21158  reject();
21159  }
21160  });
21161  };
21162 
21163  //return current page number
21164  Page.prototype.getPage = function () {
21165  return this.page;
21166  };
21167 
21168  //return max page number
21169  Page.prototype.getPageMax = function () {
21170  return this.max;
21171  };
21172 
21173  Page.prototype.getPageSize = function (size) {
21174  return this.size;
21175  };
21176 
21177  Page.prototype.getMode = function () {
21178  return this.mode;
21179  };
21180 
21181  //return appropriate rows for current page
21182  Page.prototype.getRows = function (data) {
21183  var output, start, end;
21184 
21185  if (this.mode == "local") {
21186  output = [];
21187  start = this.size * (this.page - 1);
21188  end = start + parseInt(this.size);
21189 
21190  this._setPageButtons();
21191 
21192  for (var i = start; i < end; i++) {
21193  if (data[i]) {
21194  output.push(data[i]);
21195  }
21196  }
21197 
21198  return output;
21199  } else {
21200 
21201  this._setPageButtons();
21202 
21203  return data.slice(0);
21204  }
21205  };
21206 
21207  Page.prototype.trigger = function () {
21208  var _this63 = this;
21209 
21210  var left;
21211 
21212  return new Promise(function (resolve, reject) {
21213 
21214  switch (_this63.mode) {
21215  case "local":
21216  left = _this63.table.rowManager.scrollLeft;
21217 
21218  _this63.table.rowManager.refreshActiveData("page");
21219  _this63.table.rowManager.scrollHorizontal(left);
21220 
21221  _this63.table.options.pageLoaded.call(_this63.table, _this63.getPage());
21222  resolve();
21223  break;
21224 
21225  case "remote":
21226  case "progressive_load":
21227  case "progressive_scroll":
21228  _this63.table.modules.ajax.blockActiveRequest();
21229  _this63._getRemotePage().then(function () {
21230  resolve();
21231  }).catch(function () {
21232  reject();
21233  });
21234  break;
21235 
21236  default:
21237  console.warn("Pagination Error - no such pagination mode:", _this63.mode);
21238  reject();
21239  }
21240  });
21241  };
21242 
21243  Page.prototype._getRemotePage = function () {
21244  var _this64 = this;
21245 
21246  var self = this,
21247  oldParams,
21248  pageParams;
21249 
21250  return new Promise(function (resolve, reject) {
21251 
21252  if (!self.table.modExists("ajax", true)) {
21253  reject();
21254  }
21255 
21256  //record old params and restore after request has been made
21257  oldParams = Tabulator.prototype.helpers.deepClone(self.table.modules.ajax.getParams() || {});
21258  pageParams = self.table.modules.ajax.getParams();
21259 
21260  //configure request params
21261  pageParams[_this64.paginationDataSentNames.page] = self.page;
21262 
21263  //set page size if defined
21264  if (_this64.size) {
21265  pageParams[_this64.paginationDataSentNames.size] = _this64.size;
21266  }
21267 
21268  //set sort data if defined
21269  if (_this64.table.options.ajaxSorting && _this64.table.modExists("sort")) {
21270  var sorters = self.table.modules.sort.getSort();
21271 
21272  sorters.forEach(function (item) {
21273  delete item.column;
21274  });
21275 
21276  pageParams[_this64.paginationDataSentNames.sorters] = sorters;
21277  }
21278 
21279  //set filter data if defined
21280  if (_this64.table.options.ajaxFiltering && _this64.table.modExists("filter")) {
21281  var filters = self.table.modules.filter.getFilters(true, true);
21282  pageParams[_this64.paginationDataSentNames.filters] = filters;
21283  }
21284 
21285  self.table.modules.ajax.setParams(pageParams);
21286 
21287  self.table.modules.ajax.sendRequest(_this64.progressiveLoad).then(function (data) {
21288  self._parseRemoteData(data);
21289  resolve();
21290  }).catch(function (e) {
21291  reject();
21292  });
21293 
21294  self.table.modules.ajax.setParams(oldParams);
21295  });
21296  };
21297 
21298  Page.prototype._parseRemoteData = function (data) {
21299  var self = this,
21300  left,
21301  data,
21302  margin;
21303 
21304  if (typeof data[this.paginationDataReceivedNames.last_page] === "undefined") {
21305  console.warn("Remote Pagination Error - Server response missing '" + this.paginationDataReceivedNames.last_page + "' property");
21306  }
21307 
21308  if (data[this.paginationDataReceivedNames.data]) {
21309  this.max = parseInt(data[this.paginationDataReceivedNames.last_page]) || 1;
21310 
21311  if (this.progressiveLoad) {
21312  switch (this.mode) {
21313  case "progressive_load":
21314  this.table.rowManager.addRows(data[this.paginationDataReceivedNames.data]);
21315  if (this.page < this.max) {
21316  setTimeout(function () {
21317  self.nextPage().then(function () {}).catch(function () {});
21318  }, self.table.options.ajaxProgressiveLoadDelay);
21319  }
21320  break;
21321 
21322  case "progressive_scroll":
21323  data = this.table.rowManager.getData().concat(data[this.paginationDataReceivedNames.data]);
21324 
21325  this.table.rowManager.setData(data, true);
21326 
21327  margin = this.table.options.ajaxProgressiveLoadScrollMargin || this.table.rowManager.element.clientHeight * 2;
21328 
21329  if (self.table.rowManager.element.scrollHeight <= self.table.rowManager.element.clientHeight + margin) {
21330  self.nextPage().then(function () {}).catch(function () {});
21331  }
21332  break;
21333  }
21334  } else {
21335  left = this.table.rowManager.scrollLeft;
21336 
21337  this.table.rowManager.setData(data[this.paginationDataReceivedNames.data]);
21338 
21339  this.table.rowManager.scrollHorizontal(left);
21340 
21341  this.table.columnManager.scrollHorizontal(left);
21342 
21343  this.table.options.pageLoaded.call(this.table, this.getPage());
21344  }
21345  } else {
21346  console.warn("Remote Pagination Error - Server response missing '" + this.paginationDataReceivedNames.data + "' property");
21347  }
21348  };
21349 
21350  //handle the footer element being redrawn
21351  Page.prototype.footerRedraw = function () {
21352  var footer = this.table.footerManager.element;
21353 
21354  if (Math.ceil(footer.clientWidth) - footer.scrollWidth < 0) {
21355  this.pagesElement.style.display = 'none';
21356  } else {
21357  this.pagesElement.style.display = '';
21358 
21359  if (Math.ceil(footer.clientWidth) - footer.scrollWidth < 0) {
21360  this.pagesElement.style.display = 'none';
21361  }
21362  }
21363  };
21364 
21365  //set the paramter names for pagination requests
21366  Page.prototype.paginationDataSentNames = {
21367  "page": "page",
21368  "size": "size",
21369  "sorters": "sorters",
21370  // "sort_dir":"sort_dir",
21371  "filters": "filters"
21372  // "filter_value":"filter_value",
21373  // "filter_type":"filter_type",
21374  };
21375 
21376  //set the property names for pagination responses
21377  Page.prototype.paginationDataReceivedNames = {
21378  "current_page": "current_page",
21379  "last_page": "last_page",
21380  "data": "data"
21381  };
21382 
21383  Tabulator.prototype.registerModule("page", Page);
21384 
21385  var Persistence = function Persistence(table) {
21386  this.table = table; //hold Tabulator object
21387  this.mode = "";
21388  this.id = "";
21389  // this.persistProps = ["field", "width", "visible"];
21390  this.defWatcherBlock = false;
21391  this.config = {};
21392  this.readFunc = false;
21393  this.writeFunc = false;
21394  };
21395 
21396  // Test for whether localStorage is available for use.
21397  Persistence.prototype.localStorageTest = function () {
21398  var testKey = "_tabulator_test";
21399 
21400  try {
21401  window.localStorage.setItem(testKey, testKey);
21402  window.localStorage.removeItem(testKey);
21403  return true;
21404  } catch (e) {
21405  return false;
21406  }
21407  };
21408 
21409  //setup parameters
21410  Persistence.prototype.initialize = function () {
21411  //determine persistent layout storage type
21412 
21413  var mode = this.table.options.persistenceMode,
21414  id = this.table.options.persistenceID,
21415  retreivedData;
21416 
21417  this.mode = mode !== true ? mode : this.localStorageTest() ? "local" : "cookie";
21418 
21419  if (this.table.options.persistenceReaderFunc) {
21420  if (typeof this.table.options.persistenceReaderFunc === "function") {
21421  this.readFunc = this.table.options.persistenceReaderFunc;
21422  } else {
21423  if (this.readers[this.table.options.persistenceReaderFunc]) {
21424  this.readFunc = this.readers[this.table.options.persistenceReaderFunc];
21425  } else {
21426  console.warn("Persistence Read Error - invalid reader set", this.table.options.persistenceReaderFunc);
21427  }
21428  }
21429  } else {
21430  if (this.readers[this.mode]) {
21431  this.readFunc = this.readers[this.mode];
21432  } else {
21433  console.warn("Persistence Read Error - invalid reader set", this.mode);
21434  }
21435  }
21436 
21437  if (this.table.options.persistenceWriterFunc) {
21438  if (typeof this.table.options.persistenceWriterFunc === "function") {
21439  this.writeFunc = this.table.options.persistenceWriterFunc;
21440  } else {
21441  if (this.readers[this.table.options.persistenceWriterFunc]) {
21442  this.writeFunc = this.readers[this.table.options.persistenceWriterFunc];
21443  } else {
21444  console.warn("Persistence Write Error - invalid reader set", this.table.options.persistenceWriterFunc);
21445  }
21446  }
21447  } else {
21448  if (this.writers[this.mode]) {
21449  this.writeFunc = this.writers[this.mode];
21450  } else {
21451  console.warn("Persistence Write Error - invalid writer set", this.mode);
21452  }
21453  }
21454 
21455  //set storage tag
21456  this.id = "tabulator-" + (id || this.table.element.getAttribute("id") || "");
21457 
21458  this.config = {
21459  sort: this.table.options.persistence === true || this.table.options.persistence.sort,
21460  filter: this.table.options.persistence === true || this.table.options.persistence.filter,
21461  group: this.table.options.persistence === true || this.table.options.persistence.group,
21462  page: this.table.options.persistence === true || this.table.options.persistence.page,
21463  columns: this.table.options.persistence === true ? ["title", "width", "visible"] : this.table.options.persistence.columns
21464  };
21465 
21466  //load pagination data if needed
21467  if (this.config.page) {
21468  retreivedData = this.retreiveData("page");
21469 
21470  if (retreivedData) {
21471  if (typeof retreivedData.paginationSize !== "undefined" && (this.config.page === true || this.config.page.size)) {
21472  this.table.options.paginationSize = retreivedData.paginationSize;
21473  }
21474 
21475  if (typeof retreivedData.paginationInitialPage !== "undefined" && (this.config.page === true || this.config.page.page)) {
21476  this.table.options.paginationInitialPage = retreivedData.paginationInitialPage;
21477  }
21478  }
21479  }
21480 
21481  //load group data if needed
21482  if (this.config.group) {
21483  retreivedData = this.retreiveData("group");
21484 
21485  if (retreivedData) {
21486  if (typeof retreivedData.groupBy !== "undefined" && (this.config.group === true || this.config.group.groupBy)) {
21487  this.table.options.groupBy = retreivedData.groupBy;
21488  }
21489  if (typeof retreivedData.groupStartOpen !== "undefined" && (this.config.group === true || this.config.group.groupStartOpen)) {
21490  this.table.options.groupStartOpen = retreivedData.groupStartOpen;
21491  }
21492  if (typeof retreivedData.groupHeader !== "undefined" && (this.config.group === true || this.config.group.groupHeader)) {
21493  this.table.options.groupHeader = retreivedData.groupHeader;
21494  }
21495  }
21496  }
21497  };
21498 
21499  Persistence.prototype.initializeColumn = function (column) {
21500  var self = this,
21501  def,
21502  keys;
21503 
21504  if (this.config.columns) {
21505  this.defWatcherBlock = true;
21506 
21507  def = column.getDefinition();
21508 
21509  keys = this.config.columns === true ? Object.keys(def) : this.config.columns;
21510 
21511  keys.forEach(function (key) {
21512  var props = Object.getOwnPropertyDescriptor(def, key);
21513  var value = def[key];
21514  if (props) {
21515  Object.defineProperty(def, key, {
21516  set: function set(newValue) {
21517  value = newValue;
21518 
21519  if (!self.defWatcherBlock) {
21520  self.save("columns");
21521  }
21522 
21523  if (props.set) {
21524  props.set(newValue);
21525  }
21526  },
21527  get: function get() {
21528  if (props.get) {
21529  props.get();
21530  }
21531  return value;
21532  }
21533  });
21534  }
21535  });
21536 
21537  this.defWatcherBlock = false;
21538  }
21539  };
21540 
21541  //load saved definitions
21542  Persistence.prototype.load = function (type, current) {
21543  var data = this.retreiveData(type);
21544 
21545  if (current) {
21546  data = data ? this.mergeDefinition(current, data) : current;
21547  }
21548 
21549  return data;
21550  };
21551 
21552  //retreive data from memory
21553  Persistence.prototype.retreiveData = function (type) {
21554  return this.readFunc ? this.readFunc(this.id, type) : false;
21555  };
21556 
21557  //merge old and new column definitions
21558  Persistence.prototype.mergeDefinition = function (oldCols, newCols) {
21559  var self = this,
21560  output = [];
21561 
21562  // oldCols = oldCols || [];
21563  newCols = newCols || [];
21564 
21565  newCols.forEach(function (column, to) {
21566 
21567  var from = self._findColumn(oldCols, column),
21568  keys;
21569 
21570  if (from) {
21571 
21572  if (self.config.columns === true || self.config.columns == undefined) {
21573  keys = Object.keys(from);
21574  keys.push("width");
21575  } else {
21576  keys = self.config.columns;
21577  }
21578 
21579  keys.forEach(function (key) {
21580  if (typeof column[key] !== "undefined") {
21581  from[key] = column[key];
21582  }
21583  });
21584 
21585  if (from.columns) {
21586  from.columns = self.mergeDefinition(from.columns, column.columns);
21587  }
21588 
21589  output.push(from);
21590  }
21591  });
21592 
21593  oldCols.forEach(function (column, i) {
21594  var from = self._findColumn(newCols, column);
21595  if (!from) {
21596  if (output.length > i) {
21597  output.splice(i, 0, column);
21598  } else {
21599  output.push(column);
21600  }
21601  }
21602  });
21603 
21604  return output;
21605  };
21606 
21607  //find matching columns
21608  Persistence.prototype._findColumn = function (columns, subject) {
21609  var type = subject.columns ? "group" : subject.field ? "field" : "object";
21610 
21611  return columns.find(function (col) {
21612  switch (type) {
21613  case "group":
21614  return col.title === subject.title && col.columns.length === subject.columns.length;
21615  break;
21616 
21617  case "field":
21618  return col.field === subject.field;
21619  break;
21620 
21621  case "object":
21622  return col === subject;
21623  break;
21624  }
21625  });
21626  };
21627 
21628  //save data
21629  Persistence.prototype.save = function (type) {
21630  var data = {};
21631 
21632  switch (type) {
21633  case "columns":
21634  data = this.parseColumns(this.table.columnManager.getColumns());
21635  break;
21636 
21637  case "filter":
21638  data = this.table.modules.filter.getFilters();
21639  break;
21640 
21641  case "sort":
21642  data = this.validateSorters(this.table.modules.sort.getSort());
21643  break;
21644 
21645  case "group":
21646  data = this.getGroupConfig();
21647  break;
21648 
21649  case "page":
21650  data = this.getPageConfig();
21651  break;
21652  }
21653 
21654  if (this.writeFunc) {
21655  this.writeFunc(this.id, type, data);
21656  }
21657  };
21658 
21659  //ensure sorters contain no function data
21660  Persistence.prototype.validateSorters = function (data) {
21661  data.forEach(function (item) {
21662  item.column = item.field;
21663  delete item.field;
21664  });
21665 
21666  return data;
21667  };
21668 
21669  Persistence.prototype.getGroupConfig = function () {
21670  if (this.config.group) {
21671  if (this.config.group === true || this.config.group.groupBy) {
21672  data.groupBy = this.table.options.groupBy;
21673  }
21674 
21675  if (this.config.group === true || this.config.group.groupStartOpen) {
21676  data.groupStartOpen = this.table.options.groupStartOpen;
21677  }
21678 
21679  if (this.config.group === true || this.config.group.groupHeader) {
21680  data.groupHeader = this.table.options.groupHeader;
21681  }
21682  }
21683 
21684  return data;
21685  };
21686 
21687  Persistence.prototype.getPageConfig = function () {
21688  var data = {};
21689 
21690  if (this.config.page) {
21691  if (this.config.page === true || this.config.page.size) {
21692  data.paginationSize = this.table.modules.page.getPageSize();
21693  }
21694 
21695  if (this.config.page === true || this.config.page.page) {
21696  data.paginationInitialPage = this.table.modules.page.getPage();
21697  }
21698  }
21699 
21700  return data;
21701  };
21702 
21703  //parse columns for data to store
21704  Persistence.prototype.parseColumns = function (columns) {
21705  var self = this,
21706  definitions = [];
21707 
21708  columns.forEach(function (column) {
21709  var defStore = {},
21710  colDef = column.getDefinition(),
21711  keys;
21712 
21713  if (column.isGroup) {
21714  defStore.title = colDef.title;
21715  defStore.columns = self.parseColumns(column.getColumns());
21716  } else {
21717  defStore.field = column.getField();
21718 
21719  if (self.config.columns === true || self.config.columns == undefined) {
21720  keys = Object.keys(colDef);
21721  keys.push("width");
21722  } else {
21723  keys = self.config.columns;
21724  }
21725 
21726  keys.forEach(function (key) {
21727 
21728  switch (key) {
21729  case "width":
21730  defStore.width = column.getWidth();
21731  break;
21732  case "visible":
21733  defStore.visible = column.visible;
21734  break;
21735 
21736  default:
21737  defStore[key] = colDef[key];
21738  }
21739  });
21740  }
21741 
21742  definitions.push(defStore);
21743  });
21744 
21745  return definitions;
21746  };
21747 
21748  // read peristence information from storage
21749  Persistence.prototype.readers = {
21750  local: function local(id, type) {
21751  var data = localStorage.getItem(id + "-" + type);
21752 
21753  return data ? JSON.parse(data) : false;
21754  },
21755  cookie: function cookie(id, type) {
21756  var cookie = document.cookie,
21757  key = id + "-" + type,
21758  cookiePos = cookie.indexOf(key + "="),
21759  end;
21760 
21761  //if cookie exists, decode and load column data into tabulator
21762  if (cookiePos > -1) {
21763  cookie = cookie.substr(cookiePos);
21764 
21765  end = cookie.indexOf(";");
21766 
21767  if (end > -1) {
21768  cookie = cookie.substr(0, end);
21769  }
21770 
21771  data = cookie.replace(key + "=", "");
21772  }
21773 
21774  return data ? JSON.parse(data) : false;
21775  }
21776  };
21777 
21778  //write persistence information to storage
21779  Persistence.prototype.writers = {
21780  local: function local(id, type, data) {
21781  localStorage.setItem(id + "-" + type, JSON.stringify(data));
21782  },
21783  cookie: function cookie(id, type, data) {
21784  var expireDate = new Date();
21785 
21786  expireDate.setDate(expireDate.getDate() + 10000);
21787 
21788  document.cookie = id + "_" + type + "=" + JSON.stringify(data) + "; expires=" + expireDate.toUTCString();
21789  }
21790  };
21791 
21792  Tabulator.prototype.registerModule("persistence", Persistence);
21793 
21794  var Print = function Print(table) {
21795  this.table = table; //hold Tabulator object
21796  this.element = false;
21797  this.manualBlock = false;
21798  };
21799 
21800  Print.prototype.initialize = function () {
21801  window.addEventListener("beforeprint", this.replaceTable.bind(this));
21802  window.addEventListener("afterprint", this.cleanup.bind(this));
21803  };
21804 
21805  Print.prototype.replaceTable = function () {
21806  if (!this.manualBlock) {
21807  this.element = document.createElement("div");
21808  this.element.classList.add("tabulator-print-table");
21809 
21810  this.element.appendChild(this.table.modules.htmlTableExport.genereateTable(this.table.options.printConfig, this.table.options.printCopyStyle, this.table.options.printVisibleRows, "print"));
21811 
21812  this.table.element.style.display = "none";
21813 
21814  this.table.element.parentNode.insertBefore(this.element, this.table.element);
21815  }
21816  };
21817 
21818  Print.prototype.cleanup = function () {
21819  document.body.classList.remove("tabulator-print-fullscreen-hide");
21820 
21821  if (this.element && this.element.parentNode) {
21822  this.element.parentNode.removeChild(this.element);
21823  this.table.element.style.display = "";
21824  }
21825  };
21826 
21827  Print.prototype.printFullscreen = function (visible, style, config) {
21828  var scrollX = window.scrollX,
21829  scrollY = window.scrollY,
21830  headerEl = document.createElement("div"),
21831  footerEl = document.createElement("div"),
21832  tableEl = this.table.modules.htmlTableExport.genereateTable(typeof config != "undefined" ? config : this.table.options.printConfig, typeof style != "undefined" ? style : this.table.options.printCopyStyle, visible, "print"),
21833  headerContent,
21834  footerContent;
21835 
21836  this.manualBlock = true;
21837 
21838  this.element = document.createElement("div");
21839  this.element.classList.add("tabulator-print-fullscreen");
21840 
21841  if (this.table.options.printHeader) {
21842  headerEl.classList.add("tabulator-print-header");
21843 
21844  headerContent = typeof this.table.options.printHeader == "function" ? this.table.options.printHeader.call(this.table) : this.table.options.printHeader;
21845 
21846  if (typeof headerContent == "string") {
21847  headerEl.innerHTML = headerContent;
21848  } else {
21849  headerEl.appendChild(headerContent);
21850  }
21851 
21852  this.element.appendChild(headerEl);
21853  }
21854 
21855  this.element.appendChild(tableEl);
21856 
21857  if (this.table.options.printFooter) {
21858  footerEl.classList.add("tabulator-print-footer");
21859 
21860  footerContent = typeof this.table.options.printFooter == "function" ? this.table.options.printFooter.call(this.table) : this.table.options.printFooter;
21861 
21862  if (typeof footerContent == "string") {
21863  footerEl.innerHTML = footerContent;
21864  } else {
21865  footerEl.appendChild(footerContent);
21866  }
21867 
21868  this.element.appendChild(footerEl);
21869  }
21870 
21871  document.body.classList.add("tabulator-print-fullscreen-hide");
21872  document.body.appendChild(this.element);
21873 
21874  if (this.table.options.printFormatter) {
21875  this.table.options.printFormatter(this.element, tableEl);
21876  }
21877 
21878  window.print();
21879 
21880  this.cleanup();
21881 
21882  window.scrollTo(scrollX, scrollY);
21883 
21884  this.manualBlock = false;
21885  };
21886 
21887  Tabulator.prototype.registerModule("print", Print);
21888  var ReactiveData = function ReactiveData(table) {
21889  this.table = table; //hold Tabulator object
21890  this.data = false;
21891  this.blocked = false; //block reactivity while performing update
21892  this.origFuncs = {}; // hold original data array functions to allow replacement after data is done with
21893  this.currentVersion = 0;
21894  };
21895 
21896  ReactiveData.prototype.watchData = function (data) {
21897  var self = this,
21898  pushFunc,
21899  version;
21900 
21901  this.currentVersion++;
21902 
21903  version = this.currentVersion;
21904 
21905  self.unwatchData();
21906 
21907  self.data = data;
21908 
21909  //override array push function
21910  self.origFuncs.push = data.push;
21911 
21912  Object.defineProperty(self.data, "push", {
21913  enumerable: false,
21914  configurable: true,
21915  value: function value() {
21916  var args = Array.from(arguments);
21917 
21918  if (!self.blocked && version === self.currentVersion) {
21919  args.forEach(function (arg) {
21920  self.table.rowManager.addRowActual(arg, false);
21921  });
21922  }
21923 
21924  return self.origFuncs.push.apply(data, arguments);
21925  }
21926  });
21927 
21928  //override array unshift function
21929  self.origFuncs.unshift = data.unshift;
21930 
21931  Object.defineProperty(self.data, "unshift", {
21932  enumerable: false,
21933  configurable: true,
21934  value: function value() {
21935  var args = Array.from(arguments);
21936 
21937  if (!self.blocked && version === self.currentVersion) {
21938  args.forEach(function (arg) {
21939  self.table.rowManager.addRowActual(arg, true);
21940  });
21941  }
21942 
21943  return self.origFuncs.unshift.apply(data, arguments);
21944  }
21945  });
21946 
21947  //override array shift function
21948  self.origFuncs.shift = data.shift;
21949 
21950  Object.defineProperty(self.data, "shift", {
21951  enumerable: false,
21952  configurable: true,
21953  value: function value() {
21954  var row;
21955 
21956  if (!self.blocked && version === self.currentVersion) {
21957  if (self.data.length) {
21958  row = self.table.rowManager.getRowFromDataObject(self.data[0]);
21959 
21960  if (row) {
21961  row.deleteActual();
21962  }
21963  }
21964  }
21965 
21966  return self.origFuncs.shift.call(data);
21967  }
21968  });
21969 
21970  //override array pop function
21971  self.origFuncs.pop = data.pop;
21972 
21973  Object.defineProperty(self.data, "pop", {
21974  enumerable: false,
21975  configurable: true,
21976  value: function value() {
21977  var row;
21978  if (!self.blocked && version === self.currentVersion) {
21979  if (self.data.length) {
21980  row = self.table.rowManager.getRowFromDataObject(self.data[self.data.length - 1]);
21981 
21982  if (row) {
21983  row.deleteActual();
21984  }
21985  }
21986  }
21987  return self.origFuncs.pop.call(data);
21988  }
21989  });
21990 
21991  //override array splice function
21992  self.origFuncs.splice = data.splice;
21993 
21994  Object.defineProperty(self.data, "splice", {
21995  enumerable: false,
21996  configurable: true,
21997  value: function value() {
21998  var args = Array.from(arguments),
21999  start = args[0] < 0 ? data.length + args[0] : args[0],
22000  end = args[1],
22001  newRows = args[2] ? args.slice(2) : false,
22002  startRow;
22003 
22004  if (!self.blocked && version === self.currentVersion) {
22005 
22006  //add new rows
22007  if (newRows) {
22008  startRow = data[start] ? self.table.rowManager.getRowFromDataObject(data[start]) : false;
22009 
22010  if (startRow) {
22011  newRows.forEach(function (rowData) {
22012  self.table.rowManager.addRowActual(rowData, true, startRow, true);
22013  });
22014  } else {
22015  newRows = newRows.slice().reverse();
22016 
22017  newRows.forEach(function (rowData) {
22018  self.table.rowManager.addRowActual(rowData, true, false, true);
22019  });
22020  }
22021  }
22022 
22023  //delete removed rows
22024  if (end !== 0) {
22025  var oldRows = data.slice(start, typeof args[1] === "undefined" ? args[1] : start + end);
22026 
22027  oldRows.forEach(function (rowData, i) {
22028  var row = self.table.rowManager.getRowFromDataObject(rowData);
22029 
22030  if (row) {
22031  row.deleteActual(i !== oldRows.length - 1);
22032  }
22033  });
22034  }
22035 
22036  if (newRows || end !== 0) {
22037  self.table.rowManager.reRenderInPosition();
22038  }
22039  }
22040 
22041  return self.origFuncs.splice.apply(data, arguments);
22042  }
22043  });
22044  };
22045 
22046  ReactiveData.prototype.unwatchData = function () {
22047  if (this.data !== false) {
22048  for (var key in this.origFuncs) {
22049  Object.defineProperty(this.data, key, {
22050  enumerable: true,
22051  configurable: true,
22052  writable: true,
22053  value: this.origFuncs.key
22054  });
22055  }
22056  }
22057  };
22058 
22059  ReactiveData.prototype.watchRow = function (row) {
22060  var self = this,
22061  data = row.getData();
22062 
22063  this.blocked = true;
22064 
22065  for (var key in data) {
22066  this.watchKey(row, data, key);
22067  }
22068 
22069  this.blocked = false;
22070  };
22071 
22072  ReactiveData.prototype.watchKey = function (row, data, key) {
22073  var self = this,
22074  props = Object.getOwnPropertyDescriptor(data, key),
22075  value = data[key],
22076  version = this.currentVersion;
22077 
22078  Object.defineProperty(data, key, {
22079  set: function set(newValue) {
22080  value = newValue;
22081  if (!self.blocked && version === self.currentVersion) {
22082  var update = {};
22083  update[key] = newValue;
22084  row.updateData(update);
22085  }
22086 
22087  if (props.set) {
22088  props.set(newValue);
22089  }
22090  },
22091  get: function get() {
22092 
22093  if (props.get) {
22094  props.get();
22095  }
22096 
22097  return value;
22098  }
22099  });
22100  };
22101 
22102  ReactiveData.prototype.unwatchRow = function (row) {
22103  var data = row.getData();
22104 
22105  for (var key in data) {
22106  Object.defineProperty(data, key, {
22107  value: data[key]
22108  });
22109  }
22110  };
22111 
22112  ReactiveData.prototype.block = function () {
22113  this.blocked = true;
22114  };
22115 
22116  ReactiveData.prototype.unblock = function () {
22117  this.blocked = false;
22118  };
22119 
22120  Tabulator.prototype.registerModule("reactiveData", ReactiveData);
22121 
22122  var ResizeColumns = function ResizeColumns(table) {
22123  this.table = table; //hold Tabulator object
22124  this.startColumn = false;
22125  this.startX = false;
22126  this.startWidth = false;
22127  this.handle = null;
22128  this.prevHandle = null;
22129  };
22130 
22131  ResizeColumns.prototype.initializeColumn = function (type, column, element) {
22132  var self = this,
22133  variableHeight = false,
22134  mode = this.table.options.resizableColumns;
22135 
22136  //set column resize mode
22137  if (type === "header") {
22138  variableHeight = column.definition.formatter == "textarea" || column.definition.variableHeight;
22139  column.modules.resize = { variableHeight: variableHeight };
22140  }
22141 
22142  if (mode === true || mode == type) {
22143 
22144  var handle = document.createElement('div');
22145  handle.className = "tabulator-col-resize-handle";
22146 
22147  var prevHandle = document.createElement('div');
22148  prevHandle.className = "tabulator-col-resize-handle prev";
22149 
22150  handle.addEventListener("click", function (e) {
22151  e.stopPropagation();
22152  });
22153 
22154  var handleDown = function handleDown(e) {
22155  var nearestColumn = column.getLastColumn();
22156 
22157  if (nearestColumn && self._checkResizability(nearestColumn)) {
22158  self.startColumn = column;
22159  self._mouseDown(e, nearestColumn, handle);
22160  }
22161  };
22162 
22163  handle.addEventListener("mousedown", handleDown);
22164  handle.addEventListener("touchstart", handleDown, { passive: true });
22165 
22166  //reszie column on double click
22167  handle.addEventListener("dblclick", function (e) {
22168  var col = column.getLastColumn();
22169 
22170  if (col && self._checkResizability(col)) {
22171  e.stopPropagation();
22172  col.reinitializeWidth(true);
22173  }
22174  });
22175 
22176  prevHandle.addEventListener("click", function (e) {
22177  e.stopPropagation();
22178  });
22179 
22180  var prevHandleDown = function prevHandleDown(e) {
22181  var nearestColumn, colIndex, prevColumn;
22182 
22183  nearestColumn = column.getFirstColumn();
22184 
22185  if (nearestColumn) {
22186  colIndex = self.table.columnManager.findColumnIndex(nearestColumn);
22187  prevColumn = colIndex > 0 ? self.table.columnManager.getColumnByIndex(colIndex - 1) : false;
22188 
22189  if (prevColumn && self._checkResizability(prevColumn)) {
22190  self.startColumn = column;
22191  self._mouseDown(e, prevColumn, prevHandle);
22192  }
22193  }
22194  };
22195 
22196  prevHandle.addEventListener("mousedown", prevHandleDown);
22197  prevHandle.addEventListener("touchstart", prevHandleDown, { passive: true });
22198 
22199  //resize column on double click
22200  prevHandle.addEventListener("dblclick", function (e) {
22201  var nearestColumn, colIndex, prevColumn;
22202 
22203  nearestColumn = column.getFirstColumn();
22204 
22205  if (nearestColumn) {
22206  colIndex = self.table.columnManager.findColumnIndex(nearestColumn);
22207  prevColumn = colIndex > 0 ? self.table.columnManager.getColumnByIndex(colIndex - 1) : false;
22208 
22209  if (prevColumn && self._checkResizability(prevColumn)) {
22210  e.stopPropagation();
22211  prevColumn.reinitializeWidth(true);
22212  }
22213  }
22214  });
22215 
22216  element.appendChild(handle);
22217  element.appendChild(prevHandle);
22218  }
22219  };
22220 
22221  ResizeColumns.prototype._checkResizability = function (column) {
22222  return typeof column.definition.resizable != "undefined" ? column.definition.resizable : this.table.options.resizableColumns;
22223  };
22224 
22225  ResizeColumns.prototype._mouseDown = function (e, column, handle) {
22226  var self = this;
22227 
22228  self.table.element.classList.add("tabulator-block-select");
22229 
22230  function mouseMove(e) {
22231  // self.table.columnManager.tempScrollBlock();
22232 
22233  column.setWidth(self.startWidth + ((typeof e.screenX === "undefined" ? e.touches[0].screenX : e.screenX) - self.startX));
22234 
22235  if (!self.table.browserSlow && column.modules.resize && column.modules.resize.variableHeight) {
22236  column.checkCellHeights();
22237  }
22238  }
22239 
22240  function mouseUp(e) {
22241 
22242  //block editor from taking action while resizing is taking place
22243  if (self.startColumn.modules.edit) {
22244  self.startColumn.modules.edit.blocked = false;
22245  }
22246 
22247  if (self.table.browserSlow && column.modules.resize && column.modules.resize.variableHeight) {
22248  column.checkCellHeights();
22249  }
22250 
22251  document.body.removeEventListener("mouseup", mouseUp);
22252  document.body.removeEventListener("mousemove", mouseMove);
22253 
22254  handle.removeEventListener("touchmove", mouseMove);
22255  handle.removeEventListener("touchend", mouseUp);
22256 
22257  self.table.element.classList.remove("tabulator-block-select");
22258 
22259  if (self.table.options.persistence && self.table.modExists("persistence", true) && self.table.modules.persistence.config.columns) {
22260  self.table.modules.persistence.save("columns");
22261  }
22262 
22263  self.table.options.columnResized.call(self.table, column.getComponent());
22264  }
22265 
22266  e.stopPropagation(); //prevent resize from interfereing with movable columns
22267 
22268  //block editor from taking action while resizing is taking place
22269  if (self.startColumn.modules.edit) {
22270  self.startColumn.modules.edit.blocked = true;
22271  }
22272 
22273  self.startX = typeof e.screenX === "undefined" ? e.touches[0].screenX : e.screenX;
22274  self.startWidth = column.getWidth();
22275 
22276  document.body.addEventListener("mousemove", mouseMove);
22277  document.body.addEventListener("mouseup", mouseUp);
22278  handle.addEventListener("touchmove", mouseMove, { passive: true });
22279  handle.addEventListener("touchend", mouseUp);
22280  };
22281 
22282  Tabulator.prototype.registerModule("resizeColumns", ResizeColumns);
22283  var ResizeRows = function ResizeRows(table) {
22284  this.table = table; //hold Tabulator object
22285  this.startColumn = false;
22286  this.startY = false;
22287  this.startHeight = false;
22288  this.handle = null;
22289  this.prevHandle = null;
22290  };
22291 
22292  ResizeRows.prototype.initializeRow = function (row) {
22293  var self = this,
22294  rowEl = row.getElement();
22295 
22296  var handle = document.createElement('div');
22297  handle.className = "tabulator-row-resize-handle";
22298 
22299  var prevHandle = document.createElement('div');
22300  prevHandle.className = "tabulator-row-resize-handle prev";
22301 
22302  handle.addEventListener("click", function (e) {
22303  e.stopPropagation();
22304  });
22305 
22306  var handleDown = function handleDown(e) {
22307  self.startRow = row;
22308  self._mouseDown(e, row, handle);
22309  };
22310 
22311  handle.addEventListener("mousedown", handleDown);
22312  handle.addEventListener("touchstart", handleDown, { passive: true });
22313 
22314  prevHandle.addEventListener("click", function (e) {
22315  e.stopPropagation();
22316  });
22317 
22318  var prevHandleDown = function prevHandleDown(e) {
22319  var prevRow = self.table.rowManager.prevDisplayRow(row);
22320 
22321  if (prevRow) {
22322  self.startRow = prevRow;
22323  self._mouseDown(e, prevRow, prevHandle);
22324  }
22325  };
22326 
22327  prevHandle.addEventListener("mousedown", prevHandleDown);
22328  prevHandle.addEventListener("touchstart", prevHandleDown, { passive: true });
22329 
22330  rowEl.appendChild(handle);
22331  rowEl.appendChild(prevHandle);
22332  };
22333 
22334  ResizeRows.prototype._mouseDown = function (e, row, handle) {
22335  var self = this;
22336 
22337  self.table.element.classList.add("tabulator-block-select");
22338 
22339  function mouseMove(e) {
22340  row.setHeight(self.startHeight + ((typeof e.screenY === "undefined" ? e.touches[0].screenY : e.screenY) - self.startY));
22341  }
22342 
22343  function mouseUp(e) {
22344 
22345  // //block editor from taking action while resizing is taking place
22346  // if(self.startColumn.modules.edit){
22347  // self.startColumn.modules.edit.blocked = false;
22348  // }
22349 
22350  document.body.removeEventListener("mouseup", mouseMove);
22351  document.body.removeEventListener("mousemove", mouseMove);
22352 
22353  handle.removeEventListener("touchmove", mouseMove);
22354  handle.removeEventListener("touchend", mouseUp);
22355 
22356  self.table.element.classList.remove("tabulator-block-select");
22357 
22358  self.table.options.rowResized.call(this.table, row.getComponent());
22359  }
22360 
22361  e.stopPropagation(); //prevent resize from interfereing with movable columns
22362 
22363  //block editor from taking action while resizing is taking place
22364  // if(self.startColumn.modules.edit){
22365  // self.startColumn.modules.edit.blocked = true;
22366  // }
22367 
22368  self.startY = typeof e.screenY === "undefined" ? e.touches[0].screenY : e.screenY;
22369  self.startHeight = row.getHeight();
22370 
22371  document.body.addEventListener("mousemove", mouseMove);
22372  document.body.addEventListener("mouseup", mouseUp);
22373 
22374  handle.addEventListener("touchmove", mouseMove, { passive: true });
22375  handle.addEventListener("touchend", mouseUp);
22376  };
22377 
22378  Tabulator.prototype.registerModule("resizeRows", ResizeRows);
22379  var ResizeTable = function ResizeTable(table) {
22380  this.table = table; //hold Tabulator object
22381  this.binding = false;
22382  this.observer = false;
22383  };
22384 
22385  ResizeTable.prototype.initialize = function (row) {
22386  var table = this.table,
22387  observer;
22388 
22389  if (typeof ResizeObserver !== "undefined" && table.rowManager.getRenderMode() === "virtual") {
22390  this.observer = new ResizeObserver(function (entry) {
22391  if (!table.browserMobile || table.browserMobile && !table.modules.edit.currentCell) {
22392  table.redraw();
22393  }
22394  });
22395 
22396  this.observer.observe(table.element);
22397  } else {
22398  this.binding = function () {
22399  if (!table.browserMobile || table.browserMobile && !table.modules.edit.currentCell) {
22400  table.redraw();
22401  }
22402  };
22403 
22404  window.addEventListener("resize", this.binding);
22405  }
22406  };
22407 
22408  ResizeTable.prototype.clearBindings = function (row) {
22409  if (this.binding) {
22410  window.removeEventListener("resize", this.binding);
22411  }
22412 
22413  if (this.observer) {
22414  this.observer.unobserve(this.table.element);
22415  }
22416  };
22417 
22418  Tabulator.prototype.registerModule("resizeTable", ResizeTable);
22419  var ResponsiveLayout = function ResponsiveLayout(table) {
22420  this.table = table; //hold Tabulator object
22421  this.columns = [];
22422  this.hiddenColumns = [];
22423  this.mode = "";
22424  this.index = 0;
22425  this.collapseFormatter = [];
22426  this.collapseStartOpen = true;
22427  this.collapseHandleColumn = false;
22428  };
22429 
22430  //generate resposive columns list
22431  ResponsiveLayout.prototype.initialize = function () {
22432  var self = this,
22433  columns = [];
22434 
22435  this.mode = this.table.options.responsiveLayout;
22436  this.collapseFormatter = this.table.options.responsiveLayoutCollapseFormatter || this.formatCollapsedData;
22437  this.collapseStartOpen = this.table.options.responsiveLayoutCollapseStartOpen;
22438  this.hiddenColumns = [];
22439 
22440  //detemine level of responsivity for each column
22441  this.table.columnManager.columnsByIndex.forEach(function (column, i) {
22442  if (column.modules.responsive) {
22443  if (column.modules.responsive.order && column.modules.responsive.visible) {
22444  column.modules.responsive.index = i;
22445  columns.push(column);
22446 
22447  if (!column.visible && self.mode === "collapse") {
22448  self.hiddenColumns.push(column);
22449  }
22450  }
22451  }
22452  });
22453 
22454  //sort list by responsivity
22455  columns = columns.reverse();
22456  columns = columns.sort(function (a, b) {
22457  var diff = b.modules.responsive.order - a.modules.responsive.order;
22458  return diff || b.modules.responsive.index - a.modules.responsive.index;
22459  });
22460 
22461  this.columns = columns;
22462 
22463  if (this.mode === "collapse") {
22464  this.generateCollapsedContent();
22465  }
22466 
22467  //assign collapse column
22468  for (var _iterator = this.table.columnManager.columnsByIndex, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
22469  var _ref;
22470 
22471  if (_isArray) {
22472  if (_i >= _iterator.length) break;
22473  _ref = _iterator[_i++];
22474  } else {
22475  _i = _iterator.next();
22476  if (_i.done) break;
22477  _ref = _i.value;
22478  }
22479 
22480  var col = _ref;
22481 
22482  if (col.definition.formatter == "responsiveCollapse") {
22483  this.collapseHandleColumn = col;
22484  break;
22485  }
22486  }
22487 
22488  if (this.collapseHandleColumn) {
22489  if (this.hiddenColumns.length) {
22490  this.collapseHandleColumn.show();
22491  } else {
22492  this.collapseHandleColumn.hide();
22493  }
22494  }
22495  };
22496 
22497  //define layout information
22498  ResponsiveLayout.prototype.initializeColumn = function (column) {
22499  var def = column.getDefinition();
22500 
22501  column.modules.responsive = { order: typeof def.responsive === "undefined" ? 1 : def.responsive, visible: def.visible === false ? false : true };
22502  };
22503 
22504  ResponsiveLayout.prototype.initializeRow = function (row) {
22505  var el;
22506 
22507  if (row.type !== "calc") {
22508  el = document.createElement("div");
22509  el.classList.add("tabulator-responsive-collapse");
22510 
22511  row.modules.responsiveLayout = {
22512  element: el,
22513  open: this.collapseStartOpen
22514  };
22515 
22516  if (!this.collapseStartOpen) {
22517  el.style.display = 'none';
22518  }
22519  }
22520  };
22521 
22522  ResponsiveLayout.prototype.layoutRow = function (row) {
22523  var rowEl = row.getElement();
22524 
22525  if (row.modules.responsiveLayout) {
22526  rowEl.appendChild(row.modules.responsiveLayout.element);
22527  this.generateCollapsedRowContent(row);
22528  }
22529  };
22530 
22531  //update column visibility
22532  ResponsiveLayout.prototype.updateColumnVisibility = function (column, visible) {
22533  var index;
22534  if (column.modules.responsive) {
22535  column.modules.responsive.visible = visible;
22536  this.initialize();
22537  }
22538  };
22539 
22540  ResponsiveLayout.prototype.hideColumn = function (column) {
22541  var colCount = this.hiddenColumns.length;
22542 
22543  column.hide(false, true);
22544 
22545  if (this.mode === "collapse") {
22546  this.hiddenColumns.unshift(column);
22547  this.generateCollapsedContent();
22548 
22549  if (this.collapseHandleColumn && !colCount) {
22550  this.collapseHandleColumn.show();
22551  }
22552  }
22553  };
22554 
22555  ResponsiveLayout.prototype.showColumn = function (column) {
22556  var index;
22557 
22558  column.show(false, true);
22559  //set column width to prevent calculation loops on uninitialized columns
22560  column.setWidth(column.getWidth());
22561 
22562  if (this.mode === "collapse") {
22563  index = this.hiddenColumns.indexOf(column);
22564 
22565  if (index > -1) {
22566  this.hiddenColumns.splice(index, 1);
22567  }
22568 
22569  this.generateCollapsedContent();
22570 
22571  if (this.collapseHandleColumn && !this.hiddenColumns.length) {
22572  this.collapseHandleColumn.hide();
22573  }
22574  }
22575  };
22576 
22577  //redraw columns to fit space
22578  ResponsiveLayout.prototype.update = function () {
22579  var self = this,
22580  working = true;
22581 
22582  while (working) {
22583 
22584  var width = self.table.modules.layout.getMode() == "fitColumns" ? self.table.columnManager.getFlexBaseWidth() : self.table.columnManager.getWidth();
22585 
22586  var diff = (self.table.options.headerVisible ? self.table.columnManager.element.clientWidth : self.table.element.clientWidth) - width;
22587 
22588  if (diff < 0) {
22589  //table is too wide
22590  var column = self.columns[self.index];
22591 
22592  if (column) {
22593  self.hideColumn(column);
22594  self.index++;
22595  } else {
22596  working = false;
22597  }
22598  } else {
22599 
22600  //table has spare space
22601  var _column = self.columns[self.index - 1];
22602 
22603  if (_column) {
22604  if (diff > 0) {
22605  if (diff >= _column.getWidth()) {
22606  self.showColumn(_column);
22607  self.index--;
22608  } else {
22609  working = false;
22610  }
22611  } else {
22612  working = false;
22613  }
22614  } else {
22615  working = false;
22616  }
22617  }
22618 
22619  if (!self.table.rowManager.activeRowsCount) {
22620  self.table.rowManager.renderEmptyScroll();
22621  }
22622  }
22623  };
22624 
22625  ResponsiveLayout.prototype.generateCollapsedContent = function () {
22626  var self = this,
22627  rows = this.table.rowManager.getDisplayRows();
22628 
22629  rows.forEach(function (row) {
22630  self.generateCollapsedRowContent(row);
22631  });
22632  };
22633 
22634  ResponsiveLayout.prototype.generateCollapsedRowContent = function (row) {
22635  var el, contents;
22636 
22637  if (row.modules.responsiveLayout) {
22638  el = row.modules.responsiveLayout.element;
22639 
22640  while (el.firstChild) {
22641  el.removeChild(el.firstChild);
22642  }contents = this.collapseFormatter(this.generateCollapsedRowData(row));
22643  if (contents) {
22644  el.appendChild(contents);
22645  }
22646  }
22647  };
22648 
22649  ResponsiveLayout.prototype.generateCollapsedRowData = function (row) {
22650  var self = this,
22651  data = row.getData(),
22652  output = [],
22653  mockCellComponent;
22654 
22655  this.hiddenColumns.forEach(function (column) {
22656  var value = column.getFieldValue(data);
22657 
22658  if (column.definition.title && column.field) {
22659  if (column.modules.format && self.table.options.responsiveLayoutCollapseUseFormatters) {
22660 
22661  mockCellComponent = {
22662  value: false,
22663  data: {},
22664  getValue: function getValue() {
22665  return value;
22666  },
22667  getData: function getData() {
22668  return data;
22669  },
22670  getElement: function getElement() {
22671  return document.createElement("div");
22672  },
22673  getRow: function getRow() {
22674  return row.getComponent();
22675  },
22676  getColumn: function getColumn() {
22677  return column.getComponent();
22678  }
22679  };
22680 
22681  output.push({
22682  title: column.definition.title,
22683  value: column.modules.format.formatter.call(self.table.modules.format, mockCellComponent, column.modules.format.params)
22684  });
22685  } else {
22686  output.push({
22687  title: column.definition.title,
22688  value: value
22689  });
22690  }
22691  }
22692  });
22693 
22694  return output;
22695  };
22696 
22697  ResponsiveLayout.prototype.formatCollapsedData = function (data) {
22698  var list = document.createElement("table"),
22699  listContents = "";
22700 
22701  data.forEach(function (item) {
22702  var div = document.createElement("div");
22703 
22704  if (item.value instanceof Node) {
22705  div.appendChild(item.value);
22706  item.value = div.innerHTML;
22707  }
22708 
22709  listContents += "<tr><td><strong>" + item.title + "</strong></td><td>" + item.value + "</td></tr>";
22710  });
22711 
22712  list.innerHTML = listContents;
22713 
22714  return Object.keys(data).length ? list : "";
22715  };
22716 
22717  Tabulator.prototype.registerModule("responsiveLayout", ResponsiveLayout);
22718 
22719  var SelectRow = function SelectRow(table) {
22720  this.table = table; //hold Tabulator object
22721  this.selecting = false; //flag selecting in progress
22722  this.lastClickedRow = false; //last clicked row
22723  this.selectPrev = []; //hold previously selected element for drag drop selection
22724  this.selectedRows = []; //hold selected rows
22725  this.headerCheckboxElement = null; // hold header select element
22726  };
22727 
22728  SelectRow.prototype.clearSelectionData = function (silent) {
22729  this.selecting = false;
22730  this.lastClickedRow = false;
22731  this.selectPrev = [];
22732  this.selectedRows = [];
22733 
22734  if (!silent) {
22735  this._rowSelectionChanged();
22736  }
22737  };
22738 
22739  SelectRow.prototype.initializeRow = function (row) {
22740  var self = this,
22741  element = row.getElement();
22742 
22743  // trigger end of row selection
22744  var endSelect = function endSelect() {
22745 
22746  setTimeout(function () {
22747  self.selecting = false;
22748  }, 50);
22749 
22750  document.body.removeEventListener("mouseup", endSelect);
22751  };
22752 
22753  row.modules.select = { selected: false };
22754 
22755  //set row selection class
22756  if (self.table.options.selectableCheck.call(this.table, row.getComponent())) {
22757  element.classList.add("tabulator-selectable");
22758  element.classList.remove("tabulator-unselectable");
22759 
22760  if (self.table.options.selectable && self.table.options.selectable != "highlight") {
22761  if (self.table.options.selectableRangeMode === "click") {
22762  element.addEventListener("click", function (e) {
22763  if (e.shiftKey) {
22764  self.table._clearSelection();
22765  self.lastClickedRow = self.lastClickedRow || row;
22766 
22767  var lastClickedRowIdx = self.table.rowManager.getDisplayRowIndex(self.lastClickedRow);
22768  var rowIdx = self.table.rowManager.getDisplayRowIndex(row);
22769 
22770  var fromRowIdx = lastClickedRowIdx <= rowIdx ? lastClickedRowIdx : rowIdx;
22771  var toRowIdx = lastClickedRowIdx >= rowIdx ? lastClickedRowIdx : rowIdx;
22772 
22773  var rows = self.table.rowManager.getDisplayRows().slice(0);
22774  var toggledRows = rows.splice(fromRowIdx, toRowIdx - fromRowIdx + 1);
22775 
22776  if (e.ctrlKey || e.metaKey) {
22777  toggledRows.forEach(function (toggledRow) {
22778  if (toggledRow !== self.lastClickedRow) {
22779 
22780  if (self.table.options.selectable !== true && !self.isRowSelected(row)) {
22781  if (self.selectedRows.length < self.table.options.selectable) {
22782  self.toggleRow(toggledRow);
22783  }
22784  } else {
22785  self.toggleRow(toggledRow);
22786  }
22787  }
22788  });
22789  self.lastClickedRow = row;
22790  } else {
22791  self.deselectRows();
22792 
22793  if (self.table.options.selectable !== true) {
22794  if (toggledRows.length > self.table.options.selectable) {
22795  toggledRows = toggledRows.slice(0, self.table.options.selectable);
22796  }
22797  }
22798 
22799  self.selectRows(toggledRows);
22800  }
22801  self.table._clearSelection();
22802  } else if (e.ctrlKey || e.metaKey) {
22803  self.toggleRow(row);
22804  self.lastClickedRow = row;
22805  } else {
22806  self.deselectRows();
22807  self.selectRows(row);
22808  self.lastClickedRow = row;
22809  }
22810  });
22811  } else {
22812  element.addEventListener("click", function (e) {
22813  if (!self.table.modExists("edit") || !self.table.modules.edit.getCurrentCell()) {
22814  self.table._clearSelection();
22815  }
22816 
22817  if (!self.selecting) {
22818  self.toggleRow(row);
22819  }
22820  });
22821 
22822  element.addEventListener("mousedown", function (e) {
22823  if (e.shiftKey) {
22824  self.table._clearSelection();
22825 
22826  self.selecting = true;
22827 
22828  self.selectPrev = [];
22829 
22830  document.body.addEventListener("mouseup", endSelect);
22831  document.body.addEventListener("keyup", endSelect);
22832 
22833  self.toggleRow(row);
22834 
22835  return false;
22836  }
22837  });
22838 
22839  element.addEventListener("mouseenter", function (e) {
22840  if (self.selecting) {
22841  self.table._clearSelection();
22842  self.toggleRow(row);
22843 
22844  if (self.selectPrev[1] == row) {
22845  self.toggleRow(self.selectPrev[0]);
22846  }
22847  }
22848  });
22849 
22850  element.addEventListener("mouseout", function (e) {
22851  if (self.selecting) {
22852  self.table._clearSelection();
22853  self.selectPrev.unshift(row);
22854  }
22855  });
22856  }
22857  }
22858  } else {
22859  element.classList.add("tabulator-unselectable");
22860  element.classList.remove("tabulator-selectable");
22861  }
22862  };
22863 
22864  //toggle row selection
22865  SelectRow.prototype.toggleRow = function (row) {
22866  if (this.table.options.selectableCheck.call(this.table, row.getComponent())) {
22867  if (row.modules.select && row.modules.select.selected) {
22868  this._deselectRow(row);
22869  } else {
22870  this._selectRow(row);
22871  }
22872  }
22873  };
22874 
22875  //select a number of rows
22876  SelectRow.prototype.selectRows = function (rows) {
22877  var _this65 = this;
22878 
22879  var rowMatch;
22880 
22881  switch (typeof rows === 'undefined' ? 'undefined' : _typeof(rows)) {
22882  case "undefined":
22883  this.table.rowManager.rows.forEach(function (row) {
22884  _this65._selectRow(row, true, true);
22885  });
22886 
22887  this._rowSelectionChanged();
22888  break;
22889 
22890  case "string":
22891 
22892  rowMatch = this.table.rowManager.findRow(rows);
22893 
22894  if (rowMatch) {
22895  this._selectRow(rowMatch, true, true);
22896  } else {
22897  this.table.rowManager.getRows(rows).forEach(function (row) {
22898  _this65._selectRow(row, true, true);
22899  });
22900  }
22901 
22902  this._rowSelectionChanged();
22903  break;
22904 
22905  default:
22906  if (Array.isArray(rows)) {
22907  rows.forEach(function (row) {
22908  _this65._selectRow(row, true, true);
22909  });
22910 
22911  this._rowSelectionChanged();
22912  } else {
22913  this._selectRow(rows, false, true);
22914  }
22915  break;
22916  }
22917  };
22918 
22919  //select an individual row
22920  SelectRow.prototype._selectRow = function (rowInfo, silent, force) {
22921  var index;
22922 
22923  //handle max row count
22924  if (!isNaN(this.table.options.selectable) && this.table.options.selectable !== true && !force) {
22925  if (this.selectedRows.length >= this.table.options.selectable) {
22926  if (this.table.options.selectableRollingSelection) {
22927  this._deselectRow(this.selectedRows[0]);
22928  } else {
22929  return false;
22930  }
22931  }
22932  }
22933 
22934  var row = this.table.rowManager.findRow(rowInfo);
22935 
22936  if (row) {
22937  if (this.selectedRows.indexOf(row) == -1) {
22938  if (!row.modules.select) {
22939  row.modules.select = {};
22940  }
22941 
22942  row.modules.select.selected = true;
22943  if (row.modules.select.checkboxEl) {
22944  row.modules.select.checkboxEl.checked = true;
22945  }
22946  row.getElement().classList.add("tabulator-selected");
22947 
22948  this.selectedRows.push(row);
22949 
22950  if (!silent) {
22951  this.table.options.rowSelected.call(this.table, row.getComponent());
22952  this._rowSelectionChanged();
22953  }
22954  }
22955  } else {
22956  if (!silent) {
22957  console.warn("Selection Error - No such row found, ignoring selection:" + rowInfo);
22958  }
22959  }
22960  };
22961 
22962  SelectRow.prototype.isRowSelected = function (row) {
22963  return this.selectedRows.indexOf(row) !== -1;
22964  };
22965 
22966  //deselect a number of rows
22967  SelectRow.prototype.deselectRows = function (rows) {
22968  var self = this,
22969  rowCount;
22970 
22971  if (typeof rows == "undefined") {
22972 
22973  rowCount = self.selectedRows.length;
22974 
22975  for (var i = 0; i < rowCount; i++) {
22976  self._deselectRow(self.selectedRows[0], true);
22977  }
22978 
22979  self._rowSelectionChanged();
22980  } else {
22981  if (Array.isArray(rows)) {
22982  rows.forEach(function (row) {
22983  self._deselectRow(row, true);
22984  });
22985 
22986  self._rowSelectionChanged();
22987  } else {
22988  self._deselectRow(rows);
22989  }
22990  }
22991  };
22992 
22993  //deselect an individual row
22994  SelectRow.prototype._deselectRow = function (rowInfo, silent) {
22995  var self = this,
22996  row = self.table.rowManager.findRow(rowInfo),
22997  index;
22998 
22999  if (row) {
23000  index = self.selectedRows.findIndex(function (selectedRow) {
23001  return selectedRow == row;
23002  });
23003 
23004  if (index > -1) {
23005 
23006  if (!row.modules.select) {
23007  row.modules.select = {};
23008  }
23009 
23010  row.modules.select.selected = false;
23011  if (row.modules.select.checkboxEl) {
23012  row.modules.select.checkboxEl.checked = false;
23013  }
23014  row.getElement().classList.remove("tabulator-selected");
23015  self.selectedRows.splice(index, 1);
23016 
23017  if (!silent) {
23018  self.table.options.rowDeselected.call(this.table, row.getComponent());
23019  self._rowSelectionChanged();
23020  }
23021  }
23022  } else {
23023  if (!silent) {
23024  console.warn("Deselection Error - No such row found, ignoring selection:" + rowInfo);
23025  }
23026  }
23027  };
23028 
23029  SelectRow.prototype.getSelectedData = function () {
23030  var data = [];
23031 
23032  this.selectedRows.forEach(function (row) {
23033  data.push(row.getData());
23034  });
23035 
23036  return data;
23037  };
23038 
23039  SelectRow.prototype.getSelectedRows = function () {
23040 
23041  var rows = [];
23042 
23043  this.selectedRows.forEach(function (row) {
23044  rows.push(row.getComponent());
23045  });
23046 
23047  return rows;
23048  };
23049 
23050  SelectRow.prototype._rowSelectionChanged = function () {
23051  if (this.headerCheckboxElement) {
23052  if (this.selectedRows.length === 0) {
23053  this.headerCheckboxElement.checked = false;
23054  this.headerCheckboxElement.indeterminate = false;
23055  } else if (this.table.rowManager.rows.length === this.selectedRows.length) {
23056  this.headerCheckboxElement.checked = true;
23057  this.headerCheckboxElement.indeterminate = false;
23058  } else {
23059  this.headerCheckboxElement.indeterminate = true;
23060  this.headerCheckboxElement.checked = false;
23061  }
23062  }
23063 
23064  this.table.options.rowSelectionChanged.call(this.table, this.getSelectedData(), this.getSelectedRows());
23065  };
23066 
23067  SelectRow.prototype.registerRowSelectCheckbox = function (row, element) {
23068  if (!row._row.modules.select) {
23069  row._row.modules.select = {};
23070  }
23071 
23072  row._row.modules.select.checkboxEl = element;
23073  };
23074 
23075  SelectRow.prototype.registerHeaderSelectCheckbox = function (element) {
23076  this.headerCheckboxElement = element;
23077  };
23078 
23079  Tabulator.prototype.registerModule("selectRow", SelectRow);
23080 
23081  var Sort = function Sort(table) {
23082  this.table = table; //hold Tabulator object
23083  this.sortList = []; //holder current sort
23084  this.changed = false; //has the sort changed since last render
23085  };
23086 
23087  //initialize column header for sorting
23088  Sort.prototype.initializeColumn = function (column, content) {
23089  var self = this,
23090  sorter = false,
23091  colEl,
23092  arrowEl;
23093 
23094  switch (_typeof(column.definition.sorter)) {
23095  case "string":
23096  if (self.sorters[column.definition.sorter]) {
23097  sorter = self.sorters[column.definition.sorter];
23098  } else {
23099  console.warn("Sort Error - No such sorter found: ", column.definition.sorter);
23100  }
23101  break;
23102 
23103  case "function":
23104  sorter = column.definition.sorter;
23105  break;
23106  }
23107 
23108  column.modules.sort = {
23109  sorter: sorter, dir: "none",
23110  params: column.definition.sorterParams || {},
23111  startingDir: column.definition.headerSortStartingDir || "asc",
23112  tristate: typeof column.definition.headerSortTristate !== "undefined" ? column.definition.headerSortTristate : this.table.options.headerSortTristate
23113  };
23114 
23115  if (typeof column.definition.headerSort === "undefined" ? this.table.options.headerSort !== false : column.definition.headerSort !== false) {
23116 
23117  colEl = column.getElement();
23118 
23119  colEl.classList.add("tabulator-sortable");
23120 
23121  arrowEl = document.createElement("div");
23122  arrowEl.classList.add("tabulator-arrow");
23123  //create sorter arrow
23124  content.appendChild(arrowEl);
23125 
23126  //sort on click
23127  colEl.addEventListener("click", function (e) {
23128  var dir = "",
23129  sorters = [],
23130  match = false;
23131 
23132  if (column.modules.sort) {
23133  if (column.modules.sort.tristate) {
23134  if (column.modules.sort.dir == "none") {
23135  dir = column.modules.sort.startingDir;
23136  } else {
23137  if (column.modules.sort.dir == column.modules.sort.startingDir) {
23138  dir = column.modules.sort.dir == "asc" ? "desc" : "asc";
23139  } else {
23140  dir = "none";
23141  }
23142  }
23143  } else {
23144  switch (column.modules.sort.dir) {
23145  case "asc":
23146  dir = "desc";
23147  break;
23148 
23149  case "desc":
23150  dir = "asc";
23151  break;
23152 
23153  default:
23154  dir = column.modules.sort.startingDir;
23155  }
23156  }
23157 
23158  if (self.table.options.columnHeaderSortMulti && (e.shiftKey || e.ctrlKey)) {
23159  sorters = self.getSort();
23160 
23161  match = sorters.findIndex(function (sorter) {
23162  return sorter.field === column.getField();
23163  });
23164 
23165  if (match > -1) {
23166  sorters[match].dir = dir;
23167 
23168  if (match != sorters.length - 1) {
23169  match = sorters.splice(match, 1)[0];
23170  if (dir != "none") {
23171  sorters.push(match);
23172  }
23173  }
23174  } else {
23175  if (dir != "none") {
23176  sorters.push({ column: column, dir: dir });
23177  }
23178  }
23179 
23180  //add to existing sort
23181  self.setSort(sorters);
23182  } else {
23183  if (dir == "none") {
23184  self.clear();
23185  } else {
23186  //sort by column only
23187  self.setSort(column, dir);
23188  }
23189  }
23190 
23191  self.table.rowManager.sorterRefresh(!self.sortList.length);
23192  }
23193  });
23194  }
23195  };
23196 
23197  //check if the sorters have changed since last use
23198  Sort.prototype.hasChanged = function () {
23199  var changed = this.changed;
23200  this.changed = false;
23201  return changed;
23202  };
23203 
23204  //return current sorters
23205  Sort.prototype.getSort = function () {
23206  var self = this,
23207  sorters = [];
23208 
23209  self.sortList.forEach(function (item) {
23210  if (item.column) {
23211  sorters.push({ column: item.column.getComponent(), field: item.column.getField(), dir: item.dir });
23212  }
23213  });
23214 
23215  return sorters;
23216  };
23217 
23218  //change sort list and trigger sort
23219  Sort.prototype.setSort = function (sortList, dir) {
23220  var self = this,
23221  newSortList = [];
23222 
23223  if (!Array.isArray(sortList)) {
23224  sortList = [{ column: sortList, dir: dir }];
23225  }
23226 
23227  sortList.forEach(function (item) {
23228  var column;
23229 
23230  column = self.table.columnManager.findColumn(item.column);
23231 
23232  if (column) {
23233  item.column = column;
23234  newSortList.push(item);
23235  self.changed = true;
23236  } else {
23237  console.warn("Sort Warning - Sort field does not exist and is being ignored: ", item.column);
23238  }
23239  });
23240 
23241  self.sortList = newSortList;
23242 
23243  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.sort) {
23244  this.table.modules.persistence.save("sort");
23245  }
23246  };
23247 
23248  //clear sorters
23249  Sort.prototype.clear = function () {
23250  this.setSort([]);
23251  };
23252 
23253  //find appropriate sorter for column
23254  Sort.prototype.findSorter = function (column) {
23255  var row = this.table.rowManager.activeRows[0],
23256  sorter = "string",
23257  field,
23258  value;
23259 
23260  if (row) {
23261  row = row.getData();
23262  field = column.getField();
23263 
23264  if (field) {
23265 
23266  value = column.getFieldValue(row);
23267 
23268  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
23269  case "undefined":
23270  sorter = "string";
23271  break;
23272 
23273  case "boolean":
23274  sorter = "boolean";
23275  break;
23276 
23277  default:
23278  if (!isNaN(value) && value !== "") {
23279  sorter = "number";
23280  } else {
23281  if (value.match(/((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+$/i)) {
23282  sorter = "alphanum";
23283  }
23284  }
23285  break;
23286  }
23287  }
23288  }
23289 
23290  return this.sorters[sorter];
23291  };
23292 
23293  //work through sort list sorting data
23294  Sort.prototype.sort = function (data) {
23295  var self = this,
23296  lastSort,
23297  sortList;
23298 
23299  sortList = this.table.options.sortOrderReverse ? self.sortList.slice().reverse() : self.sortList;
23300 
23301  if (self.table.options.dataSorting) {
23302  self.table.options.dataSorting.call(self.table, self.getSort());
23303  }
23304 
23305  self.clearColumnHeaders();
23306 
23307  if (!self.table.options.ajaxSorting) {
23308 
23309  sortList.forEach(function (item, i) {
23310 
23311  if (item.column && item.column.modules.sort) {
23312 
23313  //if no sorter has been defined, take a guess
23314  if (!item.column.modules.sort.sorter) {
23315  item.column.modules.sort.sorter = self.findSorter(item.column);
23316  }
23317 
23318  self._sortItem(data, item.column, item.dir, sortList, i);
23319  }
23320 
23321  self.setColumnHeader(item.column, item.dir);
23322  });
23323  } else {
23324  sortList.forEach(function (item, i) {
23325  self.setColumnHeader(item.column, item.dir);
23326  });
23327  }
23328 
23329  if (self.table.options.dataSorted) {
23330  self.table.options.dataSorted.call(self.table, self.getSort(), self.table.rowManager.getComponents("active"));
23331  }
23332  };
23333 
23334  //clear sort arrows on columns
23335  Sort.prototype.clearColumnHeaders = function () {
23336  this.table.columnManager.getRealColumns().forEach(function (column) {
23337  if (column.modules.sort) {
23338  column.modules.sort.dir = "none";
23339  column.getElement().setAttribute("aria-sort", "none");
23340  }
23341  });
23342  };
23343 
23344  //set the column header sort direction
23345  Sort.prototype.setColumnHeader = function (column, dir) {
23346  column.modules.sort.dir = dir;
23347  column.getElement().setAttribute("aria-sort", dir);
23348  };
23349 
23350  //sort each item in sort list
23351  Sort.prototype._sortItem = function (data, column, dir, sortList, i) {
23352  var self = this;
23353 
23354  var params = typeof column.modules.sort.params === "function" ? column.modules.sort.params(column.getComponent(), dir) : column.modules.sort.params;
23355 
23356  data.sort(function (a, b) {
23357 
23358  var result = self._sortRow(a, b, column, dir, params);
23359 
23360  //if results match recurse through previous searchs to be sure
23361  if (result === 0 && i) {
23362  for (var j = i - 1; j >= 0; j--) {
23363  result = self._sortRow(a, b, sortList[j].column, sortList[j].dir, params);
23364 
23365  if (result !== 0) {
23366  break;
23367  }
23368  }
23369  }
23370 
23371  return result;
23372  });
23373  };
23374 
23375  //process individual rows for a sort function on active data
23376  Sort.prototype._sortRow = function (a, b, column, dir, params) {
23377  var el1Comp, el2Comp, colComp;
23378 
23379  //switch elements depending on search direction
23380  var el1 = dir == "asc" ? a : b;
23381  var el2 = dir == "asc" ? b : a;
23382 
23383  a = column.getFieldValue(el1.getData());
23384  b = column.getFieldValue(el2.getData());
23385 
23386  a = typeof a !== "undefined" ? a : "";
23387  b = typeof b !== "undefined" ? b : "";
23388 
23389  el1Comp = el1.getComponent();
23390  el2Comp = el2.getComponent();
23391 
23392  return column.modules.sort.sorter.call(this, a, b, el1Comp, el2Comp, column.getComponent(), dir, params);
23393  };
23394 
23395  //default data sorters
23396  Sort.prototype.sorters = {
23397 
23398  //sort numbers
23399  number: function number(a, b, aRow, bRow, column, dir, params) {
23400  var alignEmptyValues = params.alignEmptyValues;
23401  var decimal = params.decimalSeparator || ".";
23402  var thousand = params.thousandSeparator || ",";
23403  var emptyAlign = 0;
23404 
23405  a = parseFloat(String(a).split(thousand).join("").split(decimal).join("."));
23406  b = parseFloat(String(b).split(thousand).join("").split(decimal).join("."));
23407 
23408  //handle non numeric values
23409  if (isNaN(a)) {
23410  emptyAlign = isNaN(b) ? 0 : -1;
23411  } else if (isNaN(b)) {
23412  emptyAlign = 1;
23413  } else {
23414  //compare valid values
23415  return a - b;
23416  }
23417 
23418  //fix empty values in position
23419  if (alignEmptyValues === "top" && dir === "desc" || alignEmptyValues === "bottom" && dir === "asc") {
23420  emptyAlign *= -1;
23421  }
23422 
23423  return emptyAlign;
23424  },
23425 
23426  //sort strings
23427  string: function string(a, b, aRow, bRow, column, dir, params) {
23428  var alignEmptyValues = params.alignEmptyValues;
23429  var emptyAlign = 0;
23430  var locale;
23431 
23432  //handle empty values
23433  if (!a) {
23434  emptyAlign = !b ? 0 : -1;
23435  } else if (!b) {
23436  emptyAlign = 1;
23437  } else {
23438  //compare valid values
23439  switch (_typeof(params.locale)) {
23440  case "boolean":
23441  if (params.locale) {
23442  locale = this.table.modules.localize.getLocale();
23443  }
23444  break;
23445  case "string":
23446  locale = params.locale;
23447  break;
23448  }
23449 
23450  return String(a).toLowerCase().localeCompare(String(b).toLowerCase(), locale);
23451  }
23452 
23453  //fix empty values in position
23454  if (alignEmptyValues === "top" && dir === "desc" || alignEmptyValues === "bottom" && dir === "asc") {
23455  emptyAlign *= -1;
23456  }
23457 
23458  return emptyAlign;
23459  },
23460 
23461  //sort date
23462  date: function date(a, b, aRow, bRow, column, dir, params) {
23463  if (!params.format) {
23464  params.format = "DD/MM/YYYY";
23465  }
23466 
23467  return this.sorters.datetime.call(this, a, b, aRow, bRow, column, dir, params);
23468  },
23469 
23470  //sort hh:mm formatted times
23471  time: function time(a, b, aRow, bRow, column, dir, params) {
23472  if (!params.format) {
23473  params.format = "hh:mm";
23474  }
23475 
23476  return this.sorters.datetime.call(this, a, b, aRow, bRow, column, dir, params);
23477  },
23478 
23479  //sort datetime
23480  datetime: function datetime(a, b, aRow, bRow, column, dir, params) {
23481  var format = params.format || "DD/MM/YYYY hh:mm:ss",
23482  alignEmptyValues = params.alignEmptyValues,
23483  emptyAlign = 0;
23484 
23485  if (typeof moment != "undefined") {
23486  a = moment(a, format);
23487  b = moment(b, format);
23488 
23489  if (!a.isValid()) {
23490  emptyAlign = !b.isValid() ? 0 : -1;
23491  } else if (!b.isValid()) {
23492  emptyAlign = 1;
23493  } else {
23494  //compare valid values
23495  return a - b;
23496  }
23497 
23498  //fix empty values in position
23499  if (alignEmptyValues === "top" && dir === "desc" || alignEmptyValues === "bottom" && dir === "asc") {
23500  emptyAlign *= -1;
23501  }
23502 
23503  return emptyAlign;
23504  } else {
23505  console.error("Sort Error - 'datetime' sorter is dependant on moment.js");
23506  }
23507  },
23508 
23509  //sort booleans
23510  boolean: function boolean(a, b, aRow, bRow, column, dir, params) {
23511  var el1 = a === true || a === "true" || a === "True" || a === 1 ? 1 : 0;
23512  var el2 = b === true || b === "true" || b === "True" || b === 1 ? 1 : 0;
23513 
23514  return el1 - el2;
23515  },
23516 
23517  //sort if element contains any data
23518  array: function array(a, b, aRow, bRow, column, dir, params) {
23519  var el1 = 0;
23520  var el2 = 0;
23521  var type = params.type || "length";
23522  var alignEmptyValues = params.alignEmptyValues;
23523  var emptyAlign = 0;
23524 
23525  function calc(value) {
23526 
23527  switch (type) {
23528  case "length":
23529  return value.length;
23530  break;
23531 
23532  case "sum":
23533  return value.reduce(function (c, d) {
23534  return c + d;
23535  });
23536  break;
23537 
23538  case "max":
23539  return Math.max.apply(null, value);
23540  break;
23541 
23542  case "min":
23543  return Math.min.apply(null, value);
23544  break;
23545 
23546  case "avg":
23547  return value.reduce(function (c, d) {
23548  return c + d;
23549  }) / value.length;
23550  break;
23551  }
23552  }
23553 
23554  //handle non array values
23555  if (!Array.isArray(a)) {
23556  alignEmptyValues = !Array.isArray(b) ? 0 : -1;
23557  } else if (!Array.isArray(b)) {
23558  alignEmptyValues = 1;
23559  } else {
23560 
23561  //compare valid values
23562  el1 = a ? calc(a) : 0;
23563  el2 = b ? calc(b) : 0;
23564 
23565  return el1 - el2;
23566  }
23567 
23568  //fix empty values in position
23569  if (alignEmptyValues === "top" && dir === "desc" || alignEmptyValues === "bottom" && dir === "asc") {
23570  emptyAlign *= -1;
23571  }
23572 
23573  return emptyAlign;
23574  },
23575 
23576  //sort if element contains any data
23577  exists: function exists(a, b, aRow, bRow, column, dir, params) {
23578  var el1 = typeof a == "undefined" ? 0 : 1;
23579  var el2 = typeof b == "undefined" ? 0 : 1;
23580 
23581  return el1 - el2;
23582  },
23583 
23584  //sort alpha numeric strings
23585  alphanum: function alphanum(as, bs, aRow, bRow, column, dir, params) {
23586  var a,
23587  b,
23588  a1,
23589  b1,
23590  i = 0,
23591  L,
23592  rx = /(\d+)|(\D+)/g,
23593  rd = /\d/;
23594  var alignEmptyValues = params.alignEmptyValues;
23595  var emptyAlign = 0;
23596 
23597  //handle empty values
23598  if (!as && as !== 0) {
23599  emptyAlign = !bs && bs !== 0 ? 0 : -1;
23600  } else if (!bs && bs !== 0) {
23601  emptyAlign = 1;
23602  } else {
23603 
23604  if (isFinite(as) && isFinite(bs)) return as - bs;
23605  a = String(as).toLowerCase();
23606  b = String(bs).toLowerCase();
23607  if (a === b) return 0;
23608  if (!(rd.test(a) && rd.test(b))) return a > b ? 1 : -1;
23609  a = a.match(rx);
23610  b = b.match(rx);
23611  L = a.length > b.length ? b.length : a.length;
23612  while (i < L) {
23613  a1 = a[i];
23614  b1 = b[i++];
23615  if (a1 !== b1) {
23616  if (isFinite(a1) && isFinite(b1)) {
23617  if (a1.charAt(0) === "0") a1 = "." + a1;
23618  if (b1.charAt(0) === "0") b1 = "." + b1;
23619  return a1 - b1;
23620  } else return a1 > b1 ? 1 : -1;
23621  }
23622  }
23623 
23624  return a.length > b.length;
23625  }
23626 
23627  //fix empty values in position
23628  if (alignEmptyValues === "top" && dir === "desc" || alignEmptyValues === "bottom" && dir === "asc") {
23629  emptyAlign *= -1;
23630  }
23631 
23632  return emptyAlign;
23633  }
23634  };
23635 
23636  Tabulator.prototype.registerModule("sort", Sort);
23637 
23638  var Validate = function Validate(table) {
23639  this.table = table;
23640  };
23641 
23642  //validate
23643  Validate.prototype.initializeColumn = function (column) {
23644  var self = this,
23645  config = [],
23646  validator;
23647 
23648  if (column.definition.validator) {
23649 
23650  if (Array.isArray(column.definition.validator)) {
23651  column.definition.validator.forEach(function (item) {
23652  validator = self._extractValidator(item);
23653 
23654  if (validator) {
23655  config.push(validator);
23656  }
23657  });
23658  } else {
23659  validator = this._extractValidator(column.definition.validator);
23660 
23661  if (validator) {
23662  config.push(validator);
23663  }
23664  }
23665 
23666  column.modules.validate = config.length ? config : false;
23667  }
23668  };
23669 
23670  Validate.prototype._extractValidator = function (value) {
23671  var type, params, pos;
23672 
23673  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
23674  case "string":
23675  pos = value.indexOf(':');
23676 
23677  if (pos > -1) {
23678  type = value.substring(0, pos);
23679  params = value.substring(pos + 1);
23680  } else {
23681  type = value;
23682  }
23683 
23684  return this._buildValidator(type, params);
23685  break;
23686 
23687  case "function":
23688  return this._buildValidator(value);
23689  break;
23690 
23691  case "object":
23692  return this._buildValidator(value.type, value.parameters);
23693  break;
23694  }
23695  };
23696 
23697  Validate.prototype._buildValidator = function (type, params) {
23698 
23699  var func = typeof type == "function" ? type : this.validators[type];
23700 
23701  if (!func) {
23702  console.warn("Validator Setup Error - No matching validator found:", type);
23703  return false;
23704  } else {
23705  return {
23706  type: typeof type == "function" ? "function" : type,
23707  func: func,
23708  params: params
23709  };
23710  }
23711  };
23712 
23713  Validate.prototype.validate = function (validators, cell, value) {
23714  var self = this,
23715  valid = [];
23716 
23717  if (validators) {
23718  validators.forEach(function (item) {
23719  if (!item.func.call(self, cell, value, item.params)) {
23720  valid.push({
23721  type: item.type,
23722  parameters: item.params
23723  });
23724  }
23725  });
23726  }
23727 
23728  return valid.length ? valid : true;
23729  };
23730 
23731  Validate.prototype.validators = {
23732 
23733  //is integer
23734  integer: function integer(cell, value, parameters) {
23735  if (value === "" || value === null || typeof value === "undefined") {
23736  return true;
23737  }
23738  value = Number(value);
23739  return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
23740  },
23741 
23742  //is float
23743  float: function float(cell, value, parameters) {
23744  if (value === "" || value === null || typeof value === "undefined") {
23745  return true;
23746  }
23747  value = Number(value);
23748  return typeof value === 'number' && isFinite(value) && value % 1 !== 0;
23749  },
23750 
23751  //must be a number
23752  numeric: function numeric(cell, value, parameters) {
23753  if (value === "" || value === null || typeof value === "undefined") {
23754  return true;
23755  }
23756  return !isNaN(value);
23757  },
23758 
23759  //must be a string
23760  string: function string(cell, value, parameters) {
23761  if (value === "" || value === null || typeof value === "undefined") {
23762  return true;
23763  }
23764  return isNaN(value);
23765  },
23766 
23767  //maximum value
23768  max: function max(cell, value, parameters) {
23769  if (value === "" || value === null || typeof value === "undefined") {
23770  return true;
23771  }
23772  return parseFloat(value) <= parameters;
23773  },
23774 
23775  //minimum value
23776  min: function min(cell, value, parameters) {
23777  if (value === "" || value === null || typeof value === "undefined") {
23778  return true;
23779  }
23780  return parseFloat(value) >= parameters;
23781  },
23782 
23783  //minimum string length
23784  minLength: function minLength(cell, value, parameters) {
23785  if (value === "" || value === null || typeof value === "undefined") {
23786  return true;
23787  }
23788  return String(value).length >= parameters;
23789  },
23790 
23791  //maximum string length
23792  maxLength: function maxLength(cell, value, parameters) {
23793  if (value === "" || value === null || typeof value === "undefined") {
23794  return true;
23795  }
23796  return String(value).length <= parameters;
23797  },
23798 
23799  //in provided value list
23800  in: function _in(cell, value, parameters) {
23801  if (value === "" || value === null || typeof value === "undefined") {
23802  return true;
23803  }
23804  if (typeof parameters == "string") {
23805  parameters = parameters.split("|");
23806  }
23807 
23808  return value === "" || parameters.indexOf(value) > -1;
23809  },
23810 
23811  //must match provided regex
23812  regex: function regex(cell, value, parameters) {
23813  if (value === "" || value === null || typeof value === "undefined") {
23814  return true;
23815  }
23816  var reg = new RegExp(parameters);
23817 
23818  return reg.test(value);
23819  },
23820 
23821  //value must be unique in this column
23822  unique: function unique(cell, value, parameters) {
23823  if (value === "" || value === null || typeof value === "undefined") {
23824  return true;
23825  }
23826  var unique = true;
23827 
23828  var cellData = cell.getData();
23829  var column = cell.getColumn()._getSelf();
23830 
23831  this.table.rowManager.rows.forEach(function (row) {
23832  var data = row.getData();
23833 
23834  if (data !== cellData) {
23835  if (value == column.getFieldValue(data)) {
23836  unique = false;
23837  }
23838  }
23839  });
23840 
23841  return unique;
23842  },
23843 
23844  //must have a value
23845  required: function required(cell, value, parameters) {
23846  return value !== "" && value !== null && typeof value !== "undefined";
23847  }
23848  };
23849 
23850  Tabulator.prototype.registerModule("validate", Validate);
23851 
23852  return Tabulator;
23853 });