otsdaq_utilities  v2_05_02_indev
tabulator_core.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 'use strict';
4 
5 // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
6 
7 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; };
8 
9 if (!Array.prototype.findIndex) {
10 
11  Object.defineProperty(Array.prototype, 'findIndex', {
12 
13  value: function value(predicate) {
14 
15  // 1. Let O be ? ToObject(this value).
16 
17  if (this == null) {
18 
19  throw new TypeError('"this" is null or not defined');
20  }
21 
22  var o = Object(this);
23 
24  // 2. Let len be ? ToLength(? Get(O, "length")).
25 
26  var len = o.length >>> 0;
27 
28  // 3. If IsCallable(predicate) is false, throw a TypeError exception.
29 
30  if (typeof predicate !== 'function') {
31 
32  throw new TypeError('predicate must be a function');
33  }
34 
35  // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
36 
37  var thisArg = arguments[1];
38 
39  // 5. Let k be 0.
40 
41  var k = 0;
42 
43  // 6. Repeat, while k < len
44 
45  while (k < len) {
46 
47  // a. Let Pk be ! ToString(k).
48 
49  // b. Let kValue be ? Get(O, Pk).
50 
51  // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
52 
53  // d. If testResult is true, return k.
54 
55  var kValue = o[k];
56 
57  if (predicate.call(thisArg, kValue, k, o)) {
58 
59  return k;
60  }
61 
62  // e. Increase k by 1.
63 
64  k++;
65  }
66 
67  // 7. Return -1.
68 
69  return -1;
70  }
71 
72  });
73 }
74 
75 // https://tc39.github.io/ecma262/#sec-array.prototype.find
76 
77 if (!Array.prototype.find) {
78 
79  Object.defineProperty(Array.prototype, 'find', {
80 
81  value: function value(predicate) {
82 
83  // 1. Let O be ? ToObject(this value).
84 
85  if (this == null) {
86 
87  throw new TypeError('"this" is null or not defined');
88  }
89 
90  var o = Object(this);
91 
92  // 2. Let len be ? ToLength(? Get(O, "length")).
93 
94  var len = o.length >>> 0;
95 
96  // 3. If IsCallable(predicate) is false, throw a TypeError exception.
97 
98  if (typeof predicate !== 'function') {
99 
100  throw new TypeError('predicate must be a function');
101  }
102 
103  // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
104 
105  var thisArg = arguments[1];
106 
107  // 5. Let k be 0.
108 
109  var k = 0;
110 
111  // 6. Repeat, while k < len
112 
113  while (k < len) {
114 
115  // a. Let Pk be ! ToString(k).
116 
117  // b. Let kValue be ? Get(O, Pk).
118 
119  // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
120 
121  // d. If testResult is true, return kValue.
122 
123  var kValue = o[k];
124 
125  if (predicate.call(thisArg, kValue, k, o)) {
126 
127  return kValue;
128  }
129 
130  // e. Increase k by 1.
131 
132  k++;
133  }
134 
135  // 7. Return undefined.
136 
137  return undefined;
138  }
139 
140  });
141 }
142 
143 var ColumnManager = function ColumnManager(table) {
144 
145  this.table = table; //hold parent table
146 
147  this.blockHozScrollEvent = false;
148 
149  this.headersElement = this.createHeadersElement();
150 
151  this.element = this.createHeaderElement(); //containing element
152 
153  this.rowManager = null; //hold row manager object
154 
155  this.columns = []; // column definition object
156 
157  this.columnsByIndex = []; //columns by index
158 
159  this.columnsByField = {}; //columns by field
160 
161  this.scrollLeft = 0;
162 
163  this.element.insertBefore(this.headersElement, this.element.firstChild);
164 };
165 
167 
168 
169 ColumnManager.prototype.createHeadersElement = function () {
170 
171  var el = document.createElement("div");
172 
173  el.classList.add("tabulator-headers");
174 
175  return el;
176 };
177 
178 ColumnManager.prototype.createHeaderElement = function () {
179 
180  var el = document.createElement("div");
181 
182  el.classList.add("tabulator-header");
183 
184  if (!this.table.options.headerVisible) {
185 
186  el.classList.add("tabulator-header-hidden");
187  }
188 
189  return el;
190 };
191 
192 ColumnManager.prototype.initialize = function () {
193 
194  var self = this;
195 
196  //scroll body along with header
197 
198  // self.element.addEventListener("scroll", function(e){
199 
200  // if(!self.blockHozScrollEvent){
201 
202  // self.table.rowManager.scrollHorizontal(self.element.scrollLeft);
203 
204  // }
205 
206  // });
207 };
208 
209 //link to row manager
210 
211 ColumnManager.prototype.setRowManager = function (manager) {
212 
213  this.rowManager = manager;
214 };
215 
216 //return containing element
217 
218 ColumnManager.prototype.getElement = function () {
219 
220  return this.element;
221 };
222 
223 //return header containing element
224 
225 ColumnManager.prototype.getHeadersElement = function () {
226 
227  return this.headersElement;
228 };
229 
230 // ColumnManager.prototype.tempScrollBlock = function(){
231 
232 // clearTimeout(this.blockHozScrollEvent);
233 
234 // this.blockHozScrollEvent = setTimeout(() => {this.blockHozScrollEvent = false;}, 50);
235 
236 // }
237 
238 
239 //scroll horizontally to match table body
240 
241 ColumnManager.prototype.scrollHorizontal = function (left) {
242 
243  var hozAdjust = 0,
244  scrollWidth = this.element.scrollWidth - this.table.element.clientWidth;
245 
246  // this.tempScrollBlock();
247 
248  this.element.scrollLeft = left;
249 
250  //adjust for vertical scrollbar moving table when present
251 
252  if (left > scrollWidth) {
253 
254  hozAdjust = left - scrollWidth;
255 
256  this.element.style.marginLeft = -hozAdjust + "px";
257  } else {
258 
259  this.element.style.marginLeft = 0;
260  }
261 
262  //keep frozen columns fixed in position
263 
264  //this._calcFrozenColumnsPos(hozAdjust + 3);
265 
266 
267  this.scrollLeft = left;
268 
269  if (this.table.modExists("frozenColumns")) {
270 
271  this.table.modules.frozenColumns.scrollHorizontal();
272  }
273 };
274 
276 
277 
278 ColumnManager.prototype.generateColumnsFromRowData = function (data) {
279 
280  var cols = [],
281  row,
282  sorter;
283 
284  if (data && data.length) {
285 
286  row = data[0];
287 
288  for (var key in row) {
289 
290  var col = {
291 
292  field: key,
293 
294  title: key
295 
296  };
297 
298  var value = row[key];
299 
300  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
301 
302  case "undefined":
303 
304  sorter = "string";
305 
306  break;
307 
308  case "boolean":
309 
310  sorter = "boolean";
311 
312  break;
313 
314  case "object":
315 
316  if (Array.isArray(value)) {
317 
318  sorter = "array";
319  } else {
320 
321  sorter = "string";
322  }
323 
324  break;
325 
326  default:
327 
328  if (!isNaN(value) && value !== "") {
329 
330  sorter = "number";
331  } else {
332 
333  if (value.match(/((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+$/i)) {
334 
335  sorter = "alphanum";
336  } else {
337 
338  sorter = "string";
339  }
340  }
341 
342  break;
343 
344  }
345 
346  col.sorter = sorter;
347 
348  cols.push(col);
349  }
350 
351  this.table.options.columns = cols;
352 
353  this.setColumns(this.table.options.columns);
354  }
355 };
356 
357 ColumnManager.prototype.setColumns = function (cols, row) {
358 
359  var self = this;
360 
361  while (self.headersElement.firstChild) {
362  self.headersElement.removeChild(self.headersElement.firstChild);
363  }self.columns = [];
364 
365  self.columnsByIndex = [];
366 
367  self.columnsByField = {};
368 
369  //reset frozen columns
370 
371  if (self.table.modExists("frozenColumns")) {
372 
373  self.table.modules.frozenColumns.reset();
374  }
375 
376  cols.forEach(function (def, i) {
377 
378  self._addColumn(def);
379  });
380 
381  self._reIndexColumns();
382 
383  if (self.table.options.responsiveLayout && self.table.modExists("responsiveLayout", true)) {
384 
385  self.table.modules.responsiveLayout.initialize();
386  }
387 
388  self.redraw(true);
389 };
390 
391 ColumnManager.prototype._addColumn = function (definition, before, nextToColumn) {
392 
393  var column = new Column(definition, this),
394  colEl = column.getElement(),
395  index = nextToColumn ? this.findColumnIndex(nextToColumn) : nextToColumn;
396 
397  if (nextToColumn && index > -1) {
398 
399  var parentIndex = this.columns.indexOf(nextToColumn.getTopColumn());
400 
401  var nextEl = nextToColumn.getElement();
402 
403  if (before) {
404 
405  this.columns.splice(parentIndex, 0, column);
406 
407  nextEl.parentNode.insertBefore(colEl, nextEl);
408  } else {
409 
410  this.columns.splice(parentIndex + 1, 0, column);
411 
412  nextEl.parentNode.insertBefore(colEl, nextEl.nextSibling);
413  }
414  } else {
415 
416  if (before) {
417 
418  this.columns.unshift(column);
419 
420  this.headersElement.insertBefore(column.getElement(), this.headersElement.firstChild);
421  } else {
422 
423  this.columns.push(column);
424 
425  this.headersElement.appendChild(column.getElement());
426  }
427 
428  column.columnRendered();
429  }
430 
431  return column;
432 };
433 
434 ColumnManager.prototype.registerColumnField = function (col) {
435 
436  if (col.definition.field) {
437 
438  this.columnsByField[col.definition.field] = col;
439  }
440 };
441 
442 ColumnManager.prototype.registerColumnPosition = function (col) {
443 
444  this.columnsByIndex.push(col);
445 };
446 
447 ColumnManager.prototype._reIndexColumns = function () {
448 
449  this.columnsByIndex = [];
450 
451  this.columns.forEach(function (column) {
452 
453  column.reRegisterPosition();
454  });
455 };
456 
457 //ensure column headers take up the correct amount of space in column groups
458 
459 ColumnManager.prototype._verticalAlignHeaders = function () {
460 
461  var self = this,
462  minHeight = 0;
463 
464  self.columns.forEach(function (column) {
465 
466  var height;
467 
468  column.clearVerticalAlign();
469 
470  height = column.getHeight();
471 
472  if (height > minHeight) {
473 
474  minHeight = height;
475  }
476  });
477 
478  self.columns.forEach(function (column) {
479 
480  column.verticalAlign(self.table.options.columnHeaderVertAlign, minHeight);
481  });
482 
483  self.rowManager.adjustTableSize();
484 };
485 
487 
488 
489 ColumnManager.prototype.findColumn = function (subject) {
490 
491  var self = this;
492 
493  if ((typeof subject === 'undefined' ? 'undefined' : _typeof(subject)) == "object") {
494 
495  if (subject instanceof Column) {
496 
497  //subject is column element
498 
499  return subject;
500  } else if (subject instanceof ColumnComponent) {
501 
502  //subject is public column component
503 
504  return subject._getSelf() || false;
505  } else if (typeof HTMLElement !== "undefined" && subject instanceof HTMLElement) {
506 
507  //subject is a HTML element of the column header
508 
509  var match = self.columns.find(function (column) {
510 
511  return column.element === subject;
512  });
513 
514  return match || false;
515  }
516  } else {
517 
518  //subject should be treated as the field name of the column
519 
520  return this.columnsByField[subject] || false;
521  }
522 
523  //catch all for any other type of input
524 
525 
526  return false;
527 };
528 
529 ColumnManager.prototype.getColumnByField = function (field) {
530 
531  return this.columnsByField[field];
532 };
533 
534 ColumnManager.prototype.getColumnsByFieldRoot = function (root) {
535  var _this = this;
536 
537  var matches = [];
538 
539  Object.keys(this.columnsByField).forEach(function (field) {
540 
541  var fieldRoot = field.split(".")[0];
542 
543  if (fieldRoot === root) {
544 
545  matches.push(_this.columnsByField[field]);
546  }
547  });
548 
549  return matches;
550 };
551 
552 ColumnManager.prototype.getColumnByIndex = function (index) {
553 
554  return this.columnsByIndex[index];
555 };
556 
557 ColumnManager.prototype.getFirstVisibileColumn = function (index) {
558 
559  var index = this.columnsByIndex.findIndex(function (col) {
560 
561  return col.visible;
562  });
563 
564  return index > -1 ? this.columnsByIndex[index] : false;
565 };
566 
567 ColumnManager.prototype.getColumns = function () {
568 
569  return this.columns;
570 };
571 
572 ColumnManager.prototype.findColumnIndex = function (column) {
573 
574  return this.columnsByIndex.findIndex(function (col) {
575 
576  return column === col;
577  });
578 };
579 
580 //return all columns that are not groups
581 
582 ColumnManager.prototype.getRealColumns = function () {
583 
584  return this.columnsByIndex;
585 };
586 
587 //travers across columns and call action
588 
589 ColumnManager.prototype.traverse = function (callback) {
590 
591  var self = this;
592 
593  self.columnsByIndex.forEach(function (column, i) {
594 
595  callback(column, i);
596  });
597 };
598 
599 //get defintions of actual columns
600 
601 ColumnManager.prototype.getDefinitions = function (active) {
602 
603  var self = this,
604  output = [];
605 
606  self.columnsByIndex.forEach(function (column) {
607 
608  if (!active || active && column.visible) {
609 
610  output.push(column.getDefinition());
611  }
612  });
613 
614  return output;
615 };
616 
617 //get full nested definition tree
618 
619 ColumnManager.prototype.getDefinitionTree = function () {
620 
621  var self = this,
622  output = [];
623 
624  self.columns.forEach(function (column) {
625 
626  output.push(column.getDefinition(true));
627  });
628 
629  return output;
630 };
631 
632 ColumnManager.prototype.getComponents = function (structured) {
633 
634  var self = this,
635  output = [],
636  columns = structured ? self.columns : self.columnsByIndex;
637 
638  columns.forEach(function (column) {
639 
640  output.push(column.getComponent());
641  });
642 
643  return output;
644 };
645 
646 ColumnManager.prototype.getWidth = function () {
647 
648  var width = 0;
649 
650  this.columnsByIndex.forEach(function (column) {
651 
652  if (column.visible) {
653 
654  width += column.getWidth();
655  }
656  });
657 
658  return width;
659 };
660 
661 ColumnManager.prototype.moveColumn = function (from, to, after) {
662 
663  this.moveColumnActual(from, to, after);
664 
665  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
666 
667  this.table.modules.responsiveLayout.initialize();
668  }
669 
670  if (this.table.modExists("columnCalcs")) {
671 
672  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
673  }
674 
675  to.element.parentNode.insertBefore(from.element, to.element);
676 
677  if (after) {
678 
679  to.element.parentNode.insertBefore(to.element, from.element);
680  }
681 
682  this._verticalAlignHeaders();
683 
684  this.table.rowManager.reinitialize();
685 };
686 
687 ColumnManager.prototype.moveColumnActual = function (from, to, after) {
688 
689  this._moveColumnInArray(this.columns, from, to, after);
690 
691  this._moveColumnInArray(this.columnsByIndex, from, to, after, true);
692 
693  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
694 
695  this.table.modules.responsiveLayout.initialize();
696  }
697 
698  if (this.table.options.columnMoved) {
699 
700  this.table.options.columnMoved.call(this.table, from.getComponent(), this.table.columnManager.getComponents());
701  }
702 
703  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
704 
705  this.table.modules.persistence.save("columns");
706  }
707 };
708 
709 ColumnManager.prototype._moveColumnInArray = function (columns, from, to, after, updateRows) {
710 
711  var fromIndex = columns.indexOf(from),
712  toIndex;
713 
714  if (fromIndex > -1) {
715 
716  columns.splice(fromIndex, 1);
717 
718  toIndex = columns.indexOf(to);
719 
720  if (toIndex > -1) {
721 
722  if (after) {
723 
724  toIndex = toIndex + 1;
725  }
726  } else {
727 
728  toIndex = fromIndex;
729  }
730 
731  columns.splice(toIndex, 0, from);
732 
733  if (updateRows) {
734 
735  this.table.rowManager.rows.forEach(function (row) {
736 
737  if (row.cells.length) {
738 
739  var cell = row.cells.splice(fromIndex, 1)[0];
740 
741  row.cells.splice(toIndex, 0, cell);
742  }
743  });
744  }
745  }
746 };
747 
748 ColumnManager.prototype.scrollToColumn = function (column, position, ifVisible) {
749  var _this2 = this;
750 
751  var left = 0,
752  offset = 0,
753  adjust = 0,
754  colEl = column.getElement();
755 
756  return new Promise(function (resolve, reject) {
757 
758  if (typeof position === "undefined") {
759 
760  position = _this2.table.options.scrollToColumnPosition;
761  }
762 
763  if (typeof ifVisible === "undefined") {
764 
765  ifVisible = _this2.table.options.scrollToColumnIfVisible;
766  }
767 
768  if (column.visible) {
769 
770  //align to correct position
771 
772  switch (position) {
773 
774  case "middle":
775 
776  case "center":
777 
778  adjust = -_this2.element.clientWidth / 2;
779 
780  break;
781 
782  case "right":
783 
784  adjust = colEl.clientWidth - _this2.headersElement.clientWidth;
785 
786  break;
787 
788  }
789 
790  //check column visibility
791 
792  if (!ifVisible) {
793 
794  offset = colEl.offsetLeft;
795 
796  if (offset > 0 && offset + colEl.offsetWidth < _this2.element.clientWidth) {
797 
798  return false;
799  }
800  }
801 
802  //calculate scroll position
803 
804  left = colEl.offsetLeft + _this2.element.scrollLeft + adjust;
805 
806  left = Math.max(Math.min(left, _this2.table.rowManager.element.scrollWidth - _this2.table.rowManager.element.clientWidth), 0);
807 
808  _this2.table.rowManager.scrollHorizontal(left);
809 
810  _this2.scrollHorizontal(left);
811 
812  resolve();
813  } else {
814 
815  console.warn("Scroll Error - Column not visible");
816 
817  reject("Scroll Error - Column not visible");
818  }
819  });
820 };
821 
823 
824 
825 ColumnManager.prototype.generateCells = function (row) {
826 
827  var self = this;
828 
829  var cells = [];
830 
831  self.columnsByIndex.forEach(function (column) {
832 
833  cells.push(column.generateCell(row));
834  });
835 
836  return cells;
837 };
838 
840 
841 
842 ColumnManager.prototype.getFlexBaseWidth = function () {
843 
844  var self = this,
845  totalWidth = self.table.element.clientWidth,
846  //table element width
847 
848  fixedWidth = 0;
849 
850  //adjust for vertical scrollbar if present
851 
852  if (self.rowManager.element.scrollHeight > self.rowManager.element.clientHeight) {
853 
854  totalWidth -= self.rowManager.element.offsetWidth - self.rowManager.element.clientWidth;
855  }
856 
857  this.columnsByIndex.forEach(function (column) {
858 
859  var width, minWidth, colWidth;
860 
861  if (column.visible) {
862 
863  width = column.definition.width || 0;
864 
865  minWidth = typeof column.minWidth == "undefined" ? self.table.options.columnMinWidth : parseInt(column.minWidth);
866 
867  if (typeof width == "string") {
868 
869  if (width.indexOf("%") > -1) {
870 
871  colWidth = totalWidth / 100 * parseInt(width);
872  } else {
873 
874  colWidth = parseInt(width);
875  }
876  } else {
877 
878  colWidth = width;
879  }
880 
881  fixedWidth += colWidth > minWidth ? colWidth : minWidth;
882  }
883  });
884 
885  return fixedWidth;
886 };
887 
888 ColumnManager.prototype.addColumn = function (definition, before, nextToColumn) {
889  var _this3 = this;
890 
891  return new Promise(function (resolve, reject) {
892 
893  var column = _this3._addColumn(definition, before, nextToColumn);
894 
895  _this3._reIndexColumns();
896 
897  if (_this3.table.options.responsiveLayout && _this3.table.modExists("responsiveLayout", true)) {
898 
899  _this3.table.modules.responsiveLayout.initialize();
900  }
901 
902  if (_this3.table.modExists("columnCalcs")) {
903 
904  _this3.table.modules.columnCalcs.recalc(_this3.table.rowManager.activeRows);
905  }
906 
907  _this3.redraw();
908 
909  if (_this3.table.modules.layout.getMode() != "fitColumns") {
910 
911  column.reinitializeWidth();
912  }
913 
914  _this3._verticalAlignHeaders();
915 
916  _this3.table.rowManager.reinitialize();
917 
918  resolve(column);
919  });
920 };
921 
922 //remove column from system
923 
924 ColumnManager.prototype.deregisterColumn = function (column) {
925 
926  var field = column.getField(),
927  index;
928 
929  //remove from field list
930 
931  if (field) {
932 
933  delete this.columnsByField[field];
934  }
935 
936  //remove from index list
937 
938  index = this.columnsByIndex.indexOf(column);
939 
940  if (index > -1) {
941 
942  this.columnsByIndex.splice(index, 1);
943  }
944 
945  //remove from column list
946 
947  index = this.columns.indexOf(column);
948 
949  if (index > -1) {
950 
951  this.columns.splice(index, 1);
952  }
953 
954  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
955 
956  this.table.modules.responsiveLayout.initialize();
957  }
958 
959  this.redraw();
960 };
961 
962 //redraw columns
963 
964 ColumnManager.prototype.redraw = function (force) {
965 
966  if (force) {
967 
968  if (Tabulator.prototype.helpers.elVisible(this.element)) {
969 
970  this._verticalAlignHeaders();
971  }
972 
973  this.table.rowManager.resetScroll();
974 
975  this.table.rowManager.reinitialize();
976  }
977 
978  if (["fitColumns", "fitDataStretch"].indexOf(this.table.modules.layout.getMode()) > -1) {
979 
980  this.table.modules.layout.layout();
981  } else {
982 
983  if (force) {
984 
985  this.table.modules.layout.layout();
986  } else {
987 
988  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
989 
990  this.table.modules.responsiveLayout.update();
991  }
992  }
993  }
994 
995  if (this.table.modExists("frozenColumns")) {
996 
997  this.table.modules.frozenColumns.layout();
998  }
999 
1000  if (this.table.modExists("columnCalcs")) {
1001 
1002  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
1003  }
1004 
1005  if (force) {
1006 
1007  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
1008 
1009  this.table.modules.persistence.save("columns");
1010  }
1011 
1012  if (this.table.modExists("columnCalcs")) {
1013 
1014  this.table.modules.columnCalcs.redraw();
1015  }
1016  }
1017 
1018  this.table.footerManager.redraw();
1019 };
1020 
1021 //public column object
1022 var ColumnComponent = function ColumnComponent(column) {
1023  this._column = column;
1024  this.type = "ColumnComponent";
1025 };
1026 
1027 ColumnComponent.prototype.getElement = function () {
1028  return this._column.getElement();
1029 };
1030 
1031 ColumnComponent.prototype.getDefinition = function () {
1032  return this._column.getDefinition();
1033 };
1034 
1035 ColumnComponent.prototype.getField = function () {
1036  return this._column.getField();
1037 };
1038 
1039 ColumnComponent.prototype.getCells = function () {
1040  var cells = [];
1041 
1042  this._column.cells.forEach(function (cell) {
1043  cells.push(cell.getComponent());
1044  });
1045 
1046  return cells;
1047 };
1048 
1049 ColumnComponent.prototype.getVisibility = function () {
1050  return this._column.visible;
1051 };
1052 
1053 ColumnComponent.prototype.show = function () {
1054  if (this._column.isGroup) {
1055  this._column.columns.forEach(function (column) {
1056  column.show();
1057  });
1058  } else {
1059  this._column.show();
1060  }
1061 };
1062 
1063 ColumnComponent.prototype.hide = function () {
1064  if (this._column.isGroup) {
1065  this._column.columns.forEach(function (column) {
1066  column.hide();
1067  });
1068  } else {
1069  this._column.hide();
1070  }
1071 };
1072 
1073 ColumnComponent.prototype.toggle = function () {
1074  if (this._column.visible) {
1075  this.hide();
1076  } else {
1077  this.show();
1078  }
1079 };
1080 
1081 ColumnComponent.prototype.delete = function () {
1082  return this._column.delete();
1083 };
1084 
1085 ColumnComponent.prototype.getSubColumns = function () {
1086  var output = [];
1087 
1088  if (this._column.columns.length) {
1089  this._column.columns.forEach(function (column) {
1090  output.push(column.getComponent());
1091  });
1092  }
1093 
1094  return output;
1095 };
1096 
1097 ColumnComponent.prototype.getParentColumn = function () {
1098  return this._column.parent instanceof Column ? this._column.parent.getComponent() : false;
1099 };
1100 
1101 ColumnComponent.prototype._getSelf = function () {
1102  return this._column;
1103 };
1104 
1105 ColumnComponent.prototype.scrollTo = function () {
1106  return this._column.table.columnManager.scrollToColumn(this._column);
1107 };
1108 
1109 ColumnComponent.prototype.getTable = function () {
1110  return this._column.table;
1111 };
1112 
1113 ColumnComponent.prototype.headerFilterFocus = function () {
1114  if (this._column.table.modExists("filter", true)) {
1115  this._column.table.modules.filter.setHeaderFilterFocus(this._column);
1116  }
1117 };
1118 
1119 ColumnComponent.prototype.reloadHeaderFilter = function () {
1120  if (this._column.table.modExists("filter", true)) {
1121  this._column.table.modules.filter.reloadHeaderFilter(this._column);
1122  }
1123 };
1124 
1125 ColumnComponent.prototype.setHeaderFilterValue = function (value) {
1126  if (this._column.table.modExists("filter", true)) {
1127  this._column.table.modules.filter.setHeaderFilterValue(this._column, value);
1128  }
1129 };
1130 
1131 ColumnComponent.prototype.move = function (to, after) {
1132  var toColumn = this._column.table.columnManager.findColumn(to);
1133 
1134  if (toColumn) {
1135  this._column.table.columnManager.moveColumn(this._column, toColumn, after);
1136  } else {
1137  console.warn("Move Error - No matching column found:", toColumn);
1138  }
1139 };
1140 
1141 ColumnComponent.prototype.getNextColumn = function () {
1142  var nextCol = this._column.nextColumn();
1143 
1144  return nextCol ? nextCol.getComponent() : false;
1145 };
1146 
1147 ColumnComponent.prototype.getPrevColumn = function () {
1148  var prevCol = this._column.prevColumn();
1149 
1150  return prevCol ? prevCol.getComponent() : false;
1151 };
1152 
1153 ColumnComponent.prototype.updateDefinition = function (updates) {
1154  return this._column.updateDefinition(updates);
1155 };
1156 
1157 var Column = function Column(def, parent) {
1158  var self = this;
1159 
1160  this.table = parent.table;
1161  this.definition = def; //column definition
1162  this.parent = parent; //hold parent object
1163  this.type = "column"; //type of element
1164  this.columns = []; //child columns
1165  this.cells = []; //cells bound to this column
1166  this.element = this.createElement(); //column header element
1167  this.contentElement = false;
1168  this.groupElement = this.createGroupElement(); //column group holder element
1169  this.isGroup = false;
1170  this.tooltip = false; //hold column tooltip
1171  this.hozAlign = ""; //horizontal text alignment
1172 
1173  //multi dimensional filed handling
1174  this.field = "";
1175  this.fieldStructure = "";
1176  this.getFieldValue = "";
1177  this.setFieldValue = "";
1178 
1179  this.titleFormatterRendered = false;
1180 
1181  this.setField(this.definition.field);
1182 
1183  if (this.table.options.invalidOptionWarnings) {
1184  this.checkDefinition();
1185  }
1186 
1187  this.modules = {}; //hold module variables;
1188 
1189  this.cellEvents = {
1190  cellClick: false,
1191  cellDblClick: false,
1192  cellContext: false,
1193  cellTap: false,
1194  cellDblTap: false,
1195  cellTapHold: false,
1196  cellMouseEnter: false,
1197  cellMouseLeave: false,
1198  cellMouseOver: false,
1199  cellMouseOut: false,
1200  cellMouseMove: false
1201  };
1202 
1203  this.width = null; //column width
1204  this.widthStyled = ""; //column width prestyled to improve render efficiency
1205  this.minWidth = null; //column minimum width
1206  this.minWidthStyled = ""; //column minimum prestyled to improve render efficiency
1207  this.widthFixed = false; //user has specified a width for this column
1208 
1209  this.visible = true; //default visible state
1210 
1211  this._mapDepricatedFunctionality();
1212 
1213  //initialize column
1214  if (def.columns) {
1215 
1216  this.isGroup = true;
1217 
1218  def.columns.forEach(function (def, i) {
1219  var newCol = new Column(def, self);
1220  self.attachColumn(newCol);
1221  });
1222 
1223  self.checkColumnVisibility();
1224  } else {
1225  parent.registerColumnField(this);
1226  }
1227 
1228  if (def.rowHandle && this.table.options.movableRows !== false && this.table.modExists("moveRow")) {
1229  this.table.modules.moveRow.setHandle(true);
1230  }
1231 
1232  this._buildHeader();
1233 
1234  this.bindModuleColumns();
1235 };
1236 
1237 Column.prototype.createElement = function () {
1238  var el = document.createElement("div");
1239 
1240  el.classList.add("tabulator-col");
1241  el.setAttribute("role", "columnheader");
1242  el.setAttribute("aria-sort", "none");
1243 
1244  return el;
1245 };
1246 
1247 Column.prototype.createGroupElement = function () {
1248  var el = document.createElement("div");
1249 
1250  el.classList.add("tabulator-col-group-cols");
1251 
1252  return el;
1253 };
1254 
1255 Column.prototype.checkDefinition = function () {
1256  var _this4 = this;
1257 
1258  Object.keys(this.definition).forEach(function (key) {
1259  if (_this4.defaultOptionList.indexOf(key) === -1) {
1260  console.warn("Invalid column definition option in '" + (_this4.field || _this4.definition.title) + "' column:", key);
1261  }
1262  });
1263 };
1264 
1265 Column.prototype.setField = function (field) {
1266  this.field = field;
1267  this.fieldStructure = field ? this.table.options.nestedFieldSeparator ? field.split(this.table.options.nestedFieldSeparator) : [field] : [];
1268  this.getFieldValue = this.fieldStructure.length > 1 ? this._getNestedData : this._getFlatData;
1269  this.setFieldValue = this.fieldStructure.length > 1 ? this._setNesteData : this._setFlatData;
1270 };
1271 
1272 //register column position with column manager
1273 Column.prototype.registerColumnPosition = function (column) {
1274  this.parent.registerColumnPosition(column);
1275 };
1276 
1277 //register column position with column manager
1278 Column.prototype.registerColumnField = function (column) {
1279  this.parent.registerColumnField(column);
1280 };
1281 
1282 //trigger position registration
1283 Column.prototype.reRegisterPosition = function () {
1284  if (this.isGroup) {
1285  this.columns.forEach(function (column) {
1286  column.reRegisterPosition();
1287  });
1288  } else {
1289  this.registerColumnPosition(this);
1290  }
1291 };
1292 
1293 Column.prototype._mapDepricatedFunctionality = function () {
1294  if (typeof this.definition.hideInHtml !== "undefined") {
1295  this.definition.htmlOutput = !this.definition.hideInHtml;
1296  console.warn("hideInHtml column definition property is deprecated, you should now use htmlOutput");
1297  }
1298 };
1299 
1300 Column.prototype.setTooltip = function () {
1301  var self = this,
1302  def = self.definition;
1303 
1304  //set header tooltips
1305  var tooltip = def.headerTooltip || def.tooltip === false ? def.headerTooltip : self.table.options.tooltipsHeader;
1306 
1307  if (tooltip) {
1308  if (tooltip === true) {
1309  if (def.field) {
1310  self.table.modules.localize.bind("columns|" + def.field, function (value) {
1311  self.element.setAttribute("title", value || def.title);
1312  });
1313  } else {
1314  self.element.setAttribute("title", def.title);
1315  }
1316  } else {
1317  if (typeof tooltip == "function") {
1318  tooltip = tooltip(self.getComponent());
1319 
1320  if (tooltip === false) {
1321  tooltip = "";
1322  }
1323  }
1324 
1325  self.element.setAttribute("title", tooltip);
1326  }
1327  } else {
1328  self.element.setAttribute("title", "");
1329  }
1330 };
1331 
1332 //build header element
1333 Column.prototype._buildHeader = function () {
1334  var self = this,
1335  def = self.definition;
1336 
1337  while (self.element.firstChild) {
1338  self.element.removeChild(self.element.firstChild);
1339  }if (def.headerVertical) {
1340  self.element.classList.add("tabulator-col-vertical");
1341 
1342  if (def.headerVertical === "flip") {
1343  self.element.classList.add("tabulator-col-vertical-flip");
1344  }
1345  }
1346 
1347  self.contentElement = self._bindEvents();
1348 
1349  self.contentElement = self._buildColumnHeaderContent();
1350 
1351  self.element.appendChild(self.contentElement);
1352 
1353  if (self.isGroup) {
1354  self._buildGroupHeader();
1355  } else {
1356  self._buildColumnHeader();
1357  }
1358 
1359  self.setTooltip();
1360 
1361  //set resizable handles
1362  if (self.table.options.resizableColumns && self.table.modExists("resizeColumns")) {
1363  self.table.modules.resizeColumns.initializeColumn("header", self, self.element);
1364  }
1365 
1366  //set resizable handles
1367  if (def.headerFilter && self.table.modExists("filter") && self.table.modExists("edit")) {
1368  if (typeof def.headerFilterPlaceholder !== "undefined" && def.field) {
1369  self.table.modules.localize.setHeaderFilterColumnPlaceholder(def.field, def.headerFilterPlaceholder);
1370  }
1371 
1372  self.table.modules.filter.initializeColumn(self);
1373  }
1374 
1375  //set resizable handles
1376  if (self.table.modExists("frozenColumns")) {
1377  self.table.modules.frozenColumns.initializeColumn(self);
1378  }
1379 
1380  //set movable column
1381  if (self.table.options.movableColumns && !self.isGroup && self.table.modExists("moveColumn")) {
1382  self.table.modules.moveColumn.initializeColumn(self);
1383  }
1384 
1385  //set calcs column
1386  if ((def.topCalc || def.bottomCalc) && self.table.modExists("columnCalcs")) {
1387  self.table.modules.columnCalcs.initializeColumn(self);
1388  }
1389 
1390  //handle persistence
1391  if (self.table.modExists("persistence") && self.table.modules.persistence.config.columns) {
1392  self.table.modules.persistence.initializeColumn(self);
1393  }
1394 
1395  //update header tooltip on mouse enter
1396  self.element.addEventListener("mouseenter", function (e) {
1397  self.setTooltip();
1398  });
1399 };
1400 
1401 Column.prototype._bindEvents = function () {
1402 
1403  var self = this,
1404  def = self.definition,
1405  dblTap,
1406  tapHold,
1407  tap;
1408 
1409  //setup header click event bindings
1410  if (typeof def.headerClick == "function") {
1411  self.element.addEventListener("click", function (e) {
1412  def.headerClick(e, self.getComponent());
1413  });
1414  }
1415 
1416  if (typeof def.headerDblClick == "function") {
1417  self.element.addEventListener("dblclick", function (e) {
1418  def.headerDblClick(e, self.getComponent());
1419  });
1420  }
1421 
1422  if (typeof def.headerContext == "function") {
1423  self.element.addEventListener("contextmenu", function (e) {
1424  def.headerContext(e, self.getComponent());
1425  });
1426  }
1427 
1428  //setup header tap event bindings
1429  if (typeof def.headerTap == "function") {
1430  tap = false;
1431 
1432  self.element.addEventListener("touchstart", function (e) {
1433  tap = true;
1434  }, { passive: true });
1435 
1436  self.element.addEventListener("touchend", function (e) {
1437  if (tap) {
1438  def.headerTap(e, self.getComponent());
1439  }
1440 
1441  tap = false;
1442  });
1443  }
1444 
1445  if (typeof def.headerDblTap == "function") {
1446  dblTap = null;
1447 
1448  self.element.addEventListener("touchend", function (e) {
1449 
1450  if (dblTap) {
1451  clearTimeout(dblTap);
1452  dblTap = null;
1453 
1454  def.headerDblTap(e, self.getComponent());
1455  } else {
1456 
1457  dblTap = setTimeout(function () {
1458  clearTimeout(dblTap);
1459  dblTap = null;
1460  }, 300);
1461  }
1462  });
1463  }
1464 
1465  if (typeof def.headerTapHold == "function") {
1466  tapHold = null;
1467 
1468  self.element.addEventListener("touchstart", function (e) {
1469  clearTimeout(tapHold);
1470 
1471  tapHold = setTimeout(function () {
1472  clearTimeout(tapHold);
1473  tapHold = null;
1474  tap = false;
1475  def.headerTapHold(e, self.getComponent());
1476  }, 1000);
1477  }, { passive: true });
1478 
1479  self.element.addEventListener("touchend", function (e) {
1480  clearTimeout(tapHold);
1481  tapHold = null;
1482  });
1483  }
1484 
1485  //store column cell click event bindings
1486  if (typeof def.cellClick == "function") {
1487  self.cellEvents.cellClick = def.cellClick;
1488  }
1489 
1490  if (typeof def.cellDblClick == "function") {
1491  self.cellEvents.cellDblClick = def.cellDblClick;
1492  }
1493 
1494  if (typeof def.cellContext == "function") {
1495  self.cellEvents.cellContext = def.cellContext;
1496  }
1497 
1498  //store column mouse event bindings
1499  if (typeof def.cellMouseEnter == "function") {
1500  self.cellEvents.cellMouseEnter = def.cellMouseEnter;
1501  }
1502 
1503  if (typeof def.cellMouseLeave == "function") {
1504  self.cellEvents.cellMouseLeave = def.cellMouseLeave;
1505  }
1506 
1507  if (typeof def.cellMouseOver == "function") {
1508  self.cellEvents.cellMouseOver = def.cellMouseOver;
1509  }
1510 
1511  if (typeof def.cellMouseOut == "function") {
1512  self.cellEvents.cellMouseOut = def.cellMouseOut;
1513  }
1514 
1515  if (typeof def.cellMouseMove == "function") {
1516  self.cellEvents.cellMouseMove = def.cellMouseMove;
1517  }
1518 
1519  //setup column cell tap event bindings
1520  if (typeof def.cellTap == "function") {
1521  self.cellEvents.cellTap = def.cellTap;
1522  }
1523 
1524  if (typeof def.cellDblTap == "function") {
1525  self.cellEvents.cellDblTap = def.cellDblTap;
1526  }
1527 
1528  if (typeof def.cellTapHold == "function") {
1529  self.cellEvents.cellTapHold = def.cellTapHold;
1530  }
1531 
1532  //setup column cell edit callbacks
1533  if (typeof def.cellEdited == "function") {
1534  self.cellEvents.cellEdited = def.cellEdited;
1535  }
1536 
1537  if (typeof def.cellEditing == "function") {
1538  self.cellEvents.cellEditing = def.cellEditing;
1539  }
1540 
1541  if (typeof def.cellEditCancelled == "function") {
1542  self.cellEvents.cellEditCancelled = def.cellEditCancelled;
1543  }
1544 };
1545 
1546 //build header element for header
1547 Column.prototype._buildColumnHeader = function () {
1548  var self = this,
1549  def = self.definition,
1550  table = self.table,
1551  sortable;
1552 
1553  //set column sorter
1554  if (table.modExists("sort")) {
1555  table.modules.sort.initializeColumn(self, self.contentElement);
1556  }
1557 
1558  //set column formatter
1559  if (table.modExists("format")) {
1560  table.modules.format.initializeColumn(self);
1561  }
1562 
1563  //set column editor
1564  if (typeof def.editor != "undefined" && table.modExists("edit")) {
1565  table.modules.edit.initializeColumn(self);
1566  }
1567 
1568  //set colum validator
1569  if (typeof def.validator != "undefined" && table.modExists("validate")) {
1570  table.modules.validate.initializeColumn(self);
1571  }
1572 
1573  //set column mutator
1574  if (table.modExists("mutator")) {
1575  table.modules.mutator.initializeColumn(self);
1576  }
1577 
1578  //set column accessor
1579  if (table.modExists("accessor")) {
1580  table.modules.accessor.initializeColumn(self);
1581  }
1582 
1583  //set respoviveLayout
1584  if (_typeof(table.options.responsiveLayout) && table.modExists("responsiveLayout")) {
1585  table.modules.responsiveLayout.initializeColumn(self);
1586  }
1587 
1588  //set column visibility
1589  if (typeof def.visible != "undefined") {
1590  if (def.visible) {
1591  self.show(true);
1592  } else {
1593  self.hide(true);
1594  }
1595  }
1596 
1597  //asign additional css classes to column header
1598  if (def.cssClass) {
1599  var classeNames = def.cssClass.split(" ");
1600  classeNames.forEach(function (className) {
1601  self.element.classList.add(className);
1602  });
1603  }
1604 
1605  if (def.field) {
1606  this.element.setAttribute("tabulator-field", def.field);
1607  }
1608 
1609  //set min width if present
1610  self.setMinWidth(typeof def.minWidth == "undefined" ? self.table.options.columnMinWidth : parseInt(def.minWidth));
1611 
1612  self.reinitializeWidth();
1613 
1614  //set tooltip if present
1615  self.tooltip = self.definition.tooltip || self.definition.tooltip === false ? self.definition.tooltip : self.table.options.tooltips;
1616 
1617  //set orizontal text alignment
1618  self.hozAlign = typeof self.definition.align == "undefined" ? "" : self.definition.align;
1619 };
1620 
1621 Column.prototype._buildColumnHeaderContent = function () {
1622  var self = this,
1623  def = self.definition,
1624  table = self.table;
1625 
1626  var contentElement = document.createElement("div");
1627  contentElement.classList.add("tabulator-col-content");
1628 
1629  contentElement.appendChild(self._buildColumnHeaderTitle());
1630 
1631  return contentElement;
1632 };
1633 
1634 //build title element of column
1635 Column.prototype._buildColumnHeaderTitle = function () {
1636  var self = this,
1637  def = self.definition,
1638  table = self.table,
1639  title;
1640 
1641  var titleHolderElement = document.createElement("div");
1642  titleHolderElement.classList.add("tabulator-col-title");
1643 
1644  if (def.editableTitle) {
1645  var titleElement = document.createElement("input");
1646  titleElement.classList.add("tabulator-title-editor");
1647 
1648  titleElement.addEventListener("click", function (e) {
1649  e.stopPropagation();
1650  titleElement.focus();
1651  });
1652 
1653  titleElement.addEventListener("change", function () {
1654  def.title = titleElement.value;
1655  table.options.columnTitleChanged.call(self.table, self.getComponent());
1656  });
1657 
1658  titleHolderElement.appendChild(titleElement);
1659 
1660  if (def.field) {
1661  table.modules.localize.bind("columns|" + def.field, function (text) {
1662  titleElement.value = text || def.title || "&nbsp;";
1663  });
1664  } else {
1665  titleElement.value = def.title || "&nbsp;";
1666  }
1667  } else {
1668  if (def.field) {
1669  table.modules.localize.bind("columns|" + def.field, function (text) {
1670  self._formatColumnHeaderTitle(titleHolderElement, text || def.title || "&nbsp;");
1671  });
1672  } else {
1673  self._formatColumnHeaderTitle(titleHolderElement, def.title || "&nbsp;");
1674  }
1675  }
1676 
1677  return titleHolderElement;
1678 };
1679 
1680 Column.prototype._formatColumnHeaderTitle = function (el, title) {
1681  var _this5 = this;
1682 
1683  var formatter, contents, params, mockCell, onRendered;
1684 
1685  if (this.definition.titleFormatter && this.table.modExists("format")) {
1686 
1687  formatter = this.table.modules.format.getFormatter(this.definition.titleFormatter);
1688 
1689  onRendered = function onRendered(callback) {
1690  _this5.titleFormatterRendered = callback;
1691  };
1692 
1693  mockCell = {
1694  getValue: function getValue() {
1695  return title;
1696  },
1697  getElement: function getElement() {
1698  return el;
1699  }
1700  };
1701 
1702  params = this.definition.titleFormatterParams || {};
1703 
1704  params = typeof params === "function" ? params() : params;
1705 
1706  contents = formatter.call(this.table.modules.format, mockCell, params, onRendered);
1707 
1708  switch (typeof contents === 'undefined' ? 'undefined' : _typeof(contents)) {
1709  case "object":
1710  if (contents instanceof Node) {
1711  el.appendChild(contents);
1712  } else {
1713  el.innerHTML = "";
1714  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);
1715  }
1716  break;
1717  case "undefined":
1718  case "null":
1719  el.innerHTML = "";
1720  break;
1721  default:
1722  el.innerHTML = contents;
1723  }
1724  } else {
1725  el.innerHTML = title;
1726  }
1727 };
1728 
1729 //build header element for column group
1730 Column.prototype._buildGroupHeader = function () {
1731  var _this6 = this;
1732 
1733  this.element.classList.add("tabulator-col-group");
1734  this.element.setAttribute("role", "columngroup");
1735  this.element.setAttribute("aria-title", this.definition.title);
1736 
1737  //asign additional css classes to column header
1738  if (this.definition.cssClass) {
1739  var classeNames = this.definition.cssClass.split(" ");
1740  classeNames.forEach(function (className) {
1741  _this6.element.classList.add(className);
1742  });
1743  }
1744 
1745  this.element.appendChild(this.groupElement);
1746 };
1747 
1748 //flat field lookup
1749 Column.prototype._getFlatData = function (data) {
1750  return data[this.field];
1751 };
1752 
1753 //nested field lookup
1754 Column.prototype._getNestedData = function (data) {
1755  var dataObj = data,
1756  structure = this.fieldStructure,
1757  length = structure.length,
1758  output;
1759 
1760  for (var i = 0; i < length; i++) {
1761 
1762  dataObj = dataObj[structure[i]];
1763 
1764  output = dataObj;
1765 
1766  if (!dataObj) {
1767  break;
1768  }
1769  }
1770 
1771  return output;
1772 };
1773 
1774 //flat field set
1775 Column.prototype._setFlatData = function (data, value) {
1776  if (this.field) {
1777  data[this.field] = value;
1778  }
1779 };
1780 
1781 //nested field set
1782 Column.prototype._setNesteData = function (data, value) {
1783  var dataObj = data,
1784  structure = this.fieldStructure,
1785  length = structure.length;
1786 
1787  for (var i = 0; i < length; i++) {
1788 
1789  if (i == length - 1) {
1790  dataObj[structure[i]] = value;
1791  } else {
1792  if (!dataObj[structure[i]]) {
1793  dataObj[structure[i]] = {};
1794  }
1795 
1796  dataObj = dataObj[structure[i]];
1797  }
1798  }
1799 };
1800 
1801 //attach column to this group
1802 Column.prototype.attachColumn = function (column) {
1803  var self = this;
1804 
1805  if (self.groupElement) {
1806  self.columns.push(column);
1807  self.groupElement.appendChild(column.getElement());
1808  } else {
1809  console.warn("Column Warning - Column being attached to another column instead of column group");
1810  }
1811 };
1812 
1813 //vertically align header in column
1814 Column.prototype.verticalAlign = function (alignment, height) {
1815 
1816  //calculate height of column header and group holder element
1817  var parentHeight = this.parent.isGroup ? this.parent.getGroupElement().clientHeight : height || this.parent.getHeadersElement().clientHeight;
1818  // var parentHeight = this.parent.isGroup ? this.parent.getGroupElement().clientHeight : this.parent.getHeadersElement().clientHeight;
1819 
1820  this.element.style.height = parentHeight + "px";
1821 
1822  if (this.isGroup) {
1823  this.groupElement.style.minHeight = parentHeight - this.contentElement.offsetHeight + "px";
1824  }
1825 
1826  //vertically align cell contents
1827  if (!this.isGroup && alignment !== "top") {
1828  if (alignment === "bottom") {
1829  this.element.style.paddingTop = this.element.clientHeight - this.contentElement.offsetHeight + "px";
1830  } else {
1831  this.element.style.paddingTop = (this.element.clientHeight - this.contentElement.offsetHeight) / 2 + "px";
1832  }
1833  }
1834 
1835  this.columns.forEach(function (column) {
1836  column.verticalAlign(alignment);
1837  });
1838 };
1839 
1840 //clear vertical alignmenet
1841 Column.prototype.clearVerticalAlign = function () {
1842  this.element.style.paddingTop = "";
1843  this.element.style.height = "";
1844  this.element.style.minHeight = "";
1845  this.groupElement.style.minHeight = "";
1846 
1847  this.columns.forEach(function (column) {
1848  column.clearVerticalAlign();
1849  });
1850 };
1851 
1852 Column.prototype.bindModuleColumns = function () {
1853  //check if rownum formatter is being used on a column
1854  if (this.definition.formatter == "rownum") {
1855  this.table.rowManager.rowNumColumn = this;
1856  }
1857 };
1858 
1860 
1861 //return column header element
1862 Column.prototype.getElement = function () {
1863  return this.element;
1864 };
1865 
1866 //return colunm group element
1867 Column.prototype.getGroupElement = function () {
1868  return this.groupElement;
1869 };
1870 
1871 //return field name
1872 Column.prototype.getField = function () {
1873  return this.field;
1874 };
1875 
1876 //return the first column in a group
1877 Column.prototype.getFirstColumn = function () {
1878  if (!this.isGroup) {
1879  return this;
1880  } else {
1881  if (this.columns.length) {
1882  return this.columns[0].getFirstColumn();
1883  } else {
1884  return false;
1885  }
1886  }
1887 };
1888 
1889 //return the last column in a group
1890 Column.prototype.getLastColumn = function () {
1891  if (!this.isGroup) {
1892  return this;
1893  } else {
1894  if (this.columns.length) {
1895  return this.columns[this.columns.length - 1].getLastColumn();
1896  } else {
1897  return false;
1898  }
1899  }
1900 };
1901 
1902 //return all columns in a group
1903 Column.prototype.getColumns = function () {
1904  return this.columns;
1905 };
1906 
1907 //return all columns in a group
1908 Column.prototype.getCells = function () {
1909  return this.cells;
1910 };
1911 
1912 //retreive the top column in a group of columns
1913 Column.prototype.getTopColumn = function () {
1914  if (this.parent.isGroup) {
1915  return this.parent.getTopColumn();
1916  } else {
1917  return this;
1918  }
1919 };
1920 
1921 //return column definition object
1922 Column.prototype.getDefinition = function (updateBranches) {
1923  var colDefs = [];
1924 
1925  if (this.isGroup && updateBranches) {
1926  this.columns.forEach(function (column) {
1927  colDefs.push(column.getDefinition(true));
1928  });
1929 
1930  this.definition.columns = colDefs;
1931  }
1932 
1933  return this.definition;
1934 };
1935 
1937 
1938 Column.prototype.checkColumnVisibility = function () {
1939  var visible = false;
1940 
1941  this.columns.forEach(function (column) {
1942  if (column.visible) {
1943  visible = true;
1944  }
1945  });
1946 
1947  if (visible) {
1948  this.show();
1949  this.parent.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), false);
1950  } else {
1951  this.hide();
1952  }
1953 };
1954 
1955 //show column
1956 Column.prototype.show = function (silent, responsiveToggle) {
1957  if (!this.visible) {
1958  this.visible = true;
1959 
1960  this.element.style.display = "";
1961 
1962  if (this.parent.isGroup) {
1963  this.parent.checkColumnVisibility();
1964  }
1965 
1966  this.cells.forEach(function (cell) {
1967  cell.show();
1968  });
1969 
1970  if (!this.isGroup && this.width === null) {
1971  this.reinitializeWidth();
1972  }
1973 
1974  this.table.columnManager._verticalAlignHeaders();
1975 
1976  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
1977  this.table.modules.persistence.save("columns");
1978  }
1979 
1980  if (!responsiveToggle && this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
1981  this.table.modules.responsiveLayout.updateColumnVisibility(this, this.visible);
1982  }
1983 
1984  if (!silent) {
1985  this.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), true);
1986  }
1987 
1988  if (this.parent.isGroup) {
1989  this.parent.matchChildWidths();
1990  }
1991  }
1992 };
1993 
1994 //hide column
1995 Column.prototype.hide = function (silent, responsiveToggle) {
1996  if (this.visible) {
1997  this.visible = false;
1998 
1999  this.element.style.display = "none";
2000 
2001  this.table.columnManager._verticalAlignHeaders();
2002 
2003  if (this.parent.isGroup) {
2004  this.parent.checkColumnVisibility();
2005  }
2006 
2007  this.cells.forEach(function (cell) {
2008  cell.hide();
2009  });
2010 
2011  if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) {
2012  this.table.modules.persistence.save("columns");
2013  }
2014 
2015  if (!responsiveToggle && this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
2016  this.table.modules.responsiveLayout.updateColumnVisibility(this, this.visible);
2017  }
2018 
2019  if (!silent) {
2020  this.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), false);
2021  }
2022 
2023  if (this.parent.isGroup) {
2024  this.parent.matchChildWidths();
2025  }
2026  }
2027 };
2028 
2029 Column.prototype.matchChildWidths = function () {
2030  var childWidth = 0;
2031 
2032  if (this.contentElement && this.columns.length) {
2033  this.columns.forEach(function (column) {
2034  if (column.visible) {
2035  childWidth += column.getWidth();
2036  }
2037  });
2038 
2039  this.contentElement.style.maxWidth = childWidth - 1 + "px";
2040  }
2041 };
2042 
2043 Column.prototype.setWidth = function (width) {
2044  this.widthFixed = true;
2045  this.setWidthActual(width);
2046 };
2047 
2048 Column.prototype.setWidthActual = function (width) {
2049  if (isNaN(width)) {
2050  width = Math.floor(this.table.element.clientWidth / 100 * parseInt(width));
2051  }
2052 
2053  width = Math.max(this.minWidth, width);
2054 
2055  this.width = width;
2056  this.widthStyled = width ? width + "px" : "";
2057 
2058  this.element.style.width = this.widthStyled;
2059 
2060  if (!this.isGroup) {
2061  this.cells.forEach(function (cell) {
2062  cell.setWidth();
2063  });
2064  }
2065 
2066  if (this.parent.isGroup) {
2067  this.parent.matchChildWidths();
2068  }
2069 
2070  //set resizable handles
2071  if (this.table.modExists("frozenColumns")) {
2072  this.table.modules.frozenColumns.layout();
2073  }
2074 };
2075 
2076 Column.prototype.checkCellHeights = function () {
2077  var rows = [];
2078 
2079  this.cells.forEach(function (cell) {
2080  if (cell.row.heightInitialized) {
2081  if (cell.row.getElement().offsetParent !== null) {
2082  rows.push(cell.row);
2083  cell.row.clearCellHeight();
2084  } else {
2085  cell.row.heightInitialized = false;
2086  }
2087  }
2088  });
2089 
2090  rows.forEach(function (row) {
2091  row.calcHeight();
2092  });
2093 
2094  rows.forEach(function (row) {
2095  row.setCellHeight();
2096  });
2097 };
2098 
2099 Column.prototype.getWidth = function () {
2100  // return this.element.offsetWidth;
2101  return this.width;
2102 };
2103 
2104 Column.prototype.getHeight = function () {
2105  return this.element.offsetHeight;
2106 };
2107 
2108 Column.prototype.setMinWidth = function (minWidth) {
2109  this.minWidth = minWidth;
2110  this.minWidthStyled = minWidth ? minWidth + "px" : "";
2111 
2112  this.element.style.minWidth = this.minWidthStyled;
2113 
2114  this.cells.forEach(function (cell) {
2115  cell.setMinWidth();
2116  });
2117 };
2118 
2119 Column.prototype.delete = function () {
2120  var _this7 = this;
2121 
2122  return new Promise(function (resolve, reject) {
2123 
2124  if (_this7.isGroup) {
2125  _this7.columns.forEach(function (column) {
2126  column.delete();
2127  });
2128  }
2129 
2130  var cellCount = _this7.cells.length;
2131 
2132  for (var i = 0; i < cellCount; i++) {
2133  _this7.cells[0].delete();
2134  }
2135 
2136  _this7.element.parentNode.removeChild(_this7.element);
2137 
2138  _this7.table.columnManager.deregisterColumn(_this7);
2139 
2140  resolve();
2141  });
2142 };
2143 
2144 Column.prototype.columnRendered = function () {
2145  if (this.titleFormatterRendered) {
2146  this.titleFormatterRendered();
2147  }
2148 };
2149 
2151 
2152 //generate cell for this column
2153 Column.prototype.generateCell = function (row) {
2154  var self = this;
2155 
2156  var cell = new Cell(self, row);
2157 
2158  this.cells.push(cell);
2159 
2160  return cell;
2161 };
2162 
2163 Column.prototype.nextColumn = function () {
2164  var index = this.table.columnManager.findColumnIndex(this);
2165  return index > -1 ? this._nextVisibleColumn(index + 1) : false;
2166 };
2167 
2168 Column.prototype._nextVisibleColumn = function (index) {
2169  var column = this.table.columnManager.getColumnByIndex(index);
2170  return !column || column.visible ? column : this._nextVisibleColumn(index + 1);
2171 };
2172 
2173 Column.prototype.prevColumn = function () {
2174  var index = this.table.columnManager.findColumnIndex(this);
2175  return index > -1 ? this._prevVisibleColumn(index - 1) : false;
2176 };
2177 
2178 Column.prototype._prevVisibleColumn = function (index) {
2179  var column = this.table.columnManager.getColumnByIndex(index);
2180  return !column || column.visible ? column : this._prevVisibleColumn(index - 1);
2181 };
2182 
2183 Column.prototype.reinitializeWidth = function (force) {
2184  this.widthFixed = false;
2185 
2186  //set width if present
2187  if (typeof this.definition.width !== "undefined" && !force) {
2188  this.setWidth(this.definition.width);
2189  }
2190 
2191  //hide header filters to prevent them altering column width
2192  if (this.table.modExists("filter")) {
2193  this.table.modules.filter.hideHeaderFilterElements();
2194  }
2195 
2196  this.fitToData();
2197 
2198  //show header filters again after layout is complete
2199  if (this.table.modExists("filter")) {
2200  this.table.modules.filter.showHeaderFilterElements();
2201  }
2202 };
2203 
2204 //set column width to maximum cell width
2205 Column.prototype.fitToData = function () {
2206  var self = this;
2207 
2208  if (!this.widthFixed) {
2209  this.element.style.width = "";
2210 
2211  self.cells.forEach(function (cell) {
2212  cell.clearWidth();
2213  });
2214  }
2215 
2216  var maxWidth = this.element.offsetWidth;
2217 
2218  if (!self.width || !this.widthFixed) {
2219  self.cells.forEach(function (cell) {
2220  var width = cell.getWidth();
2221 
2222  if (width > maxWidth) {
2223  maxWidth = width;
2224  }
2225  });
2226 
2227  if (maxWidth) {
2228  self.setWidthActual(maxWidth + 1);
2229  }
2230  }
2231 };
2232 
2233 Column.prototype.updateDefinition = function (updates) {
2234  var _this8 = this;
2235 
2236  return new Promise(function (resolve, reject) {
2237  var definition;
2238 
2239  if (!_this8.isGroup) {
2240  definition = Object.assign({}, _this8.getDefinition());
2241  definition = Object.assign(definition, updates);
2242 
2243  _this8.table.columnManager.addColumn(definition, false, _this8).then(function (column) {
2244 
2245  if (definition.field == _this8.field) {
2246  _this8.field = false; //cleair field name to prevent deletion of duplicate column from arrays
2247  }
2248 
2249  _this8.delete().then(function () {
2250  resolve(column.getComponent());
2251  }).catch(function (err) {
2252  reject(err);
2253  });
2254  }).catch(function (err) {
2255  reject(err);
2256  });
2257  } else {
2258  console.warn("Column Update Error - The updateDefintion function is only available on columns, not column groups");
2259  reject("Column Update Error - The updateDefintion function is only available on columns, not column groups");
2260  }
2261  });
2262 };
2263 
2264 Column.prototype.deleteCell = function (cell) {
2265  var index = this.cells.indexOf(cell);
2266 
2267  if (index > -1) {
2268  this.cells.splice(index, 1);
2269  }
2270 };
2271 
2272 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"];
2273 
2275 
2277 Column.prototype.getComponent = function () {
2278  return new ColumnComponent(this);
2279 };
2280 
2281 var RowManager = function RowManager(table) {
2282 
2283  this.table = table;
2284  this.element = this.createHolderElement(); //containing element
2285  this.tableElement = this.createTableElement(); //table element
2286  this.columnManager = null; //hold column manager object
2287  this.height = 0; //hold height of table element
2288 
2289  this.firstRender = false; //handle first render
2290  this.renderMode = "classic"; //current rendering mode
2291 
2292  this.rows = []; //hold row data objects
2293  this.activeRows = []; //rows currently available to on display in the table
2294  this.activeRowsCount = 0; //count of active rows
2295 
2296  this.displayRows = []; //rows currently on display in the table
2297  this.displayRowsCount = 0; //count of display rows
2298 
2299  this.scrollTop = 0;
2300  this.scrollLeft = 0;
2301 
2302  this.vDomRowHeight = 20; //approximation of row heights for padding
2303 
2304  this.vDomTop = 0; //hold position for first rendered row in the virtual DOM
2305  this.vDomBottom = 0; //hold possition for last rendered row in the virtual DOM
2306 
2307  this.vDomScrollPosTop = 0; //last scroll position of the vDom top;
2308  this.vDomScrollPosBottom = 0; //last scroll position of the vDom bottom;
2309 
2310  this.vDomTopPad = 0; //hold value of padding for top of virtual DOM
2311  this.vDomBottomPad = 0; //hold value of padding for bottom of virtual DOM
2312 
2313  this.vDomMaxRenderChain = 90; //the maximum number of dom elements that can be rendered in 1 go
2314 
2315  this.vDomWindowBuffer = 0; //window row buffer before removing elements, to smooth scrolling
2316 
2317  this.vDomWindowMinTotalRows = 20; //minimum number of rows to be generated in virtual dom (prevent buffering issues on tables with tall rows)
2318  this.vDomWindowMinMarginRows = 5; //minimum number of rows to be generated in virtual dom margin
2319 
2320  this.vDomTopNewRows = []; //rows to normalize after appending to optimize render speed
2321  this.vDomBottomNewRows = []; //rows to normalize after appending to optimize render speed
2322 
2323  this.rowNumColumn = false; //hold column component for row number column
2324 
2325  this.redrawBlock = false; //prevent redraws to allow multiple data manipulations becore continuing
2326  this.redrawBlockRestoreConfig = false; //store latest redraw function calls for when redraw is needed
2327  this.redrawBlockRederInPosition = false; //store latest redraw function calls for when redraw is needed
2328 };
2329 
2331 
2332 RowManager.prototype.createHolderElement = function () {
2333  var el = document.createElement("div");
2334 
2335  el.classList.add("tabulator-tableHolder");
2336  el.setAttribute("tabindex", 0);
2337 
2338  return el;
2339 };
2340 
2341 RowManager.prototype.createTableElement = function () {
2342  var el = document.createElement("div");
2343 
2344  el.classList.add("tabulator-table");
2345 
2346  return el;
2347 };
2348 
2349 //return containing element
2350 RowManager.prototype.getElement = function () {
2351  return this.element;
2352 };
2353 
2354 //return table element
2355 RowManager.prototype.getTableElement = function () {
2356  return this.tableElement;
2357 };
2358 
2359 //return position of row in table
2360 RowManager.prototype.getRowPosition = function (row, active) {
2361  if (active) {
2362  return this.activeRows.indexOf(row);
2363  } else {
2364  return this.rows.indexOf(row);
2365  }
2366 };
2367 
2368 //link to column manager
2369 RowManager.prototype.setColumnManager = function (manager) {
2370  this.columnManager = manager;
2371 };
2372 
2373 RowManager.prototype.initialize = function () {
2374  var self = this;
2375 
2376  self.setRenderMode();
2377 
2378  //initialize manager
2379  self.element.appendChild(self.tableElement);
2380 
2381  self.firstRender = true;
2382 
2383  //scroll header along with table body
2384  self.element.addEventListener("scroll", function () {
2385  var left = self.element.scrollLeft;
2386 
2387  //handle horizontal scrolling
2388  if (self.scrollLeft != left) {
2389  self.columnManager.scrollHorizontal(left);
2390 
2391  if (self.table.options.groupBy) {
2392  self.table.modules.groupRows.scrollHeaders(left);
2393  }
2394 
2395  if (self.table.modExists("columnCalcs")) {
2396  self.table.modules.columnCalcs.scrollHorizontal(left);
2397  }
2398 
2399  self.table.options.scrollHorizontal(left);
2400  }
2401 
2402  self.scrollLeft = left;
2403  });
2404 
2405  //handle virtual dom scrolling
2406  if (this.renderMode === "virtual") {
2407 
2408  self.element.addEventListener("scroll", function () {
2409  var top = self.element.scrollTop;
2410  var dir = self.scrollTop > top;
2411 
2412  //handle verical scrolling
2413  if (self.scrollTop != top) {
2414  self.scrollTop = top;
2415  self.scrollVertical(dir);
2416 
2417  if (self.table.options.ajaxProgressiveLoad == "scroll") {
2418  self.table.modules.ajax.nextPage(self.element.scrollHeight - self.element.clientHeight - top);
2419  }
2420 
2421  self.table.options.scrollVertical(top);
2422  } else {
2423  self.scrollTop = top;
2424  }
2425  });
2426  }
2427 };
2428 
2430 
2431 RowManager.prototype.findRow = function (subject) {
2432  var self = this;
2433 
2434  if ((typeof subject === 'undefined' ? 'undefined' : _typeof(subject)) == "object") {
2435 
2436  if (subject instanceof Row) {
2437  //subject is row element
2438  return subject;
2439  } else if (subject instanceof RowComponent) {
2440  //subject is public row component
2441  return subject._getSelf() || false;
2442  } else if (typeof HTMLElement !== "undefined" && subject instanceof HTMLElement) {
2443  //subject is a HTML element of the row
2444  var match = self.rows.find(function (row) {
2445  return row.element === subject;
2446  });
2447 
2448  return match || false;
2449  }
2450  } else if (typeof subject == "undefined" || subject === null) {
2451  return false;
2452  } else {
2453  //subject should be treated as the index of the row
2454  var _match = self.rows.find(function (row) {
2455  return row.data[self.table.options.index] == subject;
2456  });
2457 
2458  return _match || false;
2459  }
2460 
2461  //catch all for any other type of input
2462 
2463  return false;
2464 };
2465 
2466 RowManager.prototype.getRowFromDataObject = function (data) {
2467  var match = this.rows.find(function (row) {
2468  return row.data === data;
2469  });
2470 
2471  return match || false;
2472 };
2473 
2474 RowManager.prototype.getRowFromPosition = function (position, active) {
2475  if (active) {
2476  return this.activeRows[position];
2477  } else {
2478  return this.rows[position];
2479  }
2480 };
2481 
2482 RowManager.prototype.scrollToRow = function (row, position, ifVisible) {
2483  var _this9 = this;
2484 
2485  var rowIndex = this.getDisplayRows().indexOf(row),
2486  rowEl = row.getElement(),
2487  rowTop,
2488  offset = 0;
2489 
2490  return new Promise(function (resolve, reject) {
2491  if (rowIndex > -1) {
2492 
2493  if (typeof position === "undefined") {
2494  position = _this9.table.options.scrollToRowPosition;
2495  }
2496 
2497  if (typeof ifVisible === "undefined") {
2498  ifVisible = _this9.table.options.scrollToRowIfVisible;
2499  }
2500 
2501  if (position === "nearest") {
2502  switch (_this9.renderMode) {
2503  case "classic":
2504  rowTop = Tabulator.prototype.helpers.elOffset(rowEl).top;
2505  position = Math.abs(_this9.element.scrollTop - rowTop) > Math.abs(_this9.element.scrollTop + _this9.element.clientHeight - rowTop) ? "bottom" : "top";
2506  break;
2507  case "virtual":
2508  position = Math.abs(_this9.vDomTop - rowIndex) > Math.abs(_this9.vDomBottom - rowIndex) ? "bottom" : "top";
2509  break;
2510  }
2511  }
2512 
2513  //check row visibility
2514  if (!ifVisible) {
2515  if (Tabulator.prototype.helpers.elVisible(rowEl)) {
2516  offset = Tabulator.prototype.helpers.elOffset(rowEl).top - Tabulator.prototype.helpers.elOffset(_this9.element).top;
2517 
2518  if (offset > 0 && offset < _this9.element.clientHeight - rowEl.offsetHeight) {
2519  return false;
2520  }
2521  }
2522  }
2523 
2524  //scroll to row
2525  switch (_this9.renderMode) {
2526  case "classic":
2527  _this9.element.scrollTop = Tabulator.prototype.helpers.elOffset(rowEl).top - Tabulator.prototype.helpers.elOffset(_this9.element).top + _this9.element.scrollTop;
2528  break;
2529  case "virtual":
2530  _this9._virtualRenderFill(rowIndex, true);
2531  break;
2532  }
2533 
2534  //align to correct position
2535  switch (position) {
2536  case "middle":
2537  case "center":
2538 
2539  if (_this9.element.scrollHeight - _this9.element.scrollTop == _this9.element.clientHeight) {
2540  _this9.element.scrollTop = _this9.element.scrollTop + (rowEl.offsetTop - _this9.element.scrollTop) - (_this9.element.scrollHeight - rowEl.offsetTop) / 2;
2541  } else {
2542  _this9.element.scrollTop = _this9.element.scrollTop - _this9.element.clientHeight / 2;
2543  }
2544 
2545  break;
2546 
2547  case "bottom":
2548 
2549  if (_this9.element.scrollHeight - _this9.element.scrollTop == _this9.element.clientHeight) {
2550  _this9.element.scrollTop = _this9.element.scrollTop - (_this9.element.scrollHeight - rowEl.offsetTop) + rowEl.offsetHeight;
2551  } else {
2552  _this9.element.scrollTop = _this9.element.scrollTop - _this9.element.clientHeight + rowEl.offsetHeight;
2553  }
2554 
2555  break;
2556  }
2557 
2558  resolve();
2559  } else {
2560  console.warn("Scroll Error - Row not visible");
2561  reject("Scroll Error - Row not visible");
2562  }
2563  });
2564 };
2565 
2567 
2568 RowManager.prototype.setData = function (data, renderInPosition) {
2569  var _this10 = this;
2570 
2571  var self = this;
2572 
2573  return new Promise(function (resolve, reject) {
2574  if (renderInPosition && _this10.getDisplayRows().length) {
2575  if (self.table.options.pagination) {
2576  self._setDataActual(data, true);
2577  } else {
2578  _this10.reRenderInPosition(function () {
2579  self._setDataActual(data);
2580  });
2581  }
2582  } else {
2583  if (_this10.table.options.autoColumns) {
2584  _this10.table.columnManager.generateColumnsFromRowData(data);
2585  }
2586  _this10.resetScroll();
2587  _this10._setDataActual(data);
2588  }
2589 
2590  resolve();
2591  });
2592 };
2593 
2594 RowManager.prototype._setDataActual = function (data, renderInPosition) {
2595  var self = this;
2596 
2597  self.table.options.dataLoading.call(this.table, data);
2598 
2599  this._wipeElements();
2600 
2601  if (this.table.options.history && this.table.modExists("history")) {
2602  this.table.modules.history.clear();
2603  }
2604 
2605  if (Array.isArray(data)) {
2606 
2607  if (this.table.modExists("selectRow")) {
2608  this.table.modules.selectRow.clearSelectionData();
2609  }
2610 
2611  if (this.table.options.reactiveData && this.table.modExists("reactiveData", true)) {
2612  this.table.modules.reactiveData.watchData(data);
2613  }
2614 
2615  data.forEach(function (def, i) {
2616  if (def && (typeof def === 'undefined' ? 'undefined' : _typeof(def)) === "object") {
2617  var row = new Row(def, self);
2618  self.rows.push(row);
2619  } else {
2620  console.warn("Data Loading Warning - Invalid row data detected and ignored, expecting object but received:", def);
2621  }
2622  });
2623 
2624  self.table.options.dataLoaded.call(this.table, data);
2625 
2626  self.refreshActiveData(false, false, renderInPosition);
2627  } else {
2628  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);
2629  }
2630 };
2631 
2632 RowManager.prototype._wipeElements = function () {
2633  this.rows.forEach(function (row) {
2634  row.wipe();
2635  });
2636 
2637  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
2638  this.table.modules.groupRows.wipe();
2639  }
2640 
2641  this.rows = [];
2642 };
2643 
2644 RowManager.prototype.deleteRow = function (row, blockRedraw) {
2645  var allIndex = this.rows.indexOf(row),
2646  activeIndex = this.activeRows.indexOf(row);
2647 
2648  if (activeIndex > -1) {
2649  this.activeRows.splice(activeIndex, 1);
2650  }
2651 
2652  if (allIndex > -1) {
2653  this.rows.splice(allIndex, 1);
2654  }
2655 
2656  this.setActiveRows(this.activeRows);
2657 
2658  this.displayRowIterator(function (rows) {
2659  var displayIndex = rows.indexOf(row);
2660 
2661  if (displayIndex > -1) {
2662  rows.splice(displayIndex, 1);
2663  }
2664  });
2665 
2666  if (!blockRedraw) {
2667  this.reRenderInPosition();
2668  }
2669 
2670  this.table.options.rowDeleted.call(this.table, row.getComponent());
2671 
2672  this.table.options.dataEdited.call(this.table, this.getData());
2673 
2674  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
2675  this.table.modules.groupRows.updateGroupRows(true);
2676  } else if (this.table.options.pagination && this.table.modExists("page")) {
2677  this.refreshActiveData(false, false, true);
2678  } else {
2679  if (this.table.options.pagination && this.table.modExists("page")) {
2680  this.refreshActiveData("page");
2681  }
2682  }
2683 };
2684 
2685 RowManager.prototype.addRow = function (data, pos, index, blockRedraw) {
2686 
2687  var row = this.addRowActual(data, pos, index, blockRedraw);
2688 
2689  if (this.table.options.history && this.table.modExists("history")) {
2690  this.table.modules.history.action("rowAdd", row, { data: data, pos: pos, index: index });
2691  }
2692 
2693  return row;
2694 };
2695 
2696 //add multiple rows
2697 RowManager.prototype.addRows = function (data, pos, index) {
2698  var _this11 = this;
2699 
2700  var self = this,
2701  length = 0,
2702  rows = [];
2703 
2704  return new Promise(function (resolve, reject) {
2705  pos = _this11.findAddRowPos(pos);
2706 
2707  if (!Array.isArray(data)) {
2708  data = [data];
2709  }
2710 
2711  length = data.length - 1;
2712 
2713  if (typeof index == "undefined" && pos || typeof index !== "undefined" && !pos) {
2714  data.reverse();
2715  }
2716 
2717  data.forEach(function (item, i) {
2718  var row = self.addRow(item, pos, index, true);
2719  rows.push(row);
2720  });
2721 
2722  if (_this11.table.options.groupBy && _this11.table.modExists("groupRows")) {
2723  _this11.table.modules.groupRows.updateGroupRows(true);
2724  } else if (_this11.table.options.pagination && _this11.table.modExists("page")) {
2725  _this11.refreshActiveData(false, false, true);
2726  } else {
2727  _this11.reRenderInPosition();
2728  }
2729 
2730  //recalc column calculations if present
2731  if (_this11.table.modExists("columnCalcs")) {
2732  _this11.table.modules.columnCalcs.recalc(_this11.table.rowManager.activeRows);
2733  }
2734 
2735  resolve(rows);
2736  });
2737 };
2738 
2739 RowManager.prototype.findAddRowPos = function (pos) {
2740  if (typeof pos === "undefined") {
2741  pos = this.table.options.addRowPos;
2742  }
2743 
2744  if (pos === "pos") {
2745  pos = true;
2746  }
2747 
2748  if (pos === "bottom") {
2749  pos = false;
2750  }
2751 
2752  return pos;
2753 };
2754 
2755 RowManager.prototype.addRowActual = function (data, pos, index, blockRedraw) {
2756  var row = data instanceof Row ? data : new Row(data || {}, this),
2757  top = this.findAddRowPos(pos),
2758  dispRows;
2759 
2760  if (!index && this.table.options.pagination && this.table.options.paginationAddRow == "page") {
2761  dispRows = this.getDisplayRows();
2762 
2763  if (top) {
2764  if (dispRows.length) {
2765  index = dispRows[0];
2766  } else {
2767  if (this.activeRows.length) {
2768  index = this.activeRows[this.activeRows.length - 1];
2769  top = false;
2770  }
2771  }
2772  } else {
2773  if (dispRows.length) {
2774  index = dispRows[dispRows.length - 1];
2775  top = dispRows.length < this.table.modules.page.getPageSize() ? false : true;
2776  }
2777  }
2778  }
2779 
2780  if (index) {
2781  index = this.findRow(index);
2782  }
2783 
2784  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
2785  this.table.modules.groupRows.assignRowToGroup(row);
2786 
2787  var groupRows = row.getGroup().rows;
2788 
2789  if (groupRows.length > 1) {
2790 
2791  if (!index || index && groupRows.indexOf(index) == -1) {
2792  if (top) {
2793  if (groupRows[0] !== row) {
2794  index = groupRows[0];
2795  this._moveRowInArray(row.getGroup().rows, row, index, !top);
2796  }
2797  } else {
2798  if (groupRows[groupRows.length - 1] !== row) {
2799  index = groupRows[groupRows.length - 1];
2800  this._moveRowInArray(row.getGroup().rows, row, index, !top);
2801  }
2802  }
2803  } else {
2804  this._moveRowInArray(row.getGroup().rows, row, index, !top);
2805  }
2806  }
2807  }
2808 
2809  if (index) {
2810  var allIndex = this.rows.indexOf(index),
2811  activeIndex = this.activeRows.indexOf(index);
2812 
2813  this.displayRowIterator(function (rows) {
2814  var displayIndex = rows.indexOf(index);
2815 
2816  if (displayIndex > -1) {
2817  rows.splice(top ? displayIndex : displayIndex + 1, 0, row);
2818  }
2819  });
2820 
2821  if (activeIndex > -1) {
2822  this.activeRows.splice(top ? activeIndex : activeIndex + 1, 0, row);
2823  }
2824 
2825  if (allIndex > -1) {
2826  this.rows.splice(top ? allIndex : allIndex + 1, 0, row);
2827  }
2828  } else {
2829 
2830  if (top) {
2831 
2832  this.displayRowIterator(function (rows) {
2833  rows.unshift(row);
2834  });
2835 
2836  this.activeRows.unshift(row);
2837  this.rows.unshift(row);
2838  } else {
2839  this.displayRowIterator(function (rows) {
2840  rows.push(row);
2841  });
2842 
2843  this.activeRows.push(row);
2844  this.rows.push(row);
2845  }
2846  }
2847 
2848  this.setActiveRows(this.activeRows);
2849 
2850  this.table.options.rowAdded.call(this.table, row.getComponent());
2851 
2852  this.table.options.dataEdited.call(this.table, this.getData());
2853 
2854  if (!blockRedraw) {
2855  this.reRenderInPosition();
2856  }
2857 
2858  return row;
2859 };
2860 
2861 RowManager.prototype.moveRow = function (from, to, after) {
2862  if (this.table.options.history && this.table.modExists("history")) {
2863  this.table.modules.history.action("rowMove", from, { pos: this.getRowPosition(from), to: to, after: after });
2864  }
2865 
2866  this.moveRowActual(from, to, after);
2867 
2868  this.table.options.rowMoved.call(this.table, from.getComponent());
2869 };
2870 
2871 RowManager.prototype.moveRowActual = function (from, to, after) {
2872  var self = this;
2873  this._moveRowInArray(this.rows, from, to, after);
2874  this._moveRowInArray(this.activeRows, from, to, after);
2875 
2876  this.displayRowIterator(function (rows) {
2877  self._moveRowInArray(rows, from, to, after);
2878  });
2879 
2880  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
2881  var toGroup = to.getGroup();
2882  var fromGroup = from.getGroup();
2883 
2884  if (toGroup === fromGroup) {
2885  this._moveRowInArray(toGroup.rows, from, to, after);
2886  } else {
2887  if (fromGroup) {
2888  fromGroup.removeRow(from);
2889  }
2890 
2891  toGroup.insertRow(from, to, after);
2892  }
2893  }
2894 };
2895 
2896 RowManager.prototype._moveRowInArray = function (rows, from, to, after) {
2897  var fromIndex, toIndex, start, end;
2898 
2899  if (from !== to) {
2900 
2901  fromIndex = rows.indexOf(from);
2902 
2903  if (fromIndex > -1) {
2904 
2905  rows.splice(fromIndex, 1);
2906 
2907  toIndex = rows.indexOf(to);
2908 
2909  if (toIndex > -1) {
2910 
2911  if (after) {
2912  rows.splice(toIndex + 1, 0, from);
2913  } else {
2914  rows.splice(toIndex, 0, from);
2915  }
2916  } else {
2917  rows.splice(fromIndex, 0, from);
2918  }
2919  }
2920 
2921  //restyle rows
2922  if (rows === this.getDisplayRows()) {
2923 
2924  start = fromIndex < toIndex ? fromIndex : toIndex;
2925  end = toIndex > fromIndex ? toIndex : fromIndex + 1;
2926 
2927  for (var i = start; i <= end; i++) {
2928  if (rows[i]) {
2929  this.styleRow(rows[i], i);
2930  }
2931  }
2932  }
2933  }
2934 };
2935 
2936 RowManager.prototype.clearData = function () {
2937  this.setData([]);
2938 };
2939 
2940 RowManager.prototype.getRowIndex = function (row) {
2941  return this.findRowIndex(row, this.rows);
2942 };
2943 
2944 RowManager.prototype.getDisplayRowIndex = function (row) {
2945  var index = this.getDisplayRows().indexOf(row);
2946  return index > -1 ? index : false;
2947 };
2948 
2949 RowManager.prototype.nextDisplayRow = function (row, rowOnly) {
2950  var index = this.getDisplayRowIndex(row),
2951  nextRow = false;
2952 
2953  if (index !== false && index < this.displayRowsCount - 1) {
2954  nextRow = this.getDisplayRows()[index + 1];
2955  }
2956 
2957  if (nextRow && (!(nextRow instanceof Row) || nextRow.type != "row")) {
2958  return this.nextDisplayRow(nextRow, rowOnly);
2959  }
2960 
2961  return nextRow;
2962 };
2963 
2964 RowManager.prototype.prevDisplayRow = function (row, rowOnly) {
2965  var index = this.getDisplayRowIndex(row),
2966  prevRow = false;
2967 
2968  if (index) {
2969  prevRow = this.getDisplayRows()[index - 1];
2970  }
2971 
2972  if (prevRow && (!(prevRow instanceof Row) || prevRow.type != "row")) {
2973  return this.prevDisplayRow(prevRow, rowOnly);
2974  }
2975 
2976  return prevRow;
2977 };
2978 
2979 RowManager.prototype.findRowIndex = function (row, list) {
2980  var rowIndex;
2981 
2982  row = this.findRow(row);
2983 
2984  if (row) {
2985  rowIndex = list.indexOf(row);
2986 
2987  if (rowIndex > -1) {
2988  return rowIndex;
2989  }
2990  }
2991 
2992  return false;
2993 };
2994 
2995 RowManager.prototype.getData = function (active, transform) {
2996  var output = [],
2997  rows = this.getRows(active);
2998 
2999  rows.forEach(function (row) {
3000  output.push(row.getData(transform || "data"));
3001  });
3002 
3003  return output;
3004 };
3005 
3006 RowManager.prototype.getComponents = function (active) {
3007  var output = [],
3008  rows = this.getRows(active);
3009 
3010  rows.forEach(function (row) {
3011  output.push(row.getComponent());
3012  });
3013 
3014  return output;
3015 };
3016 
3017 RowManager.prototype.getDataCount = function (active) {
3018  var rows = this.getRows(active);
3019 
3020  return rows.length;
3021 };
3022 
3023 RowManager.prototype._genRemoteRequest = function () {
3024  var self = this,
3025  table = self.table,
3026  options = table.options,
3027  params = {};
3028 
3029  if (table.modExists("page")) {
3030  //set sort data if defined
3031  if (options.ajaxSorting) {
3032  var sorters = self.table.modules.sort.getSort();
3033 
3034  sorters.forEach(function (item) {
3035  delete item.column;
3036  });
3037 
3038  params[self.table.modules.page.paginationDataSentNames.sorters] = sorters;
3039  }
3040 
3041  //set filter data if defined
3042  if (options.ajaxFiltering) {
3043  var filters = self.table.modules.filter.getFilters(true, true);
3044 
3045  params[self.table.modules.page.paginationDataSentNames.filters] = filters;
3046  }
3047 
3048  self.table.modules.ajax.setParams(params, true);
3049  }
3050 
3051  table.modules.ajax.sendRequest().then(function (data) {
3052  self.setData(data);
3053  }).catch(function (e) {});
3054 };
3055 
3056 //choose the path to refresh data after a filter update
3057 RowManager.prototype.filterRefresh = function () {
3058  var table = this.table,
3059  options = table.options,
3060  left = this.scrollLeft;
3061 
3062  if (options.ajaxFiltering) {
3063  if (options.pagination == "remote" && table.modExists("page")) {
3064  table.modules.page.reset(true);
3065  table.modules.page.setPage(1).then(function () {}).catch(function () {});
3066  } else if (options.ajaxProgressiveLoad) {
3067  table.modules.ajax.loadData().then(function () {}).catch(function () {});
3068  } else {
3069  //assume data is url, make ajax call to url to get data
3070  this._genRemoteRequest();
3071  }
3072  } else {
3073  this.refreshActiveData("filter");
3074  }
3075 
3076  this.scrollHorizontal(left);
3077 };
3078 
3079 //choose the path to refresh data after a sorter update
3080 RowManager.prototype.sorterRefresh = function (loadOrignalData) {
3081  var table = this.table,
3082  options = this.table.options,
3083  left = this.scrollLeft;
3084 
3085  if (options.ajaxSorting) {
3086  if ((options.pagination == "remote" || options.progressiveLoad) && table.modExists("page")) {
3087  table.modules.page.reset(true);
3088  table.modules.page.setPage(1).then(function () {}).catch(function () {});
3089  } else if (options.ajaxProgressiveLoad) {
3090  table.modules.ajax.loadData().then(function () {}).catch(function () {});
3091  } else {
3092  //assume data is url, make ajax call to url to get data
3093  this._genRemoteRequest();
3094  }
3095  } else {
3096  this.refreshActiveData(loadOrignalData ? "filter" : "sort");
3097  }
3098 
3099  this.scrollHorizontal(left);
3100 };
3101 
3102 RowManager.prototype.scrollHorizontal = function (left) {
3103  this.scrollLeft = left;
3104  this.element.scrollLeft = left;
3105 
3106  if (this.table.options.groupBy) {
3107  this.table.modules.groupRows.scrollHeaders(left);
3108  }
3109 
3110  if (this.table.modExists("columnCalcs")) {
3111  this.table.modules.columnCalcs.scrollHorizontal(left);
3112  }
3113 };
3114 
3115 //set active data set
3116 RowManager.prototype.refreshActiveData = function (stage, skipStage, renderInPosition) {
3117  var _this12 = this;
3118 
3119  var self = this,
3120  table = this.table,
3121  cascadeOrder = ["all", "filter", "sort", "display", "freeze", "group", "tree", "page"],
3122  displayIndex;
3123 
3124  if (this.redrawBlock) {
3125 
3126  if (!this.redrawBlockRestoreConfig || cascadeOrder.indexOf(stage) < cascadeOrder.indexOf(this.redrawBlockRestoreConfig.stage)) {
3127  this.redrawBlockRestoreConfig = {
3128  stage: stage,
3129  skipStage: skipStage,
3130  renderInPosition: renderInPosition
3131  };
3132  }
3133 
3134  return;
3135  } else {
3136 
3137  if (self.table.modExists("edit")) {
3138  self.table.modules.edit.cancelEdit();
3139  }
3140 
3141  if (!stage) {
3142  stage = "all";
3143  }
3144 
3145  if (table.options.selectable && !table.options.selectablePersistence && table.modExists("selectRow")) {
3146  table.modules.selectRow.deselectRows();
3147  }
3148 
3149  //cascade through data refresh stages
3150  switch (stage) {
3151  case "all":
3152 
3153  case "filter":
3154  if (!skipStage) {
3155  if (table.modExists("filter")) {
3156  self.setActiveRows(table.modules.filter.filter(self.rows));
3157  } else {
3158  self.setActiveRows(self.rows.slice(0));
3159  }
3160  } else {
3161  skipStage = false;
3162  }
3163 
3164  case "sort":
3165  if (!skipStage) {
3166  if (table.modExists("sort")) {
3167  table.modules.sort.sort(this.activeRows);
3168  }
3169  } else {
3170  skipStage = false;
3171  }
3172 
3173  //regenerate row numbers for row number formatter if in use
3174  if (this.rowNumColumn) {
3175  this.activeRows.forEach(function (row) {
3176  var cell = row.getCell(_this12.rowNumColumn);
3177 
3178  if (cell) {
3179  cell._generateContents();
3180  }
3181  });
3182  }
3183 
3184  //generic stage to allow for pipeline trigger after the data manipulation stage
3185  case "display":
3186  this.resetDisplayRows();
3187 
3188  case "freeze":
3189  if (!skipStage) {
3190  if (this.table.modExists("frozenRows")) {
3191  if (table.modules.frozenRows.isFrozen()) {
3192  if (!table.modules.frozenRows.getDisplayIndex()) {
3193  table.modules.frozenRows.setDisplayIndex(this.getNextDisplayIndex());
3194  }
3195 
3196  displayIndex = table.modules.frozenRows.getDisplayIndex();
3197 
3198  displayIndex = self.setDisplayRows(table.modules.frozenRows.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
3199 
3200  if (displayIndex !== true) {
3201  table.modules.frozenRows.setDisplayIndex(displayIndex);
3202  }
3203  }
3204  }
3205  } else {
3206  skipStage = false;
3207  }
3208 
3209  case "group":
3210  if (!skipStage) {
3211  if (table.options.groupBy && table.modExists("groupRows")) {
3212 
3213  if (!table.modules.groupRows.getDisplayIndex()) {
3214  table.modules.groupRows.setDisplayIndex(this.getNextDisplayIndex());
3215  }
3216 
3217  displayIndex = table.modules.groupRows.getDisplayIndex();
3218 
3219  displayIndex = self.setDisplayRows(table.modules.groupRows.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
3220 
3221  if (displayIndex !== true) {
3222  table.modules.groupRows.setDisplayIndex(displayIndex);
3223  }
3224  }
3225  } else {
3226  skipStage = false;
3227  }
3228 
3229  case "tree":
3230 
3231  if (!skipStage) {
3232  if (table.options.dataTree && table.modExists("dataTree")) {
3233  if (!table.modules.dataTree.getDisplayIndex()) {
3234  table.modules.dataTree.setDisplayIndex(this.getNextDisplayIndex());
3235  }
3236 
3237  displayIndex = table.modules.dataTree.getDisplayIndex();
3238 
3239  displayIndex = self.setDisplayRows(table.modules.dataTree.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
3240 
3241  if (displayIndex !== true) {
3242  table.modules.dataTree.setDisplayIndex(displayIndex);
3243  }
3244  }
3245  } else {
3246  skipStage = false;
3247  }
3248 
3249  if (table.options.pagination && table.modExists("page") && !renderInPosition) {
3250  if (table.modules.page.getMode() == "local") {
3251  table.modules.page.reset();
3252  }
3253  }
3254 
3255  case "page":
3256  if (!skipStage) {
3257  if (table.options.pagination && table.modExists("page")) {
3258 
3259  if (!table.modules.page.getDisplayIndex()) {
3260  table.modules.page.setDisplayIndex(this.getNextDisplayIndex());
3261  }
3262 
3263  displayIndex = table.modules.page.getDisplayIndex();
3264 
3265  if (table.modules.page.getMode() == "local") {
3266  table.modules.page.setMaxRows(this.getDisplayRows(displayIndex - 1).length);
3267  }
3268 
3269  displayIndex = self.setDisplayRows(table.modules.page.getRows(this.getDisplayRows(displayIndex - 1)), displayIndex);
3270 
3271  if (displayIndex !== true) {
3272  table.modules.page.setDisplayIndex(displayIndex);
3273  }
3274  }
3275  } else {
3276  skipStage = false;
3277  }
3278  }
3279 
3280  if (Tabulator.prototype.helpers.elVisible(self.element)) {
3281  if (renderInPosition) {
3282  self.reRenderInPosition();
3283  } else {
3284  self.renderTable();
3285  if (table.options.layoutColumnsOnNewData) {
3286  self.table.columnManager.redraw(true);
3287  }
3288  }
3289  }
3290 
3291  if (table.modExists("columnCalcs")) {
3292  table.modules.columnCalcs.recalc(this.activeRows);
3293  }
3294  }
3295 };
3296 
3297 RowManager.prototype.setActiveRows = function (activeRows) {
3298  this.activeRows = activeRows;
3299  this.activeRowsCount = this.activeRows.length;
3300 };
3301 
3302 //reset display rows array
3303 RowManager.prototype.resetDisplayRows = function () {
3304  this.displayRows = [];
3305 
3306  this.displayRows.push(this.activeRows.slice(0));
3307 
3308  this.displayRowsCount = this.displayRows[0].length;
3309 
3310  if (this.table.modExists("frozenRows")) {
3311  this.table.modules.frozenRows.setDisplayIndex(0);
3312  }
3313 
3314  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
3315  this.table.modules.groupRows.setDisplayIndex(0);
3316  }
3317 
3318  if (this.table.options.pagination && this.table.modExists("page")) {
3319  this.table.modules.page.setDisplayIndex(0);
3320  }
3321 };
3322 
3323 RowManager.prototype.getNextDisplayIndex = function () {
3324  return this.displayRows.length;
3325 };
3326 
3327 //set display row pipeline data
3328 RowManager.prototype.setDisplayRows = function (displayRows, index) {
3329 
3330  var output = true;
3331 
3332  if (index && typeof this.displayRows[index] != "undefined") {
3333  this.displayRows[index] = displayRows;
3334  output = true;
3335  } else {
3336  this.displayRows.push(displayRows);
3337  output = index = this.displayRows.length - 1;
3338  }
3339 
3340  if (index == this.displayRows.length - 1) {
3341  this.displayRowsCount = this.displayRows[this.displayRows.length - 1].length;
3342  }
3343 
3344  return output;
3345 };
3346 
3347 RowManager.prototype.getDisplayRows = function (index) {
3348  if (typeof index == "undefined") {
3349  return this.displayRows.length ? this.displayRows[this.displayRows.length - 1] : [];
3350  } else {
3351  return this.displayRows[index] || [];
3352  }
3353 };
3354 
3355 RowManager.prototype.getVisibleRows = function (viewable) {
3356  var topEdge = this.element.scrollTop,
3357  bottomEdge = this.element.clientHeight + topEdge,
3358  topFound = false,
3359  topRow = 0,
3360  bottomRow = 0,
3361  rows = this.getDisplayRows();
3362 
3363  if (viewable) {
3364 
3365  this.getDisplayRows();
3366  for (var i = this.vDomTop; i <= this.vDomBottom; i++) {
3367  if (rows[i]) {
3368  if (!topFound) {
3369  if (topEdge - rows[i].getElement().offsetTop >= 0) {
3370  topRow = i;
3371  } else {
3372  topFound = true;
3373 
3374  if (bottomEdge - rows[i].getElement().offsetTop >= 0) {
3375  bottomRow = i;
3376  } else {
3377  break;
3378  }
3379  }
3380  } else {
3381  if (bottomEdge - rows[i].getElement().offsetTop >= 0) {
3382  bottomRow = i;
3383  } else {
3384  break;
3385  }
3386  }
3387  }
3388  }
3389  } else {
3390  topRow = this.vDomTop;
3391  bottomRow = this.vDomBottom;
3392  }
3393 
3394  return rows.slice(topRow, bottomRow + 1);
3395 };
3396 
3397 //repeat action accross display rows
3398 RowManager.prototype.displayRowIterator = function (callback) {
3399  this.displayRows.forEach(callback);
3400 
3401  this.displayRowsCount = this.displayRows[this.displayRows.length - 1].length;
3402 };
3403 
3404 //return only actual rows (not group headers etc)
3405 RowManager.prototype.getRows = function (active) {
3406  var rows;
3407 
3408  switch (active) {
3409  case "active":
3410  rows = this.activeRows;
3411  break;
3412 
3413  case "visible":
3414  rows = this.getVisibleRows(true);
3415  break;
3416 
3417  default:
3418  rows = this.rows;
3419  }
3420 
3421  return rows;
3422 };
3423 
3425 
3426 //trigger rerender of table in current position
3427 RowManager.prototype.reRenderInPosition = function (callback) {
3428  if (this.getRenderMode() == "virtual") {
3429 
3430  if (this.redrawBlock) {
3431  if (callback) {
3432  callback();
3433  } else {
3434  this.redrawBlockRederInPosition = true;
3435  }
3436  } else {
3437  var scrollTop = this.element.scrollTop;
3438  var topRow = false;
3439  var topOffset = false;
3440 
3441  var left = this.scrollLeft;
3442 
3443  var rows = this.getDisplayRows();
3444 
3445  for (var i = this.vDomTop; i <= this.vDomBottom; i++) {
3446 
3447  if (rows[i]) {
3448  var diff = scrollTop - rows[i].getElement().offsetTop;
3449 
3450  if (topOffset === false || Math.abs(diff) < topOffset) {
3451  topOffset = diff;
3452  topRow = i;
3453  } else {
3454  break;
3455  }
3456  }
3457  }
3458 
3459  if (callback) {
3460  callback();
3461  }
3462 
3463  this._virtualRenderFill(topRow === false ? this.displayRowsCount - 1 : topRow, true, topOffset || 0);
3464 
3465  this.scrollHorizontal(left);
3466  }
3467  } else {
3468  this.renderTable();
3469 
3470  if (callback) {
3471  callback();
3472  }
3473  }
3474 };
3475 
3476 RowManager.prototype.setRenderMode = function () {
3477  if ((this.table.element.clientHeight || this.table.options.height) && this.table.options.virtualDom) {
3478  this.renderMode = "virtual";
3479  } else {
3480  this.renderMode = "classic";
3481  }
3482 };
3483 
3484 RowManager.prototype.getRenderMode = function () {
3485  return this.renderMode;
3486 };
3487 
3488 RowManager.prototype.renderTable = function () {
3489  var self = this;
3490 
3491  self.table.options.renderStarted.call(this.table);
3492 
3493  self.element.scrollTop = 0;
3494 
3495  switch (self.renderMode) {
3496  case "classic":
3497  self._simpleRender();
3498  break;
3499 
3500  case "virtual":
3501  self._virtualRenderFill();
3502  break;
3503  }
3504 
3505  if (self.firstRender) {
3506  if (self.displayRowsCount) {
3507  self.firstRender = false;
3508  self.table.modules.layout.layout();
3509  } else {
3510  self.renderEmptyScroll();
3511  }
3512  }
3513 
3514  if (self.table.modExists("frozenColumns")) {
3515  self.table.modules.frozenColumns.layout();
3516  }
3517 
3518  if (!self.displayRowsCount) {
3519  if (self.table.options.placeholder) {
3520 
3521  if (this.renderMode) {
3522  self.table.options.placeholder.setAttribute("tabulator-render-mode", this.renderMode);
3523  }
3524 
3525  self.getElement().appendChild(self.table.options.placeholder);
3526  }
3527  }
3528 
3529  self.table.options.renderComplete.call(this.table);
3530 };
3531 
3532 //simple render on heightless table
3533 RowManager.prototype._simpleRender = function () {
3534  this._clearVirtualDom();
3535 
3536  if (this.displayRowsCount) {
3537  this.checkClassicModeGroupHeaderWidth();
3538  } else {
3539  this.renderEmptyScroll();
3540  }
3541 };
3542 
3543 RowManager.prototype.checkClassicModeGroupHeaderWidth = function () {
3544  var self = this,
3545  element = this.tableElement,
3546  onlyGroupHeaders = true;
3547 
3548  self.getDisplayRows().forEach(function (row, index) {
3549  self.styleRow(row, index);
3550  element.appendChild(row.getElement());
3551  row.initialize(true);
3552 
3553  if (row.type !== "group") {
3554  onlyGroupHeaders = false;
3555  }
3556  });
3557 
3558  if (onlyGroupHeaders) {
3559  element.style.minWidth = self.table.columnManager.getWidth() + "px";
3560  } else {
3561  element.style.minWidth = "";
3562  }
3563 };
3564 
3565 //show scrollbars on empty table div
3566 RowManager.prototype.renderEmptyScroll = function () {
3567  this.tableElement.style.minWidth = this.table.columnManager.getWidth() + "px";
3568  this.tableElement.style.minHeight = "1px";
3569  this.tableElement.style.visibility = "hidden";
3570 };
3571 
3572 RowManager.prototype._clearVirtualDom = function () {
3573  var element = this.tableElement;
3574 
3575  if (this.table.options.placeholder && this.table.options.placeholder.parentNode) {
3576  this.table.options.placeholder.parentNode.removeChild(this.table.options.placeholder);
3577  }
3578 
3579  // element.children.detach();
3580  while (element.firstChild) {
3581  element.removeChild(element.firstChild);
3582  }element.style.paddingTop = "";
3583  element.style.paddingBottom = "";
3584  element.style.minWidth = "";
3585  element.style.minHeight = "";
3586  element.style.visibility = "";
3587 
3588  this.scrollTop = 0;
3589  this.scrollLeft = 0;
3590  this.vDomTop = 0;
3591  this.vDomBottom = 0;
3592  this.vDomTopPad = 0;
3593  this.vDomBottomPad = 0;
3594 };
3595 
3596 RowManager.prototype.styleRow = function (row, index) {
3597  var rowEl = row.getElement();
3598 
3599  if (index % 2) {
3600  rowEl.classList.add("tabulator-row-even");
3601  rowEl.classList.remove("tabulator-row-odd");
3602  } else {
3603  rowEl.classList.add("tabulator-row-odd");
3604  rowEl.classList.remove("tabulator-row-even");
3605  }
3606 };
3607 
3608 //full virtual render
3609 RowManager.prototype._virtualRenderFill = function (position, forceMove, offset) {
3610  var self = this,
3611  element = self.tableElement,
3612  holder = self.element,
3613  topPad = 0,
3614  rowsHeight = 0,
3615  topPadHeight = 0,
3616  i = 0,
3617  onlyGroupHeaders = true,
3618  rows = self.getDisplayRows();
3619 
3620  position = position || 0;
3621 
3622  offset = offset || 0;
3623 
3624  if (!position) {
3625  self._clearVirtualDom();
3626  } else {
3627  while (element.firstChild) {
3628  element.removeChild(element.firstChild);
3629  } //check if position is too close to bottom of table
3630  var heightOccupied = (self.displayRowsCount - position + 1) * self.vDomRowHeight;
3631 
3632  if (heightOccupied < self.height) {
3633  position -= Math.ceil((self.height - heightOccupied) / self.vDomRowHeight);
3634 
3635  if (position < 0) {
3636  position = 0;
3637  }
3638  }
3639 
3640  //calculate initial pad
3641  topPad = Math.min(Math.max(Math.floor(self.vDomWindowBuffer / self.vDomRowHeight), self.vDomWindowMinMarginRows), position);
3642  position -= topPad;
3643  }
3644 
3645  if (self.displayRowsCount && Tabulator.prototype.helpers.elVisible(self.element)) {
3646 
3647  self.vDomTop = position;
3648 
3649  self.vDomBottom = position - 1;
3650 
3651  while ((rowsHeight <= self.height + self.vDomWindowBuffer || i < self.vDomWindowMinTotalRows) && self.vDomBottom < self.displayRowsCount - 1) {
3652  var index = self.vDomBottom + 1,
3653  row = rows[index],
3654  rowHeight = 0;
3655 
3656  self.styleRow(row, index);
3657 
3658  element.appendChild(row.getElement());
3659  if (!row.initialized) {
3660  row.initialize(true);
3661  } else {
3662  if (!row.heightInitialized) {
3663  row.normalizeHeight(true);
3664  }
3665  }
3666 
3667  rowHeight = row.getHeight();
3668 
3669  if (i < topPad) {
3670  topPadHeight += rowHeight;
3671  } else {
3672  rowsHeight += rowHeight;
3673  }
3674 
3675  if (rowHeight > this.vDomWindowBuffer) {
3676  this.vDomWindowBuffer = rowHeight * 2;
3677  }
3678 
3679  if (row.type !== "group") {
3680  onlyGroupHeaders = false;
3681  }
3682 
3683  self.vDomBottom++;
3684  i++;
3685  }
3686 
3687  if (!position) {
3688  this.vDomTopPad = 0;
3689  //adjust rowheight to match average of rendered elements
3690  self.vDomRowHeight = Math.floor((rowsHeight + topPadHeight) / i);
3691  self.vDomBottomPad = self.vDomRowHeight * (self.displayRowsCount - self.vDomBottom - 1);
3692 
3693  self.vDomScrollHeight = topPadHeight + rowsHeight + self.vDomBottomPad - self.height;
3694  } else {
3695  self.vDomTopPad = !forceMove ? self.scrollTop - topPadHeight : self.vDomRowHeight * this.vDomTop + offset;
3696  self.vDomBottomPad = self.vDomBottom == self.displayRowsCount - 1 ? 0 : Math.max(self.vDomScrollHeight - self.vDomTopPad - rowsHeight - topPadHeight, 0);
3697  }
3698 
3699  element.style.paddingTop = self.vDomTopPad + "px";
3700  element.style.paddingBottom = self.vDomBottomPad + "px";
3701 
3702  if (forceMove) {
3703  this.scrollTop = self.vDomTopPad + topPadHeight + offset - (this.element.scrollWidth > this.element.clientWidth ? this.element.offsetHeight - this.element.clientHeight : 0);
3704  }
3705 
3706  this.scrollTop = Math.min(this.scrollTop, this.element.scrollHeight - this.height);
3707 
3708  //adjust for horizontal scrollbar if present (and not at top of table)
3709  if (this.element.scrollWidth > this.element.offsetWidth && forceMove) {
3710  this.scrollTop += this.element.offsetHeight - this.element.clientHeight;
3711  }
3712 
3713  this.vDomScrollPosTop = this.scrollTop;
3714  this.vDomScrollPosBottom = this.scrollTop;
3715 
3716  holder.scrollTop = this.scrollTop;
3717 
3718  element.style.minWidth = onlyGroupHeaders ? self.table.columnManager.getWidth() + "px" : "";
3719 
3720  if (self.table.options.groupBy) {
3721  if (self.table.modules.layout.getMode() != "fitDataFill" && self.displayRowsCount == self.table.modules.groupRows.countGroups()) {
3722  self.tableElement.style.minWidth = self.table.columnManager.getWidth();
3723  }
3724  }
3725  } else {
3726  this.renderEmptyScroll();
3727  }
3728 };
3729 
3730 //handle vertical scrolling
3731 RowManager.prototype.scrollVertical = function (dir) {
3732  var topDiff = this.scrollTop - this.vDomScrollPosTop;
3733  var bottomDiff = this.scrollTop - this.vDomScrollPosBottom;
3734  var margin = this.vDomWindowBuffer * 2;
3735 
3736  if (-topDiff > margin || bottomDiff > margin) {
3737  //if big scroll redraw table;
3738  var left = this.scrollLeft;
3739  this._virtualRenderFill(Math.floor(this.element.scrollTop / this.element.scrollHeight * this.displayRowsCount));
3740  this.scrollHorizontal(left);
3741  } else {
3742 
3743  if (dir) {
3744  //scrolling up
3745  if (topDiff < 0) {
3746  this._addTopRow(-topDiff);
3747  }
3748 
3749  if (bottomDiff < 0) {
3750 
3751  //hide bottom row if needed
3752  if (this.vDomScrollHeight - this.scrollTop > this.vDomWindowBuffer) {
3753  this._removeBottomRow(-bottomDiff);
3754  }
3755  }
3756  } else {
3757  //scrolling down
3758  if (topDiff >= 0) {
3759 
3760  //hide top row if needed
3761  if (this.scrollTop > this.vDomWindowBuffer) {
3762  this._removeTopRow(topDiff);
3763  }
3764  }
3765 
3766  if (bottomDiff >= 0) {
3767  this._addBottomRow(bottomDiff);
3768  }
3769  }
3770  }
3771 };
3772 
3773 RowManager.prototype._addTopRow = function (topDiff) {
3774  var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
3775 
3776  var table = this.tableElement,
3777  rows = this.getDisplayRows();
3778 
3779  if (this.vDomTop) {
3780  var index = this.vDomTop - 1,
3781  topRow = rows[index],
3782  topRowHeight = topRow.getHeight() || this.vDomRowHeight;
3783 
3784  //hide top row if needed
3785  if (topDiff >= topRowHeight) {
3786  this.styleRow(topRow, index);
3787  table.insertBefore(topRow.getElement(), table.firstChild);
3788  if (!topRow.initialized || !topRow.heightInitialized) {
3789  this.vDomTopNewRows.push(topRow);
3790 
3791  if (!topRow.heightInitialized) {
3792  topRow.clearCellHeight();
3793  }
3794  }
3795  topRow.initialize();
3796 
3797  this.vDomTopPad -= topRowHeight;
3798 
3799  if (this.vDomTopPad < 0) {
3800  this.vDomTopPad = index * this.vDomRowHeight;
3801  }
3802 
3803  if (!index) {
3804  this.vDomTopPad = 0;
3805  }
3806 
3807  table.style.paddingTop = this.vDomTopPad + "px";
3808  this.vDomScrollPosTop -= topRowHeight;
3809  this.vDomTop--;
3810  }
3811 
3812  topDiff = -(this.scrollTop - this.vDomScrollPosTop);
3813 
3814  if (topRow.getHeight() > this.vDomWindowBuffer) {
3815  this.vDomWindowBuffer = topRow.getHeight() * 2;
3816  }
3817 
3818  if (i < this.vDomMaxRenderChain && this.vDomTop && topDiff >= (rows[this.vDomTop - 1].getHeight() || this.vDomRowHeight)) {
3819  this._addTopRow(topDiff, i + 1);
3820  } else {
3821  this._quickNormalizeRowHeight(this.vDomTopNewRows);
3822  }
3823  }
3824 };
3825 
3826 RowManager.prototype._removeTopRow = function (topDiff) {
3827  var table = this.tableElement,
3828  topRow = this.getDisplayRows()[this.vDomTop],
3829  topRowHeight = topRow.getHeight() || this.vDomRowHeight;
3830 
3831  if (topDiff >= topRowHeight) {
3832 
3833  var rowEl = topRow.getElement();
3834  rowEl.parentNode.removeChild(rowEl);
3835 
3836  this.vDomTopPad += topRowHeight;
3837  table.style.paddingTop = this.vDomTopPad + "px";
3838  this.vDomScrollPosTop += this.vDomTop ? topRowHeight : topRowHeight + this.vDomWindowBuffer;
3839  this.vDomTop++;
3840 
3841  topDiff = this.scrollTop - this.vDomScrollPosTop;
3842 
3843  this._removeTopRow(topDiff);
3844  }
3845 };
3846 
3847 RowManager.prototype._addBottomRow = function (bottomDiff) {
3848  var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
3849 
3850  var table = this.tableElement,
3851  rows = this.getDisplayRows();
3852 
3853  if (this.vDomBottom < this.displayRowsCount - 1) {
3854  var index = this.vDomBottom + 1,
3855  bottomRow = rows[index],
3856  bottomRowHeight = bottomRow.getHeight() || this.vDomRowHeight;
3857 
3858  //hide bottom row if needed
3859  if (bottomDiff >= bottomRowHeight) {
3860  this.styleRow(bottomRow, index);
3861  table.appendChild(bottomRow.getElement());
3862 
3863  if (!bottomRow.initialized || !bottomRow.heightInitialized) {
3864  this.vDomBottomNewRows.push(bottomRow);
3865 
3866  if (!bottomRow.heightInitialized) {
3867  bottomRow.clearCellHeight();
3868  }
3869  }
3870 
3871  bottomRow.initialize();
3872 
3873  this.vDomBottomPad -= bottomRowHeight;
3874 
3875  if (this.vDomBottomPad < 0 || index == this.displayRowsCount - 1) {
3876  this.vDomBottomPad = 0;
3877  }
3878 
3879  table.style.paddingBottom = this.vDomBottomPad + "px";
3880  this.vDomScrollPosBottom += bottomRowHeight;
3881  this.vDomBottom++;
3882  }
3883 
3884  bottomDiff = this.scrollTop - this.vDomScrollPosBottom;
3885 
3886  if (bottomRow.getHeight() > this.vDomWindowBuffer) {
3887  this.vDomWindowBuffer = bottomRow.getHeight() * 2;
3888  }
3889 
3890  if (i < this.vDomMaxRenderChain && this.vDomBottom < this.displayRowsCount - 1 && bottomDiff >= (rows[this.vDomBottom + 1].getHeight() || this.vDomRowHeight)) {
3891  this._addBottomRow(bottomDiff, i + 1);
3892  } else {
3893  this._quickNormalizeRowHeight(this.vDomBottomNewRows);
3894  }
3895  }
3896 };
3897 
3898 RowManager.prototype._removeBottomRow = function (bottomDiff) {
3899  var table = this.tableElement,
3900  bottomRow = this.getDisplayRows()[this.vDomBottom],
3901  bottomRowHeight = bottomRow.getHeight() || this.vDomRowHeight;
3902 
3903  if (bottomDiff >= bottomRowHeight) {
3904 
3905  var rowEl = bottomRow.getElement();
3906 
3907  if (rowEl.parentNode) {
3908  rowEl.parentNode.removeChild(rowEl);
3909  }
3910 
3911  this.vDomBottomPad += bottomRowHeight;
3912 
3913  if (this.vDomBottomPad < 0) {
3914  this.vDomBottomPad = 0;
3915  }
3916 
3917  table.style.paddingBottom = this.vDomBottomPad + "px";
3918  this.vDomScrollPosBottom -= bottomRowHeight;
3919  this.vDomBottom--;
3920 
3921  bottomDiff = -(this.scrollTop - this.vDomScrollPosBottom);
3922 
3923  this._removeBottomRow(bottomDiff);
3924  }
3925 };
3926 
3927 RowManager.prototype._quickNormalizeRowHeight = function (rows) {
3928  rows.forEach(function (row) {
3929  row.calcHeight();
3930  });
3931 
3932  rows.forEach(function (row) {
3933  row.setCellHeight();
3934  });
3935 
3936  rows.length = 0;
3937 };
3938 
3939 //normalize height of active rows
3940 RowManager.prototype.normalizeHeight = function () {
3941  this.activeRows.forEach(function (row) {
3942  row.normalizeHeight();
3943  });
3944 };
3945 
3946 //adjust the height of the table holder to fit in the Tabulator element
3947 RowManager.prototype.adjustTableSize = function () {
3948 
3949  if (this.renderMode === "virtual") {
3950  this.height = this.element.clientHeight;
3951  this.vDomWindowBuffer = this.table.options.virtualDomBuffer || this.height;
3952 
3953  var otherHeight = this.columnManager.getElement().offsetHeight + (this.table.footerManager && !this.table.footerManager.external ? this.table.footerManager.getElement().offsetHeight : 0);
3954 
3955  this.element.style.minHeight = "calc(100% - " + otherHeight + "px)";
3956  this.element.style.height = "calc(100% - " + otherHeight + "px)";
3957  this.element.style.maxHeight = "calc(100% - " + otherHeight + "px)";
3958  }
3959 };
3960 
3961 //renitialize all rows
3962 RowManager.prototype.reinitialize = function () {
3963  this.rows.forEach(function (row) {
3964  row.reinitialize();
3965  });
3966 };
3967 
3968 //prevent table from being redrawn
3969 RowManager.prototype.blockRedraw = function () {
3970  this.redrawBlock = true;
3971  this.redrawBlockRestoreConfig = false;
3972 };
3973 
3974 //restore table redrawing
3975 RowManager.prototype.restoreRedraw = function () {
3976  this.redrawBlock = false;
3977 
3978  if (this.redrawBlockRestoreConfig) {
3979  this.refreshActiveData(this.redrawBlockRestoreConfig.stage, this.redrawBlockRestoreConfig.skipStage, this.redrawBlockRestoreConfig.renderInPosition);
3980 
3981  this.redrawBlockRestoreConfig = false;
3982  } else {
3983  if (this.redrawBlockRederInPosition) {
3984  this.reRenderInPosition();
3985  }
3986  }
3987 
3988  this.redrawBlockRederInPosition = false;
3989 };
3990 
3991 //redraw table
3992 RowManager.prototype.redraw = function (force) {
3993  var pos = 0,
3994  left = this.scrollLeft;
3995 
3996  this.adjustTableSize();
3997 
3998  this.table.tableWidth = this.table.element.clientWidth;
3999 
4000  if (!force) {
4001  if (this.renderMode == "classic") {
4002 
4003  if (this.table.options.groupBy) {
4004  this.refreshActiveData("group", false, false);
4005  } else {
4006  this._simpleRender();
4007  }
4008  } else {
4009  this.reRenderInPosition();
4010  this.scrollHorizontal(left);
4011  }
4012 
4013  if (!this.displayRowsCount) {
4014  if (this.table.options.placeholder) {
4015  this.getElement().appendChild(this.table.options.placeholder);
4016  }
4017  }
4018  } else {
4019  this.renderTable();
4020  }
4021 };
4022 
4023 RowManager.prototype.resetScroll = function () {
4024  this.element.scrollLeft = 0;
4025  this.element.scrollTop = 0;
4026 
4027  if (this.table.browser === "ie") {
4028  var event = document.createEvent("Event");
4029  event.initEvent("scroll", false, true);
4030  this.element.dispatchEvent(event);
4031  } else {
4032  this.element.dispatchEvent(new Event('scroll'));
4033  }
4034 };
4035 
4036 //public row object
4037 var RowComponent = function RowComponent(row) {
4038  this._row = row;
4039 };
4040 
4041 RowComponent.prototype.getData = function (transform) {
4042  return this._row.getData(transform);
4043 };
4044 
4045 RowComponent.prototype.getElement = function () {
4046  return this._row.getElement();
4047 };
4048 
4049 RowComponent.prototype.getCells = function () {
4050  var cells = [];
4051 
4052  this._row.getCells().forEach(function (cell) {
4053  cells.push(cell.getComponent());
4054  });
4055 
4056  return cells;
4057 };
4058 
4059 RowComponent.prototype.getCell = function (column) {
4060  var cell = this._row.getCell(column);
4061  return cell ? cell.getComponent() : false;
4062 };
4063 
4064 RowComponent.prototype.getIndex = function () {
4065  return this._row.getData("data")[this._row.table.options.index];
4066 };
4067 
4068 RowComponent.prototype.getPosition = function (active) {
4069  return this._row.table.rowManager.getRowPosition(this._row, active);
4070 };
4071 
4072 RowComponent.prototype.delete = function () {
4073  return this._row.delete();
4074 };
4075 
4076 RowComponent.prototype.scrollTo = function () {
4077  return this._row.table.rowManager.scrollToRow(this._row);
4078 };
4079 
4080 RowComponent.prototype.pageTo = function () {
4081  if (this._row.table.modExists("page", true)) {
4082  return this._row.table.modules.page.setPageToRow(this._row);
4083  }
4084 };
4085 
4086 RowComponent.prototype.move = function (to, after) {
4087  this._row.moveToRow(to, after);
4088 };
4089 
4090 RowComponent.prototype.update = function (data) {
4091  return this._row.updateData(data);
4092 };
4093 
4094 RowComponent.prototype.normalizeHeight = function () {
4095  this._row.normalizeHeight(true);
4096 };
4097 
4098 RowComponent.prototype.select = function () {
4099  this._row.table.modules.selectRow.selectRows(this._row);
4100 };
4101 
4102 RowComponent.prototype.deselect = function () {
4103  this._row.table.modules.selectRow.deselectRows(this._row);
4104 };
4105 
4106 RowComponent.prototype.toggleSelect = function () {
4107  this._row.table.modules.selectRow.toggleRow(this._row);
4108 };
4109 
4110 RowComponent.prototype.isSelected = function () {
4111  return this._row.table.modules.selectRow.isRowSelected(this._row);
4112 };
4113 
4114 RowComponent.prototype._getSelf = function () {
4115  return this._row;
4116 };
4117 
4118 RowComponent.prototype.freeze = function () {
4119  if (this._row.table.modExists("frozenRows", true)) {
4120  this._row.table.modules.frozenRows.freezeRow(this._row);
4121  }
4122 };
4123 
4124 RowComponent.prototype.unfreeze = function () {
4125  if (this._row.table.modExists("frozenRows", true)) {
4126  this._row.table.modules.frozenRows.unfreezeRow(this._row);
4127  }
4128 };
4129 
4130 RowComponent.prototype.treeCollapse = function () {
4131  if (this._row.table.modExists("dataTree", true)) {
4132  this._row.table.modules.dataTree.collapseRow(this._row);
4133  }
4134 };
4135 
4136 RowComponent.prototype.treeExpand = function () {
4137  if (this._row.table.modExists("dataTree", true)) {
4138  this._row.table.modules.dataTree.expandRow(this._row);
4139  }
4140 };
4141 
4142 RowComponent.prototype.treeToggle = function () {
4143  if (this._row.table.modExists("dataTree", true)) {
4144  this._row.table.modules.dataTree.toggleRow(this._row);
4145  }
4146 };
4147 
4148 RowComponent.prototype.getTreeParent = function () {
4149  if (this._row.table.modExists("dataTree", true)) {
4150  return this._row.table.modules.dataTree.getTreeParent(this._row);
4151  }
4152 
4153  return false;
4154 };
4155 
4156 RowComponent.prototype.getTreeChildren = function () {
4157  if (this._row.table.modExists("dataTree", true)) {
4158  return this._row.table.modules.dataTree.getTreeChildren(this._row);
4159  }
4160 
4161  return false;
4162 };
4163 
4164 RowComponent.prototype.reformat = function () {
4165  return this._row.reinitialize();
4166 };
4167 
4168 RowComponent.prototype.getGroup = function () {
4169  return this._row.getGroup().getComponent();
4170 };
4171 
4172 RowComponent.prototype.getTable = function () {
4173  return this._row.table;
4174 };
4175 
4176 RowComponent.prototype.getNextRow = function () {
4177  var row = this._row.nextRow();
4178  return row ? row.getComponent() : row;
4179 };
4180 
4181 RowComponent.prototype.getPrevRow = function () {
4182  var row = this._row.prevRow();
4183  return row ? row.getComponent() : row;
4184 };
4185 
4186 var Row = function Row(data, parent) {
4187  var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "row";
4188 
4189  this.table = parent.table;
4190  this.parent = parent;
4191  this.data = {};
4192  this.type = type; //type of element
4193  this.element = this.createElement();
4194  this.modules = {}; //hold module variables;
4195  this.cells = [];
4196  this.height = 0; //hold element height
4197  this.heightStyled = ""; //hold element height prestyled to improve render efficiency
4198  this.manualHeight = false; //user has manually set row height
4199  this.outerHeight = 0; //holde lements outer height
4200  this.initialized = false; //element has been rendered
4201  this.heightInitialized = false; //element has resized cells to fit
4202 
4203  this.setData(data);
4204  this.generateElement();
4205 };
4206 
4207 Row.prototype.createElement = function () {
4208  var el = document.createElement("div");
4209 
4210  el.classList.add("tabulator-row");
4211  el.setAttribute("role", "row");
4212 
4213  return el;
4214 };
4215 
4216 Row.prototype.getElement = function () {
4217  return this.element;
4218 };
4219 
4220 Row.prototype.detachElement = function () {
4221  if (this.element && this.element.parentNode) {
4222  this.element.parentNode.removeChild(this.element);
4223  }
4224 };
4225 
4226 Row.prototype.generateElement = function () {
4227  var self = this,
4228  dblTap,
4229  tapHold,
4230  tap;
4231 
4232  //set row selection characteristics
4233  if (self.table.options.selectable !== false && self.table.modExists("selectRow")) {
4234  self.table.modules.selectRow.initializeRow(this);
4235  }
4236 
4237  //setup movable rows
4238  if (self.table.options.movableRows !== false && self.table.modExists("moveRow")) {
4239  self.table.modules.moveRow.initializeRow(this);
4240  }
4241 
4242  //setup data tree
4243  if (self.table.options.dataTree !== false && self.table.modExists("dataTree")) {
4244  self.table.modules.dataTree.initializeRow(this);
4245  }
4246 
4247  //setup column colapse container
4248  if (self.table.options.responsiveLayout === "collapse" && self.table.modExists("responsiveLayout")) {
4249  self.table.modules.responsiveLayout.initializeRow(this);
4250  }
4251 
4252  //handle row click events
4253  if (self.table.options.rowClick) {
4254  self.element.addEventListener("click", function (e) {
4255  self.table.options.rowClick(e, self.getComponent());
4256  });
4257  }
4258 
4259  if (self.table.options.rowDblClick) {
4260  self.element.addEventListener("dblclick", function (e) {
4261  self.table.options.rowDblClick(e, self.getComponent());
4262  });
4263  }
4264 
4265  if (self.table.options.rowContext) {
4266  self.element.addEventListener("contextmenu", function (e) {
4267  self.table.options.rowContext(e, self.getComponent());
4268  });
4269  }
4270 
4271  //handle mouse events
4272  if (self.table.options.rowMouseEnter) {
4273  self.element.addEventListener("mouseenter", function (e) {
4274  self.table.options.rowMouseEnter(e, self.getComponent());
4275  });
4276  }
4277 
4278  if (self.table.options.rowMouseLeave) {
4279  self.element.addEventListener("mouseleave", function (e) {
4280  self.table.options.rowMouseLeave(e, self.getComponent());
4281  });
4282  }
4283 
4284  if (self.table.options.rowMouseOver) {
4285  self.element.addEventListener("mouseover", function (e) {
4286  self.table.options.rowMouseOver(e, self.getComponent());
4287  });
4288  }
4289 
4290  if (self.table.options.rowMouseOut) {
4291  self.element.addEventListener("mouseout", function (e) {
4292  self.table.options.rowMouseOut(e, self.getComponent());
4293  });
4294  }
4295 
4296  if (self.table.options.rowMouseMove) {
4297  self.element.addEventListener("mousemove", function (e) {
4298  self.table.options.rowMouseMove(e, self.getComponent());
4299  });
4300  }
4301 
4302  if (self.table.options.rowTap) {
4303 
4304  tap = false;
4305 
4306  self.element.addEventListener("touchstart", function (e) {
4307  tap = true;
4308  }, { passive: true });
4309 
4310  self.element.addEventListener("touchend", function (e) {
4311  if (tap) {
4312  self.table.options.rowTap(e, self.getComponent());
4313  }
4314 
4315  tap = false;
4316  });
4317  }
4318 
4319  if (self.table.options.rowDblTap) {
4320 
4321  dblTap = null;
4322 
4323  self.element.addEventListener("touchend", function (e) {
4324 
4325  if (dblTap) {
4326  clearTimeout(dblTap);
4327  dblTap = null;
4328 
4329  self.table.options.rowDblTap(e, self.getComponent());
4330  } else {
4331 
4332  dblTap = setTimeout(function () {
4333  clearTimeout(dblTap);
4334  dblTap = null;
4335  }, 300);
4336  }
4337  });
4338  }
4339 
4340  if (self.table.options.rowTapHold) {
4341 
4342  tapHold = null;
4343 
4344  self.element.addEventListener("touchstart", function (e) {
4345  clearTimeout(tapHold);
4346 
4347  tapHold = setTimeout(function () {
4348  clearTimeout(tapHold);
4349  tapHold = null;
4350  tap = false;
4351  self.table.options.rowTapHold(e, self.getComponent());
4352  }, 1000);
4353  }, { passive: true });
4354 
4355  self.element.addEventListener("touchend", function (e) {
4356  clearTimeout(tapHold);
4357  tapHold = null;
4358  });
4359  }
4360 };
4361 
4362 Row.prototype.generateCells = function () {
4363  this.cells = this.table.columnManager.generateCells(this);
4364 };
4365 
4366 //functions to setup on first render
4367 Row.prototype.initialize = function (force) {
4368  var self = this;
4369 
4370  if (!self.initialized || force) {
4371 
4372  self.deleteCells();
4373 
4374  while (self.element.firstChild) {
4375  self.element.removeChild(self.element.firstChild);
4376  } //handle frozen cells
4377  if (this.table.modExists("frozenColumns")) {
4378  this.table.modules.frozenColumns.layoutRow(this);
4379  }
4380 
4381  this.generateCells();
4382 
4383  self.cells.forEach(function (cell) {
4384  self.element.appendChild(cell.getElement());
4385  cell.cellRendered();
4386  });
4387 
4388  if (force) {
4389  self.normalizeHeight();
4390  }
4391 
4392  //setup movable rows
4393  if (self.table.options.dataTree && self.table.modExists("dataTree")) {
4394  self.table.modules.dataTree.layoutRow(this);
4395  }
4396 
4397  //setup column colapse container
4398  if (self.table.options.responsiveLayout === "collapse" && self.table.modExists("responsiveLayout")) {
4399  self.table.modules.responsiveLayout.layoutRow(this);
4400  }
4401 
4402  if (self.table.options.rowFormatter) {
4403  self.table.options.rowFormatter(self.getComponent());
4404  }
4405 
4406  //set resizable handles
4407  if (self.table.options.resizableRows && self.table.modExists("resizeRows")) {
4408  self.table.modules.resizeRows.initializeRow(self);
4409  }
4410 
4411  self.initialized = true;
4412  }
4413 };
4414 
4415 Row.prototype.reinitializeHeight = function () {
4416  this.heightInitialized = false;
4417 
4418  if (this.element.offsetParent !== null) {
4419  this.normalizeHeight(true);
4420  }
4421 };
4422 
4423 Row.prototype.reinitialize = function () {
4424  this.initialized = false;
4425  this.heightInitialized = false;
4426 
4427  if (!this.manualHeight) {
4428  this.height = 0;
4429  this.heightStyled = "";
4430  }
4431 
4432  if (this.element.offsetParent !== null) {
4433  this.initialize(true);
4434  }
4435 };
4436 
4437 //get heights when doing bulk row style calcs in virtual DOM
4438 Row.prototype.calcHeight = function (force) {
4439 
4440  var maxHeight = 0,
4441  minHeight = this.table.options.resizableRows ? this.element.clientHeight : 0;
4442 
4443  this.cells.forEach(function (cell) {
4444  var height = cell.getHeight();
4445  if (height > maxHeight) {
4446  maxHeight = height;
4447  }
4448  });
4449 
4450  if (force) {
4451  this.height = Math.max(maxHeight, minHeight);
4452  } else {
4453  this.height = this.manualHeight ? this.height : Math.max(maxHeight, minHeight);
4454  }
4455 
4456  this.heightStyled = this.height ? this.height + "px" : "";
4457  this.outerHeight = this.element.offsetHeight;
4458 };
4459 
4460 //set of cells
4461 Row.prototype.setCellHeight = function () {
4462  this.cells.forEach(function (cell) {
4463  cell.setHeight();
4464  });
4465 
4466  this.heightInitialized = true;
4467 };
4468 
4469 Row.prototype.clearCellHeight = function () {
4470  this.cells.forEach(function (cell) {
4471  cell.clearHeight();
4472  });
4473 };
4474 
4475 //normalize the height of elements in the row
4476 Row.prototype.normalizeHeight = function (force) {
4477 
4478  if (force) {
4479  this.clearCellHeight();
4480  }
4481 
4482  this.calcHeight(force);
4483 
4484  this.setCellHeight();
4485 };
4486 
4487 // Row.prototype.setHeight = function(height){
4488 // this.height = height;
4489 
4490 // this.setCellHeight();
4491 // };
4492 
4493 //set height of rows
4494 Row.prototype.setHeight = function (height, force) {
4495  if (this.height != height || force) {
4496 
4497  this.manualHeight = true;
4498 
4499  this.height = height;
4500  this.heightStyled = height ? height + "px" : "";
4501 
4502  this.setCellHeight();
4503 
4504  // this.outerHeight = this.element.outerHeight();
4505  this.outerHeight = this.element.offsetHeight;
4506  }
4507 };
4508 
4509 //return rows outer height
4510 Row.prototype.getHeight = function () {
4511  return this.outerHeight;
4512 };
4513 
4514 //return rows outer Width
4515 Row.prototype.getWidth = function () {
4516  return this.element.offsetWidth;
4517 };
4518 
4520 
4521 Row.prototype.deleteCell = function (cell) {
4522  var index = this.cells.indexOf(cell);
4523 
4524  if (index > -1) {
4525  this.cells.splice(index, 1);
4526  }
4527 };
4528 
4530 
4531 Row.prototype.setData = function (data) {
4532  if (this.table.modExists("mutator")) {
4533  data = this.table.modules.mutator.transformRow(data, "data", data);
4534  }
4535 
4536  this.data = data;
4537 
4538  if (this.table.options.reactiveData && this.table.modExists("reactiveData", true)) {
4539  this.table.modules.reactiveData.watchRow(this);
4540  }
4541 };
4542 
4543 //update the rows data
4544 Row.prototype.updateData = function (data) {
4545  var _this13 = this;
4546 
4547  var visible = Tabulator.prototype.helpers.elVisible(this.element),
4548  tempData = {};
4549 
4550  return new Promise(function (resolve, reject) {
4551 
4552  if (typeof data === "string") {
4553  data = JSON.parse(data);
4554  }
4555 
4556  if (_this13.table.options.reactiveData && _this13.table.modExists("reactiveData", true)) {
4557  _this13.table.modules.reactiveData.block();
4558  }
4559 
4560  //mutate incomming data if needed
4561  if (_this13.table.modExists("mutator")) {
4562 
4563  tempData = Object.assign(tempData, _this13.data);
4564  tempData = Object.assign(tempData, data);
4565 
4566  data = _this13.table.modules.mutator.transformRow(tempData, "data", data);
4567  }
4568 
4569  //set data
4570  for (var attrname in data) {
4571  _this13.data[attrname] = data[attrname];
4572  }
4573 
4574  if (_this13.table.options.reactiveData && _this13.table.modExists("reactiveData", true)) {
4575  _this13.table.modules.reactiveData.unblock();
4576  }
4577 
4578  //update affected cells only
4579  for (var attrname in data) {
4580 
4581  var columns = _this13.table.columnManager.getColumnsByFieldRoot(attrname);
4582 
4583  columns.forEach(function (column) {
4584  var cell = _this13.getCell(column.getField());
4585 
4586  if (cell) {
4587  var value = column.getFieldValue(data);
4588  if (cell.getValue() != value) {
4589  cell.setValueProcessData(value);
4590 
4591  if (visible) {
4592  cell.cellRendered();
4593  }
4594  }
4595  }
4596  });
4597  }
4598 
4599  //Partial reinitialization if visible
4600  if (visible) {
4601  _this13.normalizeHeight();
4602 
4603  if (_this13.table.options.rowFormatter) {
4604  _this13.table.options.rowFormatter(_this13.getComponent());
4605  }
4606  } else {
4607  _this13.initialized = false;
4608  _this13.height = 0;
4609  _this13.heightStyled = "";
4610  }
4611 
4612  if (_this13.table.options.dataTree !== false && _this13.table.modExists("dataTree") && _this13.table.modules.dataTree.redrawNeeded(data)) {
4613  _this13.table.modules.dataTree.initializeRow(_this13);
4614  _this13.table.modules.dataTree.layoutRow(_this13);
4615  _this13.table.rowManager.refreshActiveData("tree", false, true);
4616  }
4617 
4618  //this.reinitialize();
4619 
4620  _this13.table.options.rowUpdated.call(_this13.table, _this13.getComponent());
4621 
4622  resolve();
4623  });
4624 };
4625 
4626 Row.prototype.getData = function (transform) {
4627  var self = this;
4628 
4629  if (transform) {
4630  if (self.table.modExists("accessor")) {
4631  return self.table.modules.accessor.transformRow(self.data, transform);
4632  }
4633  } else {
4634  return this.data;
4635  }
4636 };
4637 
4638 Row.prototype.getCell = function (column) {
4639  var match = false;
4640 
4641  column = this.table.columnManager.findColumn(column);
4642 
4643  match = this.cells.find(function (cell) {
4644  return cell.column === column;
4645  });
4646 
4647  return match;
4648 };
4649 
4650 Row.prototype.getCellIndex = function (findCell) {
4651  return this.cells.findIndex(function (cell) {
4652  return cell === findCell;
4653  });
4654 };
4655 
4656 Row.prototype.findNextEditableCell = function (index) {
4657  var nextCell = false;
4658 
4659  if (index < this.cells.length - 1) {
4660  for (var i = index + 1; i < this.cells.length; i++) {
4661  var cell = this.cells[i];
4662 
4663  if (cell.column.modules.edit && Tabulator.prototype.helpers.elVisible(cell.getElement())) {
4664  var allowEdit = true;
4665 
4666  if (typeof cell.column.modules.edit.check == "function") {
4667  allowEdit = cell.column.modules.edit.check(cell.getComponent());
4668  }
4669 
4670  if (allowEdit) {
4671  nextCell = cell;
4672  break;
4673  }
4674  }
4675  }
4676  }
4677 
4678  return nextCell;
4679 };
4680 
4681 Row.prototype.findPrevEditableCell = function (index) {
4682  var prevCell = false;
4683 
4684  if (index > 0) {
4685  for (var i = index - 1; i >= 0; i--) {
4686  var cell = this.cells[i],
4687  allowEdit = true;
4688 
4689  if (cell.column.modules.edit && Tabulator.prototype.helpers.elVisible(cell.getElement())) {
4690  if (typeof cell.column.modules.edit.check == "function") {
4691  allowEdit = cell.column.modules.edit.check(cell.getComponent());
4692  }
4693 
4694  if (allowEdit) {
4695  prevCell = cell;
4696  break;
4697  }
4698  }
4699  }
4700  }
4701 
4702  return prevCell;
4703 };
4704 
4705 Row.prototype.getCells = function () {
4706  return this.cells;
4707 };
4708 
4709 Row.prototype.nextRow = function () {
4710  var row = this.table.rowManager.nextDisplayRow(this, true);
4711  return row || false;
4712 };
4713 
4714 Row.prototype.prevRow = function () {
4715  var row = this.table.rowManager.prevDisplayRow(this, true);
4716  return row || false;
4717 };
4718 
4719 Row.prototype.moveToRow = function (to, before) {
4720  var toRow = this.table.rowManager.findRow(to);
4721 
4722  if (toRow) {
4723  this.table.rowManager.moveRowActual(this, toRow, !before);
4724  this.table.rowManager.refreshActiveData("display", false, true);
4725  } else {
4726  console.warn("Move Error - No matching row found:", to);
4727  }
4728 };
4729 
4731 
4732 Row.prototype.delete = function () {
4733  var _this14 = this;
4734 
4735  return new Promise(function (resolve, reject) {
4736  var index, rows;
4737 
4738  if (_this14.table.options.history && _this14.table.modExists("history")) {
4739 
4740  if (_this14.table.options.groupBy && _this14.table.modExists("groupRows")) {
4741  rows = _this14.getGroup().rows;
4742  index = rows.indexOf(_this14);
4743 
4744  if (index) {
4745  index = rows[index - 1];
4746  }
4747  } else {
4748  index = _this14.table.rowManager.getRowIndex(_this14);
4749 
4750  if (index) {
4751  index = _this14.table.rowManager.rows[index - 1];
4752  }
4753  }
4754 
4755  _this14.table.modules.history.action("rowDelete", _this14, { data: _this14.getData(), pos: !index, index: index });
4756  }
4757 
4758  _this14.deleteActual();
4759 
4760  resolve();
4761  });
4762 };
4763 
4764 Row.prototype.deleteActual = function (blockRedraw) {
4765  var index = this.table.rowManager.getRowIndex(this);
4766 
4767  //deselect row if it is selected
4768  if (this.table.modExists("selectRow")) {
4769  this.table.modules.selectRow._deselectRow(this, true);
4770  }
4771 
4772  // if(this.table.options.dataTree && this.table.modExists("dataTree")){
4773  // this.table.modules.dataTree.collapseRow(this, true);
4774  // }
4775 
4776  //remove any reactive data watchers from row object
4777  if (this.table.options.reactiveData && this.table.modExists("reactiveData", true)) {}
4778  // this.table.modules.reactiveData.unwatchRow(this);
4779 
4780 
4781  //remove from group
4782  if (this.modules.group) {
4783  this.modules.group.removeRow(this);
4784  }
4785 
4786  this.table.rowManager.deleteRow(this, blockRedraw);
4787 
4788  this.deleteCells();
4789 
4790  this.initialized = false;
4791  this.heightInitialized = false;
4792 
4793  //recalc column calculations if present
4794  if (this.table.modExists("columnCalcs")) {
4795  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
4796  this.table.modules.columnCalcs.recalcRowGroup(this);
4797  } else {
4798  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
4799  }
4800  }
4801 };
4802 
4803 Row.prototype.deleteCells = function () {
4804  var cellCount = this.cells.length;
4805 
4806  for (var i = 0; i < cellCount; i++) {
4807  this.cells[0].delete();
4808  }
4809 };
4810 
4811 Row.prototype.wipe = function () {
4812  this.deleteCells();
4813 
4814  while (this.element.firstChild) {
4815  this.element.removeChild(this.element.firstChild);
4816  }this.element = false;
4817  this.modules = {};
4818 
4819  if (this.element.parentNode) {
4820  this.element.parentNode.removeChild(this.element);
4821  }
4822 };
4823 
4824 Row.prototype.getGroup = function () {
4825  return this.modules.group || false;
4826 };
4827 
4829 Row.prototype.getComponent = function () {
4830  return new RowComponent(this);
4831 };
4832 
4833 //public row object
4834 var CellComponent = function CellComponent(cell) {
4835  this._cell = cell;
4836 };
4837 
4838 CellComponent.prototype.getValue = function () {
4839  return this._cell.getValue();
4840 };
4841 
4842 CellComponent.prototype.getOldValue = function () {
4843  return this._cell.getOldValue();
4844 };
4845 
4846 CellComponent.prototype.getElement = function () {
4847  return this._cell.getElement();
4848 };
4849 
4850 CellComponent.prototype.getRow = function () {
4851  return this._cell.row.getComponent();
4852 };
4853 
4854 CellComponent.prototype.getData = function () {
4855  return this._cell.row.getData();
4856 };
4857 
4858 CellComponent.prototype.getField = function () {
4859  return this._cell.column.getField();
4860 };
4861 
4862 CellComponent.prototype.getColumn = function () {
4863  return this._cell.column.getComponent();
4864 };
4865 
4866 CellComponent.prototype.setValue = function (value, mutate) {
4867  if (typeof mutate == "undefined") {
4868  mutate = true;
4869  }
4870 
4871  this._cell.setValue(value, mutate);
4872 };
4873 
4874 CellComponent.prototype.restoreOldValue = function () {
4875  this._cell.setValueActual(this._cell.getOldValue());
4876 };
4877 
4878 CellComponent.prototype.edit = function (force) {
4879  return this._cell.edit(force);
4880 };
4881 
4882 CellComponent.prototype.cancelEdit = function () {
4883  this._cell.cancelEdit();
4884 };
4885 
4886 CellComponent.prototype.nav = function () {
4887  return this._cell.nav();
4888 };
4889 
4890 CellComponent.prototype.checkHeight = function () {
4891  this._cell.checkHeight();
4892 };
4893 
4894 CellComponent.prototype.getTable = function () {
4895  return this._cell.table;
4896 };
4897 
4898 CellComponent.prototype._getSelf = function () {
4899  return this._cell;
4900 };
4901 
4902 var Cell = function Cell(column, row) {
4903 
4904  this.table = column.table;
4905  this.column = column;
4906  this.row = row;
4907  this.element = null;
4908  this.value = null;
4909  this.oldValue = null;
4910  this.modules = {};
4911 
4912  this.height = null;
4913  this.width = null;
4914  this.minWidth = null;
4915 
4916  this.build();
4917 };
4918 
4920 
4921 //generate element
4922 Cell.prototype.build = function () {
4923  this.generateElement();
4924 
4925  this.setWidth();
4926 
4927  this._configureCell();
4928 
4929  this.setValueActual(this.column.getFieldValue(this.row.data));
4930 };
4931 
4932 Cell.prototype.generateElement = function () {
4933  this.element = document.createElement('div');
4934  this.element.className = "tabulator-cell";
4935  this.element.setAttribute("role", "gridcell");
4936  this.element = this.element;
4937 };
4938 
4939 Cell.prototype._configureCell = function () {
4940  var self = this,
4941  cellEvents = self.column.cellEvents,
4942  element = self.element,
4943  field = this.column.getField();
4944 
4945  //set text alignment
4946  element.style.textAlign = self.column.hozAlign;
4947 
4948  if (field) {
4949  element.setAttribute("tabulator-field", field);
4950  }
4951 
4952  //add class to cell if needed
4953  if (self.column.definition.cssClass) {
4954  var classNames = self.column.definition.cssClass.split(" ");
4955  classNames.forEach(function (className) {
4956  element.classList.add(className);
4957  });
4958  }
4959 
4960  //update tooltip on mouse enter
4961  if (this.table.options.tooltipGenerationMode === "hover") {
4962  element.addEventListener("mouseenter", function (e) {
4963  self._generateTooltip();
4964  });
4965  }
4966 
4967  self._bindClickEvents(cellEvents);
4968 
4969  self._bindTouchEvents(cellEvents);
4970 
4971  self._bindMouseEvents(cellEvents);
4972 
4973  if (self.column.modules.edit) {
4974  self.table.modules.edit.bindEditor(self);
4975  }
4976 
4977  if (self.column.definition.rowHandle && self.table.options.movableRows !== false && self.table.modExists("moveRow")) {
4978  self.table.modules.moveRow.initializeCell(self);
4979  }
4980 
4981  //hide cell if not visible
4982  if (!self.column.visible) {
4983  self.hide();
4984  }
4985 };
4986 
4987 Cell.prototype._bindClickEvents = function (cellEvents) {
4988  var self = this,
4989  element = self.element;
4990 
4991  //set event bindings
4992  if (cellEvents.cellClick || self.table.options.cellClick) {
4993  element.addEventListener("click", function (e) {
4994  var component = self.getComponent();
4995 
4996  if (cellEvents.cellClick) {
4997  cellEvents.cellClick.call(self.table, e, component);
4998  }
4999 
5000  if (self.table.options.cellClick) {
5001  self.table.options.cellClick.call(self.table, e, component);
5002  }
5003  });
5004  }
5005 
5006  if (cellEvents.cellDblClick || this.table.options.cellDblClick) {
5007  element.addEventListener("dblclick", function (e) {
5008  var component = self.getComponent();
5009 
5010  if (cellEvents.cellDblClick) {
5011  cellEvents.cellDblClick.call(self.table, e, component);
5012  }
5013 
5014  if (self.table.options.cellDblClick) {
5015  self.table.options.cellDblClick.call(self.table, e, component);
5016  }
5017  });
5018  } else {
5019  element.addEventListener("dblclick", function (e) {
5020  e.preventDefault();
5021 
5022  try {
5023  if (document.selection) {
5024  // IE
5025  var range = document.body.createTextRange();
5026  range.moveToElementText(self.element);
5027  range.select();
5028  } else if (window.getSelection) {
5029  var range = document.createRange();
5030  range.selectNode(self.element);
5031  window.getSelection().removeAllRanges();
5032  window.getSelection().addRange(range);
5033  }
5034  } catch (e) {}
5035  });
5036  }
5037 
5038  if (cellEvents.cellContext || this.table.options.cellContext) {
5039  element.addEventListener("contextmenu", function (e) {
5040  var component = self.getComponent();
5041 
5042  if (cellEvents.cellContext) {
5043  cellEvents.cellContext.call(self.table, e, component);
5044  }
5045 
5046  if (self.table.options.cellContext) {
5047  self.table.options.cellContext.call(self.table, e, component);
5048  }
5049  });
5050  }
5051 };
5052 
5053 Cell.prototype._bindMouseEvents = function (cellEvents) {
5054  var self = this,
5055  element = self.element;
5056 
5057  if (cellEvents.cellMouseEnter || self.table.options.cellMouseEnter) {
5058  element.addEventListener("mouseenter", function (e) {
5059  var component = self.getComponent();
5060 
5061  if (cellEvents.cellMouseEnter) {
5062  cellEvents.cellMouseEnter.call(self.table, e, component);
5063  }
5064 
5065  if (self.table.options.cellMouseEnter) {
5066  self.table.options.cellMouseEnter.call(self.table, e, component);
5067  }
5068  });
5069  }
5070 
5071  if (cellEvents.cellMouseLeave || self.table.options.cellMouseLeave) {
5072  element.addEventListener("mouseleave", function (e) {
5073  var component = self.getComponent();
5074 
5075  if (cellEvents.cellMouseLeave) {
5076  cellEvents.cellMouseLeave.call(self.table, e, component);
5077  }
5078 
5079  if (self.table.options.cellMouseLeave) {
5080  self.table.options.cellMouseLeave.call(self.table, e, component);
5081  }
5082  });
5083  }
5084 
5085  if (cellEvents.cellMouseOver || self.table.options.cellMouseOver) {
5086  element.addEventListener("mouseover", function (e) {
5087  var component = self.getComponent();
5088 
5089  if (cellEvents.cellMouseOver) {
5090  cellEvents.cellMouseOver.call(self.table, e, component);
5091  }
5092 
5093  if (self.table.options.cellMouseOver) {
5094  self.table.options.cellMouseOver.call(self.table, e, component);
5095  }
5096  });
5097  }
5098 
5099  if (cellEvents.cellMouseOut || self.table.options.cellMouseOut) {
5100  element.addEventListener("mouseout", function (e) {
5101  var component = self.getComponent();
5102 
5103  if (cellEvents.cellMouseOut) {
5104  cellEvents.cellMouseOut.call(self.table, e, component);
5105  }
5106 
5107  if (self.table.options.cellMouseOut) {
5108  self.table.options.cellMouseOut.call(self.table, e, component);
5109  }
5110  });
5111  }
5112 
5113  if (cellEvents.cellMouseMove || self.table.options.cellMouseMove) {
5114  element.addEventListener("mousemove", function (e) {
5115  var component = self.getComponent();
5116 
5117  if (cellEvents.cellMouseMove) {
5118  cellEvents.cellMouseMove.call(self.table, e, component);
5119  }
5120 
5121  if (self.table.options.cellMouseMove) {
5122  self.table.options.cellMouseMove.call(self.table, e, component);
5123  }
5124  });
5125  }
5126 };
5127 
5128 Cell.prototype._bindTouchEvents = function (cellEvents) {
5129  var self = this,
5130  element = self.element,
5131  dblTap,
5132  tapHold,
5133  tap;
5134 
5135  if (cellEvents.cellTap || this.table.options.cellTap) {
5136  tap = false;
5137 
5138  element.addEventListener("touchstart", function (e) {
5139  tap = true;
5140  }, { passive: true });
5141 
5142  element.addEventListener("touchend", function (e) {
5143  if (tap) {
5144  var component = self.getComponent();
5145 
5146  if (cellEvents.cellTap) {
5147  cellEvents.cellTap.call(self.table, e, component);
5148  }
5149 
5150  if (self.table.options.cellTap) {
5151  self.table.options.cellTap.call(self.table, e, component);
5152  }
5153  }
5154 
5155  tap = false;
5156  });
5157  }
5158 
5159  if (cellEvents.cellDblTap || this.table.options.cellDblTap) {
5160  dblTap = null;
5161 
5162  element.addEventListener("touchend", function (e) {
5163 
5164  if (dblTap) {
5165  clearTimeout(dblTap);
5166  dblTap = null;
5167 
5168  var component = self.getComponent();
5169 
5170  if (cellEvents.cellDblTap) {
5171  cellEvents.cellDblTap.call(self.table, e, component);
5172  }
5173 
5174  if (self.table.options.cellDblTap) {
5175  self.table.options.cellDblTap.call(self.table, e, component);
5176  }
5177  } else {
5178 
5179  dblTap = setTimeout(function () {
5180  clearTimeout(dblTap);
5181  dblTap = null;
5182  }, 300);
5183  }
5184  });
5185  }
5186 
5187  if (cellEvents.cellTapHold || this.table.options.cellTapHold) {
5188  tapHold = null;
5189 
5190  element.addEventListener("touchstart", function (e) {
5191  clearTimeout(tapHold);
5192 
5193  tapHold = setTimeout(function () {
5194  clearTimeout(tapHold);
5195  tapHold = null;
5196  tap = false;
5197  var component = self.getComponent();
5198 
5199  if (cellEvents.cellTapHold) {
5200  cellEvents.cellTapHold.call(self.table, e, component);
5201  }
5202 
5203  if (self.table.options.cellTapHold) {
5204  self.table.options.cellTapHold.call(self.table, e, component);
5205  }
5206  }, 1000);
5207  }, { passive: true });
5208 
5209  element.addEventListener("touchend", function (e) {
5210  clearTimeout(tapHold);
5211  tapHold = null;
5212  });
5213  }
5214 };
5215 
5216 //generate cell contents
5217 Cell.prototype._generateContents = function () {
5218  var val;
5219 
5220  if (this.table.modExists("format")) {
5221  val = this.table.modules.format.formatValue(this);
5222  } else {
5223  val = this.element.innerHTML = this.value;
5224  }
5225 
5226  switch (typeof val === 'undefined' ? 'undefined' : _typeof(val)) {
5227  case "object":
5228  if (val instanceof Node) {
5229 
5230  //clear previous cell contents
5231  while (this.element.firstChild) {
5232  this.element.removeChild(this.element.firstChild);
5233  }this.element.appendChild(val);
5234  } else {
5235  this.element.innerHTML = "";
5236 
5237  if (val != null) {
5238  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);
5239  }
5240  }
5241  break;
5242  case "undefined":
5243  case "null":
5244  this.element.innerHTML = "";
5245  break;
5246  default:
5247  this.element.innerHTML = val;
5248  }
5249 };
5250 
5251 Cell.prototype.cellRendered = function () {
5252  if (this.table.modExists("format") && this.table.modules.format.cellRendered) {
5253  this.table.modules.format.cellRendered(this);
5254  }
5255 };
5256 
5257 //generate tooltip text
5258 Cell.prototype._generateTooltip = function () {
5259  var tooltip = this.column.tooltip;
5260 
5261  if (tooltip) {
5262  if (tooltip === true) {
5263  tooltip = this.value;
5264  } else if (typeof tooltip == "function") {
5265  tooltip = tooltip(this.getComponent());
5266 
5267  if (tooltip === false) {
5268  tooltip = "";
5269  }
5270  }
5271 
5272  if (typeof tooltip === "undefined") {
5273  tooltip = "";
5274  }
5275 
5276  this.element.setAttribute("title", tooltip);
5277  } else {
5278  this.element.setAttribute("title", "");
5279  }
5280 };
5281 
5283 Cell.prototype.getElement = function () {
5284  return this.element;
5285 };
5286 
5287 Cell.prototype.getValue = function () {
5288  return this.value;
5289 };
5290 
5291 Cell.prototype.getOldValue = function () {
5292  return this.oldValue;
5293 };
5294 
5296 
5297 Cell.prototype.setValue = function (value, mutate) {
5298 
5299  var changed = this.setValueProcessData(value, mutate),
5300  component;
5301 
5302  if (changed) {
5303  if (this.table.options.history && this.table.modExists("history")) {
5304  this.table.modules.history.action("cellEdit", this, { oldValue: this.oldValue, newValue: this.value });
5305  }
5306 
5307  component = this.getComponent();
5308 
5309  if (this.column.cellEvents.cellEdited) {
5310  this.column.cellEvents.cellEdited.call(this.table, component);
5311  }
5312 
5313  this.table.options.cellEdited.call(this.table, component);
5314 
5315  this.table.options.dataEdited.call(this.table, this.table.rowManager.getData());
5316  }
5317 };
5318 
5319 Cell.prototype.setValueProcessData = function (value, mutate) {
5320  var changed = false;
5321 
5322  if (this.value != value) {
5323 
5324  changed = true;
5325 
5326  if (mutate) {
5327  if (this.column.modules.mutate) {
5328  value = this.table.modules.mutator.transformCell(this, value);
5329  }
5330  }
5331  }
5332 
5333  this.setValueActual(value);
5334 
5335  if (changed && this.table.modExists("columnCalcs")) {
5336  if (this.column.definition.topCalc || this.column.definition.bottomCalc) {
5337  if (this.table.options.groupBy && this.table.modExists("groupRows")) {
5338 
5339  if (this.table.options.columnCalcs == "table" || this.table.options.columnCalcs == "both") {
5340  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
5341  }
5342 
5343  if (this.table.options.columnCalcs != "table") {
5344  this.table.modules.columnCalcs.recalcRowGroup(this.row);
5345  }
5346  } else {
5347  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
5348  }
5349  }
5350  }
5351 
5352  return changed;
5353 };
5354 
5355 Cell.prototype.setValueActual = function (value) {
5356  this.oldValue = this.value;
5357 
5358  this.value = value;
5359 
5360  if (this.table.options.reactiveData && this.table.modExists("reactiveData")) {
5361  this.table.modules.reactiveData.block();
5362  }
5363 
5364  this.column.setFieldValue(this.row.data, value);
5365 
5366  if (this.table.options.reactiveData && this.table.modExists("reactiveData")) {
5367  this.table.modules.reactiveData.unblock();
5368  }
5369 
5370  this._generateContents();
5371  this._generateTooltip();
5372 
5373  //set resizable handles
5374  if (this.table.options.resizableColumns && this.table.modExists("resizeColumns")) {
5375  this.table.modules.resizeColumns.initializeColumn("cell", this.column, this.element);
5376  }
5377 
5378  //handle frozen cells
5379  if (this.table.modExists("frozenColumns")) {
5380  this.table.modules.frozenColumns.layoutElement(this.element, this.column);
5381  }
5382 };
5383 
5384 Cell.prototype.setWidth = function () {
5385  this.width = this.column.width;
5386  this.element.style.width = this.column.widthStyled;
5387 };
5388 
5389 Cell.prototype.clearWidth = function () {
5390  this.width = "";
5391  this.element.style.width = "";
5392 };
5393 
5394 Cell.prototype.getWidth = function () {
5395  return this.width || this.element.offsetWidth;
5396 };
5397 
5398 Cell.prototype.setMinWidth = function () {
5399  this.minWidth = this.column.minWidth;
5400  this.element.style.minWidth = this.column.minWidthStyled;
5401 };
5402 
5403 Cell.prototype.checkHeight = function () {
5404  // var height = this.element.css("height");
5405  this.row.reinitializeHeight();
5406 };
5407 
5408 Cell.prototype.clearHeight = function () {
5409  this.element.style.height = "";
5410  this.height = null;
5411 };
5412 
5413 Cell.prototype.setHeight = function () {
5414  this.height = this.row.height;
5415  this.element.style.height = this.row.heightStyled;
5416 };
5417 
5418 Cell.prototype.getHeight = function () {
5419  return this.height || this.element.offsetHeight;
5420 };
5421 
5422 Cell.prototype.show = function () {
5423  this.element.style.display = "";
5424 };
5425 
5426 Cell.prototype.hide = function () {
5427  this.element.style.display = "none";
5428 };
5429 
5430 Cell.prototype.edit = function (force) {
5431  if (this.table.modExists("edit", true)) {
5432  return this.table.modules.edit.editCell(this, force);
5433  }
5434 };
5435 
5436 Cell.prototype.cancelEdit = function () {
5437  if (this.table.modExists("edit", true)) {
5438  var editing = this.table.modules.edit.getCurrentCell();
5439 
5440  if (editing && editing._getSelf() === this) {
5441  this.table.modules.edit.cancelEdit();
5442  } else {
5443  console.warn("Cancel Editor Error - This cell is not currently being edited ");
5444  }
5445  }
5446 };
5447 
5448 Cell.prototype.delete = function () {
5449  if (!this.table.rowManager.redrawBlock) {
5450  this.element.parentNode.removeChild(this.element);
5451  }
5452  this.element = false;
5453  this.column.deleteCell(this);
5454  this.row.deleteCell(this);
5455  this.calcs = {};
5456 };
5457 
5459 
5460 Cell.prototype.nav = function () {
5461 
5462  var self = this,
5463  nextCell = false,
5464  index = this.row.getCellIndex(this);
5465 
5466  return {
5467  next: function next() {
5468  var nextCell = this.right(),
5469  nextRow;
5470 
5471  if (!nextCell) {
5472  nextRow = self.table.rowManager.nextDisplayRow(self.row, true);
5473 
5474  if (nextRow) {
5475  nextCell = nextRow.findNextEditableCell(-1);
5476 
5477  if (nextCell) {
5478  nextCell.edit();
5479  return true;
5480  }
5481  }
5482  } else {
5483  return true;
5484  }
5485 
5486  return false;
5487  },
5488  prev: function prev() {
5489  var nextCell = this.left(),
5490  prevRow;
5491 
5492  if (!nextCell) {
5493  prevRow = self.table.rowManager.prevDisplayRow(self.row, true);
5494 
5495  if (prevRow) {
5496  nextCell = prevRow.findPrevEditableCell(prevRow.cells.length);
5497 
5498  if (nextCell) {
5499  nextCell.edit();
5500  return true;
5501  }
5502  }
5503  } else {
5504  return true;
5505  }
5506 
5507  return false;
5508  },
5509  left: function left() {
5510 
5511  nextCell = self.row.findPrevEditableCell(index);
5512 
5513  if (nextCell) {
5514  nextCell.edit();
5515  return true;
5516  } else {
5517  return false;
5518  }
5519  },
5520  right: function right() {
5521  nextCell = self.row.findNextEditableCell(index);
5522 
5523  if (nextCell) {
5524  nextCell.edit();
5525  return true;
5526  } else {
5527  return false;
5528  }
5529  },
5530  up: function up() {
5531  var nextRow = self.table.rowManager.prevDisplayRow(self.row, true);
5532 
5533  if (nextRow) {
5534  nextRow.cells[index].edit();
5535  }
5536  },
5537  down: function down() {
5538  var nextRow = self.table.rowManager.nextDisplayRow(self.row, true);
5539 
5540  if (nextRow) {
5541  nextRow.cells[index].edit();
5542  }
5543  }
5544 
5545  };
5546 };
5547 
5548 Cell.prototype.getIndex = function () {
5549  this.row.getCellIndex(this);
5550 };
5551 
5553 Cell.prototype.getComponent = function () {
5554  return new CellComponent(this);
5555 };
5556 var FooterManager = function FooterManager(table) {
5557  this.table = table;
5558  this.active = false;
5559  this.element = this.createElement(); //containing element
5560  this.external = false;
5561  this.links = [];
5562 
5563  this._initialize();
5564 };
5565 
5566 FooterManager.prototype.createElement = function () {
5567  var el = document.createElement("div");
5568 
5569  el.classList.add("tabulator-footer");
5570 
5571  return el;
5572 };
5573 
5574 FooterManager.prototype._initialize = function (element) {
5575  if (this.table.options.footerElement) {
5576 
5577  switch (_typeof(this.table.options.footerElement)) {
5578  case "string":
5579 
5580  if (this.table.options.footerElement[0] === "<") {
5581  this.element.innerHTML = this.table.options.footerElement;
5582  } else {
5583  this.external = true;
5584  this.element = document.querySelector(this.table.options.footerElement);
5585  }
5586  break;
5587  default:
5588  this.element = this.table.options.footerElement;
5589  break;
5590  }
5591  }
5592 };
5593 
5594 FooterManager.prototype.getElement = function () {
5595  return this.element;
5596 };
5597 
5598 FooterManager.prototype.append = function (element, parent) {
5599  this.activate(parent);
5600 
5601  this.element.appendChild(element);
5602  this.table.rowManager.adjustTableSize();
5603 };
5604 
5605 FooterManager.prototype.prepend = function (element, parent) {
5606  this.activate(parent);
5607 
5608  this.element.insertBefore(element, this.element.firstChild);
5609  this.table.rowManager.adjustTableSize();
5610 };
5611 
5612 FooterManager.prototype.remove = function (element) {
5613  element.parentNode.removeChild(element);
5614  this.deactivate();
5615 };
5616 
5617 FooterManager.prototype.deactivate = function (force) {
5618  if (!this.element.firstChild || force) {
5619  if (!this.external) {
5620  this.element.parentNode.removeChild(this.element);
5621  }
5622  this.active = false;
5623  }
5624 
5625  // this.table.rowManager.adjustTableSize();
5626 };
5627 
5628 FooterManager.prototype.activate = function (parent) {
5629  if (!this.active) {
5630  this.active = true;
5631  if (!this.external) {
5632  this.table.element.appendChild(this.getElement());
5633  this.table.element.style.display = '';
5634  }
5635  }
5636 
5637  if (parent) {
5638  this.links.push(parent);
5639  }
5640 };
5641 
5642 FooterManager.prototype.redraw = function () {
5643  this.links.forEach(function (link) {
5644  link.footerRedraw();
5645  });
5646 };
5647 
5648 var Tabulator = function Tabulator(element, options) {
5649 
5650  this.options = {};
5651 
5652  this.columnManager = null; // hold Column Manager
5653  this.rowManager = null; //hold Row Manager
5654  this.footerManager = null; //holder Footer Manager
5655  this.browser = ""; //hold current browser type
5656  this.browserSlow = false; //handle reduced functionality for slower browsers
5657  this.browserMobile = false; //check if running on moble, prevent resize cancelling edit on keyboard appearence
5658 
5659  this.modules = {}; //hold all modules bound to this table
5660 
5661  this.initializeElement(element);
5662  this.initializeOptions(options || {});
5663  this._create();
5664 
5665  Tabulator.prototype.comms.register(this); //register table for inderdevice communication
5666 };
5667 
5668 //default setup options
5669 Tabulator.prototype.defaultOptions = {
5670 
5671  height: false, //height of tabulator
5672 
5673  layout: "fitData",
5674  layoutColumnsOnNewData: false, //update column widths on setData
5675 
5676  columnMinWidth: 40, //minimum global width for a column
5677  columnHeaderVertAlign: "top", //vertical alignment of column headers
5678  columnVertAlign: false, // DEPRECATED - Left to allow warning
5679 
5680  resizableColumns: true, //resizable columns
5681  resizableRows: false, //resizable rows
5682  autoResize: true, //auto resize table
5683 
5684  columns: [], //store for colum header info
5685 
5686  data: [], //default starting data
5687 
5688  autoColumns: false, //build columns from data row structure
5689 
5690  reactiveData: false, //enable data reactivity
5691 
5692  nestedFieldSeparator: ".", //seperatpr for nested data
5693 
5694  tooltips: false, //Tool tip value
5695  tooltipsHeader: false, //Tool tip for headers
5696  tooltipGenerationMode: "load", //when to generate tooltips
5697 
5698  initialSort: false, //initial sorting criteria
5699  initialFilter: false, //initial filtering criteria
5700  initialHeaderFilter: false, //initial header filtering criteria
5701 
5702  columnHeaderSortMulti: true, //multiple or single column sorting
5703 
5704  sortOrderReverse: false, //reverse internal sort ordering
5705 
5706  headerSort: true, //set default global header sort
5707  headerSortTristate: false, //set default tristate header sorting
5708 
5709  footerElement: false, //hold footer element
5710 
5711  index: "id", //filed for row index
5712 
5713  keybindings: [], //array for keybindings
5714 
5715  tabEndNewRow: false, //create new row when tab to end of table
5716 
5717  invalidOptionWarnings: true, //allow toggling of invalid option warnings
5718 
5719  clipboard: false, //enable clipboard
5720  clipboardCopyStyled: true, //formatted table data
5721  clipboardCopySelector: "active", //method of chosing which data is coppied to the clipboard
5722  clipboardCopyFormatter: "table", //convert data to a clipboard string
5723  clipboardPasteParser: "table", //convert pasted clipboard data to rows
5724  clipboardPasteAction: "insert", //how to insert pasted data into the table
5725  clipboardCopyConfig: false, //clipboard config
5726 
5727  clipboardCopied: function clipboardCopied() {}, //data has been copied to the clipboard
5728  clipboardPasted: function clipboardPasted() {}, //data has been pasted into the table
5729  clipboardPasteError: function clipboardPasteError() {}, //data has not successfully been pasted into the table
5730 
5731  downloadDataFormatter: false, //function to manipulate table data before it is downloaded
5732  downloadReady: function downloadReady(data, blob) {
5733  return blob;
5734  }, //function to manipulate download data
5735  downloadComplete: false, //function to manipulate download data
5736  downloadConfig: false, //download config
5737 
5738  dataTree: false, //enable data tree
5739  dataTreeElementColumn: false,
5740  dataTreeBranchElement: true, //show data tree branch element
5741  dataTreeChildIndent: 9, //data tree child indent in px
5742  dataTreeChildField: "_children", //data tre column field to look for child rows
5743  dataTreeCollapseElement: false, //data tree row collapse element
5744  dataTreeExpandElement: false, //data tree row expand element
5745  dataTreeStartExpanded: false,
5746  dataTreeRowExpanded: function dataTreeRowExpanded() {}, //row has been expanded
5747  dataTreeRowCollapsed: function dataTreeRowCollapsed() {}, //row has been collapsed
5748 
5749  printAsHtml: false, //enable print as html
5750  printFormatter: false, //printing page formatter
5751  printHeader: false, //page header contents
5752  printFooter: false, //page footer contents
5753  printCopyStyle: true, //enable print as html styling
5754  printVisibleRows: true, //restrict print to visible rows only
5755  printConfig: {}, //print config options
5756 
5757  addRowPos: "bottom", //position to insert blank rows, top|bottom
5758 
5759  selectable: "highlight", //highlight rows on hover
5760  selectableRangeMode: "drag", //highlight rows on hover
5761  selectableRollingSelection: true, //roll selection once maximum number of selectable rows is reached
5762  selectablePersistence: true, // maintain selection when table view is updated
5763  selectableCheck: function selectableCheck(data, row) {
5764  return true;
5765  }, //check wheather row is selectable
5766 
5767  headerFilterPlaceholder: false, //placeholder text to display in header filters
5768 
5769  headerVisible: true, //hide header
5770 
5771  history: false, //enable edit history
5772 
5773  locale: false, //current system language
5774  langs: {},
5775 
5776  virtualDom: true, //enable DOM virtualization
5777  virtualDomBuffer: 0, // set virtual DOM buffer size
5778 
5779  persistentLayout: false, //DEPRICATED - REMOVE in 5.0
5780  persistentSort: false, //DEPRICATED - REMOVE in 5.0
5781  persistentFilter: false, //DEPRICATED - REMOVE in 5.0
5782  persistenceID: "", //key for persistent storage
5783  persistenceMode: true, //mode for storing persistence information
5784  persistenceReaderFunc: false, //function for handling persistence data reading
5785  persistenceWriterFunc: false, //function for handling persistence data writing
5786 
5787  persistence: false,
5788 
5789  responsiveLayout: false, //responsive layout flags
5790  responsiveLayoutCollapseStartOpen: true, //start showing collapsed data
5791  responsiveLayoutCollapseUseFormatters: true, //responsive layout collapse formatter
5792  responsiveLayoutCollapseFormatter: false, //responsive layout collapse formatter
5793 
5794  pagination: false, //set pagination type
5795  paginationSize: false, //set number of rows to a page
5796  paginationInitialPage: 1, //initail page to show on load
5797  paginationButtonCount: 5, // set count of page button
5798  paginationSizeSelector: false, //add pagination size selector element
5799  paginationElement: false, //element to hold pagination numbers
5800  paginationDataSent: {}, //pagination data sent to the server
5801  paginationDataReceived: {}, //pagination data received from the server
5802  paginationAddRow: "page", //add rows on table or page
5803 
5804  ajaxURL: false, //url for ajax loading
5805  ajaxURLGenerator: false,
5806  ajaxParams: {}, //params for ajax loading
5807  ajaxConfig: "get", //ajax request type
5808  ajaxContentType: "form", //ajax request type
5809  ajaxRequestFunc: false, //promise function
5810  ajaxLoader: true, //show loader
5811  ajaxLoaderLoading: false, //loader element
5812  ajaxLoaderError: false, //loader element
5813  ajaxFiltering: false,
5814  ajaxSorting: false,
5815  ajaxProgressiveLoad: false, //progressive loading
5816  ajaxProgressiveLoadDelay: 0, //delay between requests
5817  ajaxProgressiveLoadScrollMargin: 0, //margin before scroll begins
5818 
5819  groupBy: false, //enable table grouping and set field to group by
5820  groupStartOpen: true, //starting state of group
5821  groupValues: false,
5822 
5823  groupHeader: false, //header generation function
5824 
5825  htmlOutputConfig: false, //html outypu config
5826 
5827  movableColumns: false, //enable movable columns
5828 
5829  movableRows: false, //enable movable rows
5830  movableRowsConnectedTables: false, //tables for movable rows to be connected to
5831  movableRowsSender: false,
5832  movableRowsReceiver: "insert",
5833  movableRowsSendingStart: function movableRowsSendingStart() {},
5834  movableRowsSent: function movableRowsSent() {},
5835  movableRowsSentFailed: function movableRowsSentFailed() {},
5836  movableRowsSendingStop: function movableRowsSendingStop() {},
5837  movableRowsReceivingStart: function movableRowsReceivingStart() {},
5838  movableRowsReceived: function movableRowsReceived() {},
5839  movableRowsReceivedFailed: function movableRowsReceivedFailed() {},
5840  movableRowsReceivingStop: function movableRowsReceivingStop() {},
5841 
5842  scrollToRowPosition: "top",
5843  scrollToRowIfVisible: true,
5844 
5845  scrollToColumnPosition: "left",
5846  scrollToColumnIfVisible: true,
5847 
5848  rowFormatter: false,
5849 
5850  placeholder: false,
5851 
5852  //table building callbacks
5853  tableBuilding: function tableBuilding() {},
5854  tableBuilt: function tableBuilt() {},
5855 
5856  //render callbacks
5857  renderStarted: function renderStarted() {},
5858  renderComplete: function renderComplete() {},
5859 
5860  //row callbacks
5861  rowClick: false,
5862  rowDblClick: false,
5863  rowContext: false,
5864  rowTap: false,
5865  rowDblTap: false,
5866  rowTapHold: false,
5867  rowMouseEnter: false,
5868  rowMouseLeave: false,
5869  rowMouseOver: false,
5870  rowMouseOut: false,
5871  rowMouseMove: false,
5872  rowAdded: function rowAdded() {},
5873  rowDeleted: function rowDeleted() {},
5874  rowMoved: function rowMoved() {},
5875  rowUpdated: function rowUpdated() {},
5876  rowSelectionChanged: function rowSelectionChanged() {},
5877  rowSelected: function rowSelected() {},
5878  rowDeselected: function rowDeselected() {},
5879  rowResized: function rowResized() {},
5880 
5881  //cell callbacks
5882  //row callbacks
5883  cellClick: false,
5884  cellDblClick: false,
5885  cellContext: false,
5886  cellTap: false,
5887  cellDblTap: false,
5888  cellTapHold: false,
5889  cellMouseEnter: false,
5890  cellMouseLeave: false,
5891  cellMouseOver: false,
5892  cellMouseOut: false,
5893  cellMouseMove: false,
5894  cellEditing: function cellEditing() {},
5895  cellEdited: function cellEdited() {},
5896  cellEditCancelled: function cellEditCancelled() {},
5897 
5898  //column callbacks
5899  columnMoved: false,
5900  columnResized: function columnResized() {},
5901  columnTitleChanged: function columnTitleChanged() {},
5902  columnVisibilityChanged: function columnVisibilityChanged() {},
5903 
5904  //HTML iport callbacks
5905  htmlImporting: function htmlImporting() {},
5906  htmlImported: function htmlImported() {},
5907 
5908  //data callbacks
5909  dataLoading: function dataLoading() {},
5910  dataLoaded: function dataLoaded() {},
5911  dataEdited: function dataEdited() {},
5912 
5913  //ajax callbacks
5914  ajaxRequesting: function ajaxRequesting() {},
5915  ajaxResponse: false,
5916  ajaxError: function ajaxError() {},
5917 
5918  //filtering callbacks
5919  dataFiltering: false,
5920  dataFiltered: false,
5921 
5922  //sorting callbacks
5923  dataSorting: function dataSorting() {},
5924  dataSorted: function dataSorted() {},
5925 
5926  //grouping callbacks
5927  groupToggleElement: "arrow",
5928  groupClosedShowCalcs: false,
5929  dataGrouping: function dataGrouping() {},
5930  dataGrouped: false,
5931  groupVisibilityChanged: function groupVisibilityChanged() {},
5932  groupClick: false,
5933  groupDblClick: false,
5934  groupContext: false,
5935  groupTap: false,
5936  groupDblTap: false,
5937  groupTapHold: false,
5938 
5939  columnCalcs: true,
5940 
5941  //pagination callbacks
5942  pageLoaded: function pageLoaded() {},
5943 
5944  //localization callbacks
5945  localized: function localized() {},
5946 
5947  //validation has failed
5948  validationFailed: function validationFailed() {},
5949 
5950  //history callbacks
5951  historyUndo: function historyUndo() {},
5952  historyRedo: function historyRedo() {},
5953 
5954  //scroll callbacks
5955  scrollHorizontal: function scrollHorizontal() {},
5956  scrollVertical: function scrollVertical() {}
5957 
5958 };
5959 
5960 Tabulator.prototype.initializeOptions = function (options) {
5961 
5962  //warn user if option is not available
5963  if (options.invalidOptionWarnings !== false) {
5964  for (var key in options) {
5965  if (typeof this.defaultOptions[key] === "undefined") {
5966  console.warn("Invalid table constructor option:", key);
5967  }
5968  }
5969  }
5970 
5971  //assign options to table
5972  for (var key in this.defaultOptions) {
5973  if (key in options) {
5974  this.options[key] = options[key];
5975  } else {
5976  if (Array.isArray(this.defaultOptions[key])) {
5977  this.options[key] = [];
5978  } else if (_typeof(this.defaultOptions[key]) === "object") {
5979  this.options[key] = {};
5980  } else {
5981  this.options[key] = this.defaultOptions[key];
5982  }
5983  }
5984  }
5985 };
5986 
5987 Tabulator.prototype.initializeElement = function (element) {
5988 
5989  if (typeof HTMLElement !== "undefined" && element instanceof HTMLElement) {
5990  this.element = element;
5991  return true;
5992  } else if (typeof element === "string") {
5993  this.element = document.querySelector(element);
5994 
5995  if (this.element) {
5996  return true;
5997  } else {
5998  console.error("Tabulator Creation Error - no element found matching selector: ", element);
5999  return false;
6000  }
6001  } else {
6002  console.error("Tabulator Creation Error - Invalid element provided:", element);
6003  return false;
6004  }
6005 };
6006 
6007 //convert depricated functionality to new functions
6008 Tabulator.prototype._mapDepricatedFunctionality = function () {
6009 
6010  //map depricated persistance setup options
6011  if (this.options.persistentLayout || this.options.persistentSort || this.options.persistentFilter) {
6012  if (!this.options.persistence) {
6013  this.options.persistence = {};
6014  }
6015  }
6016 
6017  if (this.options.persistentLayout) {
6018  console.warn("persistentLayout option is deprecated, you should now use the persistence option");
6019 
6020  if (this.options.persistence !== true && typeof this.options.persistence.columns === "undefined") {
6021  this.options.persistence.columns = true;
6022  }
6023  }
6024 
6025  if (this.options.persistentSort) {
6026  console.warn("persistentSort option is deprecated, you should now use the persistence option");
6027 
6028  if (this.options.persistence !== true && typeof this.options.persistence.sort === "undefined") {
6029  this.options.persistence.sort = true;
6030  }
6031  }
6032 
6033  if (this.options.persistentFilter) {
6034  console.warn("persistentFilter option is deprecated, you should now use the persistence option");
6035 
6036  if (this.options.persistence !== true && typeof this.options.persistence.filter === "undefined") {
6037  this.options.persistence.filter = true;
6038  }
6039  }
6040 
6041  if (this.options.columnVertAlign) {
6042  console.warn("columnVertAlign option is deprecated, you should now use the columnHeaderVertAlign option");
6043 
6044  this.options.columnHeaderVertAlign = this.options.columnVertAlign;
6045  }
6046 };
6047 
6048 Tabulator.prototype._clearSelection = function () {
6049 
6050  this.element.classList.add("tabulator-block-select");
6051 
6052  if (window.getSelection) {
6053  if (window.getSelection().empty) {
6054  // Chrome
6055  window.getSelection().empty();
6056  } else if (window.getSelection().removeAllRanges) {
6057  // Firefox
6058  window.getSelection().removeAllRanges();
6059  }
6060  } else if (document.selection) {
6061  // IE?
6062  document.selection.empty();
6063  }
6064 
6065  this.element.classList.remove("tabulator-block-select");
6066 };
6067 
6068 //concreate table
6069 Tabulator.prototype._create = function () {
6070  this._clearObjectPointers();
6071 
6072  this._mapDepricatedFunctionality();
6073 
6074  this.bindModules();
6075 
6076  if (this.element.tagName === "TABLE") {
6077  if (this.modExists("htmlTableImport", true)) {
6078  this.modules.htmlTableImport.parseTable();
6079  }
6080  }
6081 
6082  this.columnManager = new ColumnManager(this);
6083  this.rowManager = new RowManager(this);
6084  this.footerManager = new FooterManager(this);
6085 
6086  this.columnManager.setRowManager(this.rowManager);
6087  this.rowManager.setColumnManager(this.columnManager);
6088 
6089  this._buildElement();
6090 
6091  this._loadInitialData();
6092 };
6093 
6094 //clear pointers to objects in default config object
6095 Tabulator.prototype._clearObjectPointers = function () {
6096  this.options.columns = this.options.columns.slice(0);
6097 
6098  if (!this.options.reactiveData) {
6099  this.options.data = this.options.data.slice(0);
6100  }
6101 };
6102 
6103 //build tabulator element
6104 Tabulator.prototype._buildElement = function () {
6105  var _this15 = this;
6106 
6107  var element = this.element,
6108  mod = this.modules,
6109  options = this.options;
6110 
6111  options.tableBuilding.call(this);
6112 
6113  element.classList.add("tabulator");
6114  element.setAttribute("role", "grid");
6115 
6116  //empty element
6117  while (element.firstChild) {
6118  element.removeChild(element.firstChild);
6119  } //set table height
6120  if (options.height) {
6121  options.height = isNaN(options.height) ? options.height : options.height + "px";
6122  element.style.height = options.height;
6123  }
6124 
6125  this.columnManager.initialize();
6126  this.rowManager.initialize();
6127 
6128  this._detectBrowser();
6129 
6130  if (this.modExists("layout", true)) {
6131  mod.layout.initialize(options.layout);
6132  }
6133 
6134  //set localization
6135  if (options.headerFilterPlaceholder !== false) {
6136  mod.localize.setHeaderFilterPlaceholder(options.headerFilterPlaceholder);
6137  }
6138 
6139  for (var locale in options.langs) {
6140  mod.localize.installLang(locale, options.langs[locale]);
6141  }
6142 
6143  mod.localize.setLocale(options.locale);
6144 
6145  //configure placeholder element
6146  if (typeof options.placeholder == "string") {
6147 
6148  var el = document.createElement("div");
6149  el.classList.add("tabulator-placeholder");
6150 
6151  var span = document.createElement("span");
6152  span.innerHTML = options.placeholder;
6153 
6154  el.appendChild(span);
6155 
6156  options.placeholder = el;
6157  }
6158 
6159  //build table elements
6160  element.appendChild(this.columnManager.getElement());
6161  element.appendChild(this.rowManager.getElement());
6162 
6163  if (options.footerElement) {
6164  this.footerManager.activate();
6165  }
6166 
6167  if (options.persistence && this.modExists("persistence", true)) {
6168  mod.persistence.initialize();
6169  }
6170 
6171  if (options.persistence && this.modExists("persistence", true) && mod.persistence.config.columns) {
6172  options.columns = mod.persistence.load("columns", options.columns);
6173  }
6174 
6175  if (options.movableRows && this.modExists("moveRow")) {
6176  mod.moveRow.initialize();
6177  }
6178 
6179  if (options.autoColumns && this.options.data) {
6180  this.columnManager.generateColumnsFromRowData(this.options.data);
6181  }
6182 
6183  if (this.modExists("columnCalcs")) {
6184  mod.columnCalcs.initialize();
6185  }
6186 
6187  this.columnManager.setColumns(options.columns);
6188 
6189  if (options.dataTree && this.modExists("dataTree", true)) {
6190  mod.dataTree.initialize();
6191  }
6192 
6193  if (this.modExists("frozenRows")) {
6194  this.modules.frozenRows.initialize();
6195  }
6196 
6197  if ((options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort || options.initialSort) && this.modExists("sort", true)) {
6198  var sorters = [];
6199 
6200  if (options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort) {
6201  sorters = mod.persistence.load("sort");
6202 
6203  if (sorters === false && options.initialSort) {
6204  sorters = options.initialSort;
6205  }
6206  } else if (options.initialSort) {
6207  sorters = options.initialSort;
6208  }
6209 
6210  mod.sort.setSort(sorters);
6211  }
6212 
6213  if ((options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter || options.initialFilter) && this.modExists("filter", true)) {
6214  var filters = [];
6215 
6216  if (options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter) {
6217  filters = mod.persistence.load("filter");
6218 
6219  if (filters === false && options.initialFilter) {
6220  filters = options.initialFilter;
6221  }
6222  } else if (options.initialFilter) {
6223  filters = options.initialFilter;
6224  }
6225 
6226  mod.filter.setFilter(filters);
6227  }
6228 
6229  if (options.initialHeaderFilter && this.modExists("filter", true)) {
6230  options.initialHeaderFilter.forEach(function (item) {
6231 
6232  var column = _this15.columnManager.findColumn(item.field);
6233 
6234  if (column) {
6235  mod.filter.setHeaderFilterValue(column, item.value);
6236  } else {
6237  console.warn("Column Filter Error - No matching column found:", item.field);
6238  return false;
6239  }
6240  });
6241  }
6242 
6243  if (this.modExists("ajax")) {
6244  mod.ajax.initialize();
6245  }
6246 
6247  if (options.pagination && this.modExists("page", true)) {
6248  mod.page.initialize();
6249  }
6250 
6251  if (options.groupBy && this.modExists("groupRows", true)) {
6252  mod.groupRows.initialize();
6253  }
6254 
6255  if (this.modExists("keybindings")) {
6256  mod.keybindings.initialize();
6257  }
6258 
6259  if (this.modExists("selectRow")) {
6260  mod.selectRow.clearSelectionData(true);
6261  }
6262 
6263  if (options.autoResize && this.modExists("resizeTable")) {
6264  mod.resizeTable.initialize();
6265  }
6266 
6267  if (this.modExists("clipboard")) {
6268  mod.clipboard.initialize();
6269  }
6270 
6271  if (options.printAsHtml && this.modExists("print")) {
6272  mod.print.initialize();
6273  }
6274 
6275  options.tableBuilt.call(this);
6276 };
6277 
6278 Tabulator.prototype._loadInitialData = function () {
6279  var self = this;
6280 
6281  if (self.options.pagination && self.modExists("page")) {
6282  self.modules.page.reset(true);
6283 
6284  if (self.options.pagination == "local") {
6285  if (self.options.data.length) {
6286  self.rowManager.setData(self.options.data);
6287  } else {
6288  if ((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")) {
6289  self.modules.ajax.loadData().then(function () {}).catch(function () {
6290  if (self.options.paginationInitialPage) {
6291  self.modules.page.setPage(self.options.paginationInitialPage);
6292  }
6293  });
6294 
6295  return;
6296  } else {
6297  self.rowManager.setData(self.options.data);
6298  }
6299  }
6300 
6301  if (self.options.paginationInitialPage) {
6302  self.modules.page.setPage(self.options.paginationInitialPage);
6303  }
6304  } else {
6305  if (self.options.ajaxURL) {
6306  self.modules.page.setPage(self.options.paginationInitialPage).then(function () {}).catch(function () {});
6307  } else {
6308  self.rowManager.setData([]);
6309  }
6310  }
6311  } else {
6312  if (self.options.data.length) {
6313  self.rowManager.setData(self.options.data);
6314  } else {
6315  if ((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")) {
6316  self.modules.ajax.loadData().then(function () {}).catch(function () {});
6317  } else {
6318  self.rowManager.setData(self.options.data);
6319  }
6320  }
6321  }
6322 };
6323 
6324 //deconstructor
6325 Tabulator.prototype.destroy = function () {
6326  var element = this.element;
6327 
6328  Tabulator.prototype.comms.deregister(this); //deregister table from inderdevice communication
6329 
6330  if (this.options.reactiveData && this.modExists("reactiveData", true)) {
6331  this.modules.reactiveData.unwatchData();
6332  }
6333 
6334  //clear row data
6335  this.rowManager.rows.forEach(function (row) {
6336  row.wipe();
6337  });
6338 
6339  this.rowManager.rows = [];
6340  this.rowManager.activeRows = [];
6341  this.rowManager.displayRows = [];
6342 
6343  //clear event bindings
6344  if (this.options.autoResize && this.modExists("resizeTable")) {
6345  this.modules.resizeTable.clearBindings();
6346  }
6347 
6348  if (this.modExists("keybindings")) {
6349  this.modules.keybindings.clearBindings();
6350  }
6351 
6352  //clear DOM
6353  while (element.firstChild) {
6354  element.removeChild(element.firstChild);
6355  }element.classList.remove("tabulator");
6356 };
6357 
6358 Tabulator.prototype._detectBrowser = function () {
6359  var ua = navigator.userAgent || navigator.vendor || window.opera;
6360 
6361  if (ua.indexOf("Trident") > -1) {
6362  this.browser = "ie";
6363  this.browserSlow = true;
6364  } else if (ua.indexOf("Edge") > -1) {
6365  this.browser = "edge";
6366  this.browserSlow = true;
6367  } else if (ua.indexOf("Firefox") > -1) {
6368  this.browser = "firefox";
6369  this.browserSlow = false;
6370  } else {
6371  this.browser = "other";
6372  this.browserSlow = false;
6373  }
6374 
6375  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));
6376 };
6377 
6379 
6380 //block table redrawing
6381 Tabulator.prototype.blockRedraw = function () {
6382  return this.rowManager.blockRedraw();
6383 };
6384 
6385 //restore table redrawing
6386 Tabulator.prototype.restoreRedraw = function () {
6387  return this.rowManager.restoreRedraw();
6388 };
6389 
6390 //local data from local file
6391 Tabulator.prototype.setDataFromLocalFile = function (extensions) {
6392  var _this16 = this;
6393 
6394  return new Promise(function (resolve, reject) {
6395  var input = document.createElement("input");
6396  input.type = "file";
6397  input.accept = extensions || ".json,application/json";
6398 
6399  input.addEventListener("change", function (e) {
6400  var file = input.files[0],
6401  reader = new FileReader(),
6402  data;
6403 
6404  reader.readAsText(file);
6405 
6406  reader.onload = function (e) {
6407 
6408  try {
6409  data = JSON.parse(reader.result);
6410  } catch (e) {
6411  console.warn("File Load Error - File contents is invalid JSON", e);
6412  reject(e);
6413  return;
6414  }
6415 
6416  _this16._setData(data).then(function (data) {
6417  resolve(data);
6418  }).catch(function (err) {
6419  resolve(err);
6420  });
6421  };
6422 
6423  reader.onerror = function (e) {
6424  console.warn("File Load Error - Unable to read file");
6425  reject();
6426  };
6427  });
6428 
6429  input.click();
6430  });
6431 };
6432 
6433 //load data
6434 Tabulator.prototype.setData = function (data, params, config) {
6435  if (this.modExists("ajax")) {
6436  this.modules.ajax.blockActiveRequest();
6437  }
6438 
6439  return this._setData(data, params, config);
6440 };
6441 
6442 Tabulator.prototype._setData = function (data, params, config, inPosition) {
6443  var self = this;
6444 
6445  if (typeof data === "string") {
6446  if (data.indexOf("{") == 0 || data.indexOf("[") == 0) {
6447  //data is a json encoded string
6448  return self.rowManager.setData(JSON.parse(data), inPosition);
6449  } else {
6450 
6451  if (self.modExists("ajax", true)) {
6452  if (params) {
6453  self.modules.ajax.setParams(params);
6454  }
6455 
6456  if (config) {
6457  self.modules.ajax.setConfig(config);
6458  }
6459 
6460  self.modules.ajax.setUrl(data);
6461 
6462  if (self.options.pagination == "remote" && self.modExists("page", true)) {
6463  self.modules.page.reset(true);
6464  return self.modules.page.setPage(1);
6465  } else {
6466  //assume data is url, make ajax call to url to get data
6467  return self.modules.ajax.loadData(inPosition);
6468  }
6469  }
6470  }
6471  } else {
6472  if (data) {
6473  //asume data is already an object
6474  return self.rowManager.setData(data, inPosition);
6475  } else {
6476 
6477  //no data provided, check if ajaxURL is present;
6478  if (self.modExists("ajax") && (self.modules.ajax.getUrl || self.options.ajaxURLGenerator)) {
6479 
6480  if (self.options.pagination == "remote" && self.modExists("page", true)) {
6481  self.modules.page.reset(true);
6482  return self.modules.page.setPage(1);
6483  } else {
6484  return self.modules.ajax.loadData(inPosition);
6485  }
6486  } else {
6487  //empty data
6488  return self.rowManager.setData([], inPosition);
6489  }
6490  }
6491  }
6492 };
6493 
6494 //clear data
6495 Tabulator.prototype.clearData = function () {
6496  if (this.modExists("ajax")) {
6497  this.modules.ajax.blockActiveRequest();
6498  }
6499 
6500  this.rowManager.clearData();
6501 };
6502 
6503 //get table data array
6504 Tabulator.prototype.getData = function (active) {
6505 
6506  if (active === true) {
6507  console.warn("passing a boolean to the getData function is deprecated, you should now pass the string 'active'");
6508  active = "active";
6509  }
6510 
6511  return this.rowManager.getData(active);
6512 };
6513 
6514 //get table data array count
6515 Tabulator.prototype.getDataCount = function (active) {
6516 
6517  if (active === true) {
6518  console.warn("passing a boolean to the getDataCount function is deprecated, you should now pass the string 'active'");
6519  active = "active";
6520  }
6521 
6522  return this.rowManager.getDataCount(active);
6523 };
6524 
6525 //search for specific row components
6526 Tabulator.prototype.searchRows = function (field, type, value) {
6527  if (this.modExists("filter", true)) {
6528  return this.modules.filter.search("rows", field, type, value);
6529  }
6530 };
6531 
6532 //search for specific data
6533 Tabulator.prototype.searchData = function (field, type, value) {
6534  if (this.modExists("filter", true)) {
6535  return this.modules.filter.search("data", field, type, value);
6536  }
6537 };
6538 
6539 //get table html
6540 Tabulator.prototype.getHtml = function (visible, style, config) {
6541  if (this.modExists("htmlTableExport", true)) {
6542  return this.modules.htmlTableExport.getHtml(visible, style, config);
6543  }
6544 };
6545 
6546 //get print html
6547 Tabulator.prototype.print = function (visible, style, config) {
6548  if (this.modExists("print", true)) {
6549  return this.modules.print.printFullscreen(visible, style, config);
6550  }
6551 };
6552 
6553 //retrieve Ajax URL
6554 Tabulator.prototype.getAjaxUrl = function () {
6555  if (this.modExists("ajax", true)) {
6556  return this.modules.ajax.getUrl();
6557  }
6558 };
6559 
6560 //replace data, keeping table in position with same sort
6561 Tabulator.prototype.replaceData = function (data, params, config) {
6562  if (this.modExists("ajax")) {
6563  this.modules.ajax.blockActiveRequest();
6564  }
6565 
6566  return this._setData(data, params, config, true);
6567 };
6568 
6569 //update table data
6570 Tabulator.prototype.updateData = function (data) {
6571  var _this17 = this;
6572 
6573  var self = this;
6574  var responses = 0;
6575 
6576  return new Promise(function (resolve, reject) {
6577  if (_this17.modExists("ajax")) {
6578  _this17.modules.ajax.blockActiveRequest();
6579  }
6580 
6581  if (typeof data === "string") {
6582  data = JSON.parse(data);
6583  }
6584 
6585  if (data) {
6586  data.forEach(function (item) {
6587  var row = self.rowManager.findRow(item[self.options.index]);
6588 
6589  if (row) {
6590  responses++;
6591 
6592  row.updateData(item).then(function () {
6593  responses--;
6594 
6595  if (!responses) {
6596  resolve();
6597  }
6598  });
6599  }
6600  });
6601  } else {
6602  console.warn("Update Error - No data provided");
6603  reject("Update Error - No data provided");
6604  }
6605  });
6606 };
6607 
6608 Tabulator.prototype.addData = function (data, pos, index) {
6609  var _this18 = this;
6610 
6611  return new Promise(function (resolve, reject) {
6612  if (_this18.modExists("ajax")) {
6613  _this18.modules.ajax.blockActiveRequest();
6614  }
6615 
6616  if (typeof data === "string") {
6617  data = JSON.parse(data);
6618  }
6619 
6620  if (data) {
6621  _this18.rowManager.addRows(data, pos, index).then(function (rows) {
6622  var output = [];
6623 
6624  rows.forEach(function (row) {
6625  output.push(row.getComponent());
6626  });
6627 
6628  resolve(output);
6629  });
6630  } else {
6631  console.warn("Update Error - No data provided");
6632  reject("Update Error - No data provided");
6633  }
6634  });
6635 };
6636 
6637 //update table data
6638 Tabulator.prototype.updateOrAddData = function (data) {
6639  var _this19 = this;
6640 
6641  var self = this,
6642  rows = [],
6643  responses = 0;
6644 
6645  return new Promise(function (resolve, reject) {
6646  if (_this19.modExists("ajax")) {
6647  _this19.modules.ajax.blockActiveRequest();
6648  }
6649 
6650  if (typeof data === "string") {
6651  data = JSON.parse(data);
6652  }
6653 
6654  if (data) {
6655  data.forEach(function (item) {
6656  var row = self.rowManager.findRow(item[self.options.index]);
6657 
6658  responses++;
6659 
6660  if (row) {
6661  row.updateData(item).then(function () {
6662  responses--;
6663  rows.push(row.getComponent());
6664 
6665  if (!responses) {
6666  resolve(rows);
6667  }
6668  });
6669  } else {
6670  self.rowManager.addRows(item).then(function (newRows) {
6671  responses--;
6672  rows.push(newRows[0].getComponent());
6673 
6674  if (!responses) {
6675  resolve(rows);
6676  }
6677  });
6678  }
6679  });
6680  } else {
6681  console.warn("Update Error - No data provided");
6682  reject("Update Error - No data provided");
6683  }
6684  });
6685 };
6686 
6687 //get row object
6688 Tabulator.prototype.getRow = function (index) {
6689  var row = this.rowManager.findRow(index);
6690 
6691  if (row) {
6692  return row.getComponent();
6693  } else {
6694  console.warn("Find Error - No matching row found:", index);
6695  return false;
6696  }
6697 };
6698 
6699 //get row object
6700 Tabulator.prototype.getRowFromPosition = function (position, active) {
6701  var row = this.rowManager.getRowFromPosition(position, active);
6702 
6703  if (row) {
6704  return row.getComponent();
6705  } else {
6706  console.warn("Find Error - No matching row found:", position);
6707  return false;
6708  }
6709 };
6710 
6711 //delete row from table
6712 Tabulator.prototype.deleteRow = function (index) {
6713  var _this20 = this;
6714 
6715  return new Promise(function (resolve, reject) {
6716  var count = 0,
6717  successCount = 0,
6718  self = _this20;
6719 
6720  function doneCheck() {
6721  count++;
6722 
6723  if (count == index.length) {
6724  if (successCount) {
6725  self.rowManager.reRenderInPosition();
6726  resolve();
6727  }
6728  }
6729  }
6730 
6731  if (!Array.isArray(index)) {
6732  index = [index];
6733  }
6734 
6735  index.forEach(function (item) {
6736  var row = _this20.rowManager.findRow(item, true);
6737 
6738  if (row) {
6739  row.delete().then(function () {
6740  successCount++;
6741  doneCheck();
6742  }).catch(function (err) {
6743  doneCheck();
6744  reject(err);
6745  });
6746  } else {
6747  console.warn("Delete Error - No matching row found:", item);
6748  reject("Delete Error - No matching row found");
6749  doneCheck();
6750  }
6751  });
6752  });
6753 };
6754 
6755 //add row to table
6756 Tabulator.prototype.addRow = function (data, pos, index) {
6757  var _this21 = this;
6758 
6759  return new Promise(function (resolve, reject) {
6760  if (typeof data === "string") {
6761  data = JSON.parse(data);
6762  }
6763 
6764  _this21.rowManager.addRows(data, pos, index).then(function (rows) {
6765  //recalc column calculations if present
6766  if (_this21.modExists("columnCalcs")) {
6767  _this21.modules.columnCalcs.recalc(_this21.rowManager.activeRows);
6768  }
6769 
6770  resolve(rows[0].getComponent());
6771  });
6772  });
6773 };
6774 
6775 //update a row if it exitsts otherwise create it
6776 Tabulator.prototype.updateOrAddRow = function (index, data) {
6777  var _this22 = this;
6778 
6779  return new Promise(function (resolve, reject) {
6780  var row = _this22.rowManager.findRow(index);
6781 
6782  if (typeof data === "string") {
6783  data = JSON.parse(data);
6784  }
6785 
6786  if (row) {
6787  row.updateData(data).then(function () {
6788  //recalc column calculations if present
6789  if (_this22.modExists("columnCalcs")) {
6790  _this22.modules.columnCalcs.recalc(_this22.rowManager.activeRows);
6791  }
6792 
6793  resolve(row.getComponent());
6794  }).catch(function (err) {
6795  reject(err);
6796  });
6797  } else {
6798  row = _this22.rowManager.addRows(data).then(function (rows) {
6799  //recalc column calculations if present
6800  if (_this22.modExists("columnCalcs")) {
6801  _this22.modules.columnCalcs.recalc(_this22.rowManager.activeRows);
6802  }
6803 
6804  resolve(rows[0].getComponent());
6805  }).catch(function (err) {
6806  reject(err);
6807  });
6808  }
6809  });
6810 };
6811 
6812 //update row data
6813 Tabulator.prototype.updateRow = function (index, data) {
6814  var _this23 = this;
6815 
6816  return new Promise(function (resolve, reject) {
6817  var row = _this23.rowManager.findRow(index);
6818 
6819  if (typeof data === "string") {
6820  data = JSON.parse(data);
6821  }
6822 
6823  if (row) {
6824  row.updateData(data).then(function () {
6825  resolve(row.getComponent());
6826  }).catch(function (err) {
6827  reject(err);
6828  });
6829  } else {
6830  console.warn("Update Error - No matching row found:", index);
6831  reject("Update Error - No matching row found");
6832  }
6833  });
6834 };
6835 
6836 //scroll to row in DOM
6837 Tabulator.prototype.scrollToRow = function (index, position, ifVisible) {
6838  var _this24 = this;
6839 
6840  return new Promise(function (resolve, reject) {
6841  var row = _this24.rowManager.findRow(index);
6842 
6843  if (row) {
6844  _this24.rowManager.scrollToRow(row, position, ifVisible).then(function () {
6845  resolve();
6846  }).catch(function (err) {
6847  reject(err);
6848  });
6849  } else {
6850  console.warn("Scroll Error - No matching row found:", index);
6851  reject("Scroll Error - No matching row found");
6852  }
6853  });
6854 };
6855 
6856 Tabulator.prototype.moveRow = function (from, to, after) {
6857  var fromRow = this.rowManager.findRow(from);
6858 
6859  if (fromRow) {
6860  fromRow.moveToRow(to, after);
6861  } else {
6862  console.warn("Move Error - No matching row found:", from);
6863  }
6864 };
6865 
6866 Tabulator.prototype.getRows = function (active) {
6867 
6868  if (active === true) {
6869  console.warn("passing a boolean to the getRows function is deprecated, you should now pass the string 'active'");
6870  active = "active";
6871  }
6872 
6873  return this.rowManager.getComponents(active);
6874 };
6875 
6876 //get position of row in table
6877 Tabulator.prototype.getRowPosition = function (index, active) {
6878  var row = this.rowManager.findRow(index);
6879 
6880  if (row) {
6881  return this.rowManager.getRowPosition(row, active);
6882  } else {
6883  console.warn("Position Error - No matching row found:", index);
6884  return false;
6885  }
6886 };
6887 
6888 //copy table data to clipboard
6889 Tabulator.prototype.copyToClipboard = function (selector, selectorParams, formatter, formatterParams) {
6890  if (this.modExists("clipboard", true)) {
6891  this.modules.clipboard.copy(selector, selectorParams, formatter, formatterParams);
6892  }
6893 };
6894 
6896 
6897 Tabulator.prototype.setColumns = function (definition) {
6898  this.columnManager.setColumns(definition);
6899 };
6900 
6901 Tabulator.prototype.getColumns = function (structured) {
6902  return this.columnManager.getComponents(structured);
6903 };
6904 
6905 Tabulator.prototype.getColumn = function (field) {
6906  var col = this.columnManager.findColumn(field);
6907 
6908  if (col) {
6909  return col.getComponent();
6910  } else {
6911  console.warn("Find Error - No matching column found:", field);
6912  return false;
6913  }
6914 };
6915 
6916 Tabulator.prototype.getColumnDefinitions = function () {
6917  return this.columnManager.getDefinitionTree();
6918 };
6919 
6920 Tabulator.prototype.getColumnLayout = function () {
6921  if (this.modExists("persistence", true)) {
6922  return this.modules.persistence.parseColumns(this.columnManager.getColumns());
6923  }
6924 };
6925 
6926 Tabulator.prototype.setColumnLayout = function (layout) {
6927  if (this.modExists("persistence", true)) {
6928  this.columnManager.setColumns(this.modules.persistence.mergeDefinition(this.options.columns, layout));
6929  return true;
6930  }
6931  return false;
6932 };
6933 
6934 Tabulator.prototype.showColumn = function (field) {
6935  var column = this.columnManager.findColumn(field);
6936 
6937  if (column) {
6938  column.show();
6939 
6940  if (this.options.responsiveLayout && this.modExists("responsiveLayout", true)) {
6941  this.modules.responsiveLayout.update();
6942  }
6943  } else {
6944  console.warn("Column Show Error - No matching column found:", field);
6945  return false;
6946  }
6947 };
6948 
6949 Tabulator.prototype.hideColumn = function (field) {
6950  var column = this.columnManager.findColumn(field);
6951 
6952  if (column) {
6953  column.hide();
6954 
6955  if (this.options.responsiveLayout && this.modExists("responsiveLayout", true)) {
6956  this.modules.responsiveLayout.update();
6957  }
6958  } else {
6959  console.warn("Column Hide Error - No matching column found:", field);
6960  return false;
6961  }
6962 };
6963 
6964 Tabulator.prototype.toggleColumn = function (field) {
6965  var column = this.columnManager.findColumn(field);
6966 
6967  if (column) {
6968  if (column.visible) {
6969  column.hide();
6970  } else {
6971  column.show();
6972  }
6973  } else {
6974  console.warn("Column Visibility Toggle Error - No matching column found:", field);
6975  return false;
6976  }
6977 };
6978 
6979 Tabulator.prototype.addColumn = function (definition, before, field) {
6980  var _this25 = this;
6981 
6982  return new Promise(function (resolve, reject) {
6983  var column = _this25.columnManager.findColumn(field);
6984 
6985  _this25.columnManager.addColumn(definition, before, column).then(function (column) {
6986  resolve(column.getComponent());
6987  }).catch(function (err) {
6988  reject(err);
6989  });
6990  });
6991 };
6992 
6993 Tabulator.prototype.deleteColumn = function (field) {
6994  var _this26 = this;
6995 
6996  return new Promise(function (resolve, reject) {
6997  var column = _this26.columnManager.findColumn(field);
6998 
6999  if (column) {
7000  column.delete().then(function () {
7001  resolve();
7002  }).catch(function (err) {
7003  reject(err);
7004  });
7005  } else {
7006  console.warn("Column Delete Error - No matching column found:", field);
7007  reject();
7008  }
7009  });
7010 };
7011 
7012 Tabulator.prototype.updateColumnDefinition = function (field, definition) {
7013  var _this27 = this;
7014 
7015  return new Promise(function (resolve, reject) {
7016  var column = _this27.columnManager.findColumn(field);
7017 
7018  if (column) {
7019  column.updateDefinition().then(function (col) {
7020  resolve(col);
7021  }).catch(function (err) {
7022  reject(err);
7023  });
7024  } else {
7025  console.warn("Column Update Error - No matching column found:", field);
7026  reject();
7027  }
7028  });
7029 };
7030 
7031 Tabulator.prototype.moveColumn = function (from, to, after) {
7032  var fromColumn = this.columnManager.findColumn(from);
7033  var toColumn = this.columnManager.findColumn(to);
7034 
7035  if (fromColumn) {
7036  if (toColumn) {
7037  this.columnManager.moveColumn(fromColumn, toColumn, after);
7038  } else {
7039  console.warn("Move Error - No matching column found:", toColumn);
7040  }
7041  } else {
7042  console.warn("Move Error - No matching column found:", from);
7043  }
7044 };
7045 
7046 //scroll to column in DOM
7047 Tabulator.prototype.scrollToColumn = function (field, position, ifVisible) {
7048  var _this28 = this;
7049 
7050  return new Promise(function (resolve, reject) {
7051  var column = _this28.columnManager.findColumn(field);
7052 
7053  if (column) {
7054  _this28.columnManager.scrollToColumn(column, position, ifVisible).then(function () {
7055  resolve();
7056  }).catch(function (err) {
7057  reject(err);
7058  });
7059  } else {
7060  console.warn("Scroll Error - No matching column found:", field);
7061  reject("Scroll Error - No matching column found");
7062  }
7063  });
7064 };
7065 
7067 Tabulator.prototype.setLocale = function (locale) {
7068  this.modules.localize.setLocale(locale);
7069 };
7070 
7071 Tabulator.prototype.getLocale = function () {
7072  return this.modules.localize.getLocale();
7073 };
7074 
7075 Tabulator.prototype.getLang = function (locale) {
7076  return this.modules.localize.getLang(locale);
7077 };
7078 
7080 
7081 //redraw list without updating data
7082 Tabulator.prototype.redraw = function (force) {
7083  this.columnManager.redraw(force);
7084  this.rowManager.redraw(force);
7085 };
7086 
7087 Tabulator.prototype.setHeight = function (height) {
7088 
7089  if (this.rowManager.renderMode !== "classic") {
7090  this.options.height = isNaN(height) ? height : height + "px";
7091  this.element.style.height = this.options.height;
7092  this.rowManager.redraw();
7093  } else {
7094  console.warn("setHeight function is not available in classic render mode");
7095  }
7096 };
7097 
7099 
7100 //trigger sort
7101 Tabulator.prototype.setSort = function (sortList, dir) {
7102  if (this.modExists("sort", true)) {
7103  this.modules.sort.setSort(sortList, dir);
7104  this.rowManager.sorterRefresh();
7105  }
7106 };
7107 
7108 Tabulator.prototype.getSorters = function () {
7109  if (this.modExists("sort", true)) {
7110  return this.modules.sort.getSort();
7111  }
7112 };
7113 
7114 Tabulator.prototype.clearSort = function () {
7115  if (this.modExists("sort", true)) {
7116  this.modules.sort.clear();
7117  this.rowManager.sorterRefresh();
7118  }
7119 };
7120 
7122 
7123 //set standard filters
7124 Tabulator.prototype.setFilter = function (field, type, value) {
7125  if (this.modExists("filter", true)) {
7126  this.modules.filter.setFilter(field, type, value);
7127  this.rowManager.filterRefresh();
7128  }
7129 };
7130 
7131 //add filter to array
7132 Tabulator.prototype.addFilter = function (field, type, value) {
7133  if (this.modExists("filter", true)) {
7134  this.modules.filter.addFilter(field, type, value);
7135  this.rowManager.filterRefresh();
7136  }
7137 };
7138 
7139 //get all filters
7140 Tabulator.prototype.getFilters = function (all) {
7141  if (this.modExists("filter", true)) {
7142  return this.modules.filter.getFilters(all);
7143  }
7144 };
7145 
7146 Tabulator.prototype.setHeaderFilterFocus = function (field) {
7147  if (this.modExists("filter", true)) {
7148  var column = this.columnManager.findColumn(field);
7149 
7150  if (column) {
7151  this.modules.filter.setHeaderFilterFocus(column);
7152  } else {
7153  console.warn("Column Filter Focus Error - No matching column found:", field);
7154  return false;
7155  }
7156  }
7157 };
7158 
7159 Tabulator.prototype.setHeaderFilterValue = function (field, value) {
7160  if (this.modExists("filter", true)) {
7161  var column = this.columnManager.findColumn(field);
7162 
7163  if (column) {
7164  this.modules.filter.setHeaderFilterValue(column, value);
7165  } else {
7166  console.warn("Column Filter Error - No matching column found:", field);
7167  return false;
7168  }
7169  }
7170 };
7171 
7172 Tabulator.prototype.getHeaderFilters = function () {
7173  if (this.modExists("filter", true)) {
7174  return this.modules.filter.getHeaderFilters();
7175  }
7176 };
7177 
7178 //remove filter from array
7179 Tabulator.prototype.removeFilter = function (field, type, value) {
7180  if (this.modExists("filter", true)) {
7181  this.modules.filter.removeFilter(field, type, value);
7182  this.rowManager.filterRefresh();
7183  }
7184 };
7185 
7186 //clear filters
7187 Tabulator.prototype.clearFilter = function (all) {
7188  if (this.modExists("filter", true)) {
7189  this.modules.filter.clearFilter(all);
7190  this.rowManager.filterRefresh();
7191  }
7192 };
7193 
7194 //clear header filters
7195 Tabulator.prototype.clearHeaderFilter = function () {
7196  if (this.modExists("filter", true)) {
7197  this.modules.filter.clearHeaderFilter();
7198  this.rowManager.filterRefresh();
7199  }
7200 };
7201 
7203 Tabulator.prototype.selectRow = function (rows) {
7204  if (this.modExists("selectRow", true)) {
7205  if (rows === true) {
7206  console.warn("passing a boolean to the selectRowselectRow function is deprecated, you should now pass the string 'active'");
7207  rows = "active";
7208  }
7209  this.modules.selectRow.selectRows(rows);
7210  }
7211 };
7212 
7213 Tabulator.prototype.deselectRow = function (rows) {
7214  if (this.modExists("selectRow", true)) {
7215  this.modules.selectRow.deselectRows(rows);
7216  }
7217 };
7218 
7219 Tabulator.prototype.toggleSelectRow = function (row) {
7220  if (this.modExists("selectRow", true)) {
7221  this.modules.selectRow.toggleRow(row);
7222  }
7223 };
7224 
7225 Tabulator.prototype.getSelectedRows = function () {
7226  if (this.modExists("selectRow", true)) {
7227  return this.modules.selectRow.getSelectedRows();
7228  }
7229 };
7230 
7231 Tabulator.prototype.getSelectedData = function () {
7232  if (this.modExists("selectRow", true)) {
7233  return this.modules.selectRow.getSelectedData();
7234  }
7235 };
7236 
7238 
7239 Tabulator.prototype.setMaxPage = function (max) {
7240  if (this.options.pagination && this.modExists("page")) {
7241  this.modules.page.setMaxPage(max);
7242  } else {
7243  return false;
7244  }
7245 };
7246 
7247 Tabulator.prototype.setPage = function (page) {
7248  if (this.options.pagination && this.modExists("page")) {
7249  return this.modules.page.setPage(page);
7250  } else {
7251  return new Promise(function (resolve, reject) {
7252  reject();
7253  });
7254  }
7255 };
7256 
7257 Tabulator.prototype.setPageToRow = function (row) {
7258  var _this29 = this;
7259 
7260  return new Promise(function (resolve, reject) {
7261  if (_this29.options.pagination && _this29.modExists("page")) {
7262  row = _this29.rowManager.findRow(row);
7263 
7264  if (row) {
7265  _this29.modules.page.setPageToRow(row).then(function () {
7266  resolve();
7267  }).catch(function () {
7268  reject();
7269  });
7270  } else {
7271  reject();
7272  }
7273  } else {
7274  reject();
7275  }
7276  });
7277 };
7278 
7279 Tabulator.prototype.setPageSize = function (size) {
7280  if (this.options.pagination && this.modExists("page")) {
7281  this.modules.page.setPageSize(size);
7282  this.modules.page.setPage(1).then(function () {}).catch(function () {});
7283  } else {
7284  return false;
7285  }
7286 };
7287 
7288 Tabulator.prototype.getPageSize = function () {
7289  if (this.options.pagination && this.modExists("page", true)) {
7290  return this.modules.page.getPageSize();
7291  }
7292 };
7293 
7294 Tabulator.prototype.previousPage = function () {
7295  if (this.options.pagination && this.modExists("page")) {
7296  this.modules.page.previousPage();
7297  } else {
7298  return false;
7299  }
7300 };
7301 
7302 Tabulator.prototype.nextPage = function () {
7303  if (this.options.pagination && this.modExists("page")) {
7304  this.modules.page.nextPage();
7305  } else {
7306  return false;
7307  }
7308 };
7309 
7310 Tabulator.prototype.getPage = function () {
7311  if (this.options.pagination && this.modExists("page")) {
7312  return this.modules.page.getPage();
7313  } else {
7314  return false;
7315  }
7316 };
7317 
7318 Tabulator.prototype.getPageMax = function () {
7319  if (this.options.pagination && this.modExists("page")) {
7320  return this.modules.page.getPageMax();
7321  } else {
7322  return false;
7323  }
7324 };
7325 
7327 
7328 Tabulator.prototype.setGroupBy = function (groups) {
7329  if (this.modExists("groupRows", true)) {
7330  this.options.groupBy = groups;
7331  this.modules.groupRows.initialize();
7332  this.rowManager.refreshActiveData("display");
7333 
7334  if (this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group) {
7335  this.modules.persistence.save("group");
7336  }
7337  } else {
7338  return false;
7339  }
7340 };
7341 
7342 Tabulator.prototype.setGroupStartOpen = function (values) {
7343  if (this.modExists("groupRows", true)) {
7344  this.options.groupStartOpen = values;
7345  this.modules.groupRows.initialize();
7346  if (this.options.groupBy) {
7347  this.rowManager.refreshActiveData("group");
7348 
7349  if (this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group) {
7350  this.modules.persistence.save("group");
7351  }
7352  } else {
7353  console.warn("Grouping Update - cant refresh view, no groups have been set");
7354  }
7355  } else {
7356  return false;
7357  }
7358 };
7359 
7360 Tabulator.prototype.setGroupHeader = function (values) {
7361  if (this.modExists("groupRows", true)) {
7362  this.options.groupHeader = values;
7363  this.modules.groupRows.initialize();
7364  if (this.options.groupBy) {
7365  this.rowManager.refreshActiveData("group");
7366 
7367  if (this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group) {
7368  this.modules.persistence.save("group");
7369  }
7370  } else {
7371  console.warn("Grouping Update - cant refresh view, no groups have been set");
7372  }
7373  } else {
7374  return false;
7375  }
7376 };
7377 
7378 Tabulator.prototype.getGroups = function (values) {
7379  if (this.modExists("groupRows", true)) {
7380  return this.modules.groupRows.getGroups(true);
7381  } else {
7382  return false;
7383  }
7384 };
7385 
7386 // get grouped table data in the same format as getData()
7387 Tabulator.prototype.getGroupedData = function () {
7388  if (this.modExists("groupRows", true)) {
7389  return this.options.groupBy ? this.modules.groupRows.getGroupedData() : this.getData();
7390  }
7391 };
7392 
7394 Tabulator.prototype.getCalcResults = function () {
7395  if (this.modExists("columnCalcs", true)) {
7396  return this.modules.columnCalcs.getResults();
7397  } else {
7398  return false;
7399  }
7400 };
7401 
7403 
7404 Tabulator.prototype.navigatePrev = function () {
7405  var cell = false;
7406 
7407  if (this.modExists("edit", true)) {
7408  cell = this.modules.edit.currentCell;
7409 
7410  if (cell) {
7411  return cell.nav().prev();
7412  }
7413  }
7414 
7415  return false;
7416 };
7417 
7418 Tabulator.prototype.navigateNext = function () {
7419  var cell = false;
7420 
7421  if (this.modExists("edit", true)) {
7422  cell = this.modules.edit.currentCell;
7423 
7424  if (cell) {
7425  return cell.nav().next();
7426  }
7427  }
7428 
7429  return false;
7430 };
7431 
7432 Tabulator.prototype.navigateLeft = function () {
7433  var cell = false;
7434 
7435  if (this.modExists("edit", true)) {
7436  cell = this.modules.edit.currentCell;
7437 
7438  if (cell) {
7439  e.preventDefault();
7440  return cell.nav().left();
7441  }
7442  }
7443 
7444  return false;
7445 };
7446 
7447 Tabulator.prototype.navigateRight = function () {
7448  var cell = false;
7449 
7450  if (this.modExists("edit", true)) {
7451  cell = this.modules.edit.currentCell;
7452 
7453  if (cell) {
7454  e.preventDefault();
7455  return cell.nav().right();
7456  }
7457  }
7458 
7459  return false;
7460 };
7461 
7462 Tabulator.prototype.navigateUp = function () {
7463  var cell = false;
7464 
7465  if (this.modExists("edit", true)) {
7466  cell = this.modules.edit.currentCell;
7467 
7468  if (cell) {
7469  e.preventDefault();
7470  return cell.nav().up();
7471  }
7472  }
7473 
7474  return false;
7475 };
7476 
7477 Tabulator.prototype.navigateDown = function () {
7478  var cell = false;
7479 
7480  if (this.modExists("edit", true)) {
7481  cell = this.modules.edit.currentCell;
7482 
7483  if (cell) {
7484  e.preventDefault();
7485  return cell.nav().down();
7486  }
7487  }
7488 
7489  return false;
7490 };
7491 
7493 Tabulator.prototype.undo = function () {
7494  if (this.options.history && this.modExists("history", true)) {
7495  return this.modules.history.undo();
7496  } else {
7497  return false;
7498  }
7499 };
7500 
7501 Tabulator.prototype.redo = function () {
7502  if (this.options.history && this.modExists("history", true)) {
7503  return this.modules.history.redo();
7504  } else {
7505  return false;
7506  }
7507 };
7508 
7509 Tabulator.prototype.getHistoryUndoSize = function () {
7510  if (this.options.history && this.modExists("history", true)) {
7511  return this.modules.history.getHistoryUndoSize();
7512  } else {
7513  return false;
7514  }
7515 };
7516 
7517 Tabulator.prototype.getHistoryRedoSize = function () {
7518  if (this.options.history && this.modExists("history", true)) {
7519  return this.modules.history.getHistoryRedoSize();
7520  } else {
7521  return false;
7522  }
7523 };
7524 
7526 
7527 Tabulator.prototype.download = function (type, filename, options, active) {
7528  if (this.modExists("download", true)) {
7529  this.modules.download.download(type, filename, options, active);
7530  }
7531 };
7532 
7533 Tabulator.prototype.downloadToTab = function (type, filename, options, active) {
7534  if (this.modExists("download", true)) {
7535  this.modules.download.download(type, filename, options, active, true);
7536  }
7537 };
7538 
7540 
7541 Tabulator.prototype.tableComms = function (table, module, action, data) {
7542  this.modules.comms.receive(table, module, action, data);
7543 };
7544 
7546 
7547 //object to hold module
7548 Tabulator.prototype.moduleBindings = {};
7549 
7550 //extend module
7551 Tabulator.prototype.extendModule = function (name, property, values) {
7552 
7553  if (Tabulator.prototype.moduleBindings[name]) {
7554  var source = Tabulator.prototype.moduleBindings[name].prototype[property];
7555 
7556  if (source) {
7557  if ((typeof values === 'undefined' ? 'undefined' : _typeof(values)) == "object") {
7558  for (var key in values) {
7559  source[key] = values[key];
7560  }
7561  } else {
7562  console.warn("Module Error - Invalid value type, it must be an object");
7563  }
7564  } else {
7565  console.warn("Module Error - property does not exist:", property);
7566  }
7567  } else {
7568  console.warn("Module Error - module does not exist:", name);
7569  }
7570 };
7571 
7572 //add module to tabulator
7573 Tabulator.prototype.registerModule = function (name, module) {
7574  var self = this;
7575  Tabulator.prototype.moduleBindings[name] = module;
7576 };
7577 
7578 //ensure that module are bound to instantiated function
7579 Tabulator.prototype.bindModules = function () {
7580  this.modules = {};
7581 
7582  for (var name in Tabulator.prototype.moduleBindings) {
7583  this.modules[name] = new Tabulator.prototype.moduleBindings[name](this);
7584  }
7585 };
7586 
7587 //Check for module
7588 Tabulator.prototype.modExists = function (plugin, required) {
7589  if (this.modules[plugin]) {
7590  return true;
7591  } else {
7592  if (required) {
7593  console.error("Tabulator Module Not Installed: " + plugin);
7594  }
7595  return false;
7596  }
7597 };
7598 
7599 Tabulator.prototype.helpers = {
7600 
7601  elVisible: function elVisible(el) {
7602  return !(el.offsetWidth <= 0 && el.offsetHeight <= 0);
7603  },
7604 
7605  elOffset: function elOffset(el) {
7606  var box = el.getBoundingClientRect();
7607 
7608  return {
7609  top: box.top + window.pageYOffset - document.documentElement.clientTop,
7610  left: box.left + window.pageXOffset - document.documentElement.clientLeft
7611  };
7612  },
7613 
7614  deepClone: function deepClone(obj) {
7615  var clone = Array.isArray(obj) ? [] : {};
7616 
7617  for (var i in obj) {
7618  if (obj[i] != null && _typeof(obj[i]) === "object") {
7619  if (obj[i] instanceof Date) {
7620  clone[i] = new Date(obj[i]);
7621  } else {
7622  clone[i] = this.deepClone(obj[i]);
7623  }
7624  } else {
7625  clone[i] = obj[i];
7626  }
7627  }
7628  return clone;
7629  }
7630 };
7631 
7632 Tabulator.prototype.comms = {
7633  tables: [],
7634  register: function register(table) {
7635  Tabulator.prototype.comms.tables.push(table);
7636  },
7637  deregister: function deregister(table) {
7638  var index = Tabulator.prototype.comms.tables.indexOf(table);
7639 
7640  if (index > -1) {
7641  Tabulator.prototype.comms.tables.splice(index, 1);
7642  }
7643  },
7644  lookupTable: function lookupTable(query, silent) {
7645  var results = [],
7646  matches,
7647  match;
7648 
7649  if (typeof query === "string") {
7650  matches = document.querySelectorAll(query);
7651 
7652  if (matches.length) {
7653  for (var i = 0; i < matches.length; i++) {
7654  match = Tabulator.prototype.comms.matchElement(matches[i]);
7655 
7656  if (match) {
7657  results.push(match);
7658  }
7659  }
7660  }
7661  } else if (typeof HTMLElement !== "undefined" && query instanceof HTMLElement || query instanceof Tabulator) {
7662  match = Tabulator.prototype.comms.matchElement(query);
7663 
7664  if (match) {
7665  results.push(match);
7666  }
7667  } else if (Array.isArray(query)) {
7668  query.forEach(function (item) {
7669  results = results.concat(Tabulator.prototype.comms.lookupTable(item));
7670  });
7671  } else {
7672  if (!silent) {
7673  console.warn("Table Connection Error - Invalid Selector", query);
7674  }
7675  }
7676 
7677  return results;
7678  },
7679  matchElement: function matchElement(element) {
7680  return Tabulator.prototype.comms.tables.find(function (table) {
7681  return element instanceof Tabulator ? table === element : table.element === element;
7682  });
7683  }
7684 };
7685 
7686 Tabulator.prototype.findTable = function (query) {
7687  var results = Tabulator.prototype.comms.lookupTable(query, true);
7688  return Array.isArray(results) && !results.length ? false : results;
7689 };
7690 
7691 var Layout = function Layout(table) {
7692 
7693  this.table = table;
7694 
7695  this.mode = null;
7696 };
7697 
7698 //initialize layout system
7699 
7700 Layout.prototype.initialize = function (layout) {
7701 
7702  if (this.modes[layout]) {
7703 
7704  this.mode = layout;
7705  } else {
7706 
7707  console.warn("Layout Error - invalid mode set, defaulting to 'fitData' : " + layout);
7708 
7709  this.mode = 'fitData';
7710  }
7711 
7712  this.table.element.setAttribute("tabulator-layout", this.mode);
7713 };
7714 
7715 Layout.prototype.getMode = function () {
7716 
7717  return this.mode;
7718 };
7719 
7720 //trigger table layout
7721 
7722 Layout.prototype.layout = function () {
7723 
7724  this.modes[this.mode].call(this, this.table.columnManager.columnsByIndex);
7725 };
7726 
7727 //layout render functions
7728 
7729 Layout.prototype.modes = {
7730 
7731  //resize columns to fit data the contain
7732 
7733  "fitData": function fitData(columns) {
7734 
7735  columns.forEach(function (column) {
7736 
7737  column.reinitializeWidth();
7738  });
7739 
7740  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
7741 
7742  this.table.modules.responsiveLayout.update();
7743  }
7744  },
7745 
7746  //resize columns to fit data the contain and stretch row to fill table
7747 
7748  "fitDataFill": function fitDataFill(columns) {
7749 
7750  columns.forEach(function (column) {
7751 
7752  column.reinitializeWidth();
7753  });
7754 
7755  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
7756 
7757  this.table.modules.responsiveLayout.update();
7758  }
7759  },
7760 
7761  //resize columns to fit data the contain and stretch last column to fill table
7762 
7763  "fitDataStretch": function fitDataStretch(columns) {
7764  var _this30 = this;
7765 
7766  var colsWidth = 0,
7767  tableWidth = this.table.rowManager.element.clientWidth,
7768  gap = 0,
7769  lastCol = false;
7770 
7771  columns.forEach(function (column, i) {
7772 
7773  if (!column.widthFixed) {
7774 
7775  column.reinitializeWidth();
7776  }
7777 
7778  if (_this30.table.options.responsiveLayout ? column.modules.responsive.visible : column.visible) {
7779 
7780  lastCol = column;
7781  }
7782 
7783  if (column.visible) {
7784 
7785  colsWidth += column.getWidth();
7786  }
7787  });
7788 
7789  if (lastCol) {
7790 
7791  gap = tableWidth - colsWidth + lastCol.getWidth();
7792 
7793  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
7794 
7795  lastCol.setWidth(0);
7796 
7797  this.table.modules.responsiveLayout.update();
7798  }
7799 
7800  if (gap > 0) {
7801 
7802  lastCol.setWidth(gap);
7803  } else {
7804 
7805  lastCol.reinitializeWidth();
7806  }
7807  } else {
7808 
7809  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
7810 
7811  this.table.modules.responsiveLayout.update();
7812  }
7813  }
7814  },
7815 
7816  //resize columns to fit
7817 
7818  "fitColumns": function fitColumns(columns) {
7819 
7820  var self = this;
7821 
7822  var totalWidth = self.table.element.clientWidth; //table element width
7823 
7824  var fixedWidth = 0; //total width of columns with a defined width
7825 
7826  var flexWidth = 0; //total width available to flexible columns
7827 
7828  var flexGrowUnits = 0; //total number of widthGrow blocks accross all columns
7829 
7830  var flexColWidth = 0; //desired width of flexible columns
7831 
7832  var flexColumns = []; //array of flexible width columns
7833 
7834  var fixedShrinkColumns = []; //array of fixed width columns that can shrink
7835 
7836  var flexShrinkUnits = 0; //total number of widthShrink blocks accross all columns
7837 
7838  var overflowWidth = 0; //horizontal overflow width
7839 
7840  var gapFill = 0; //number of pixels to be added to final column to close and half pixel gaps
7841 
7842 
7843  function calcWidth(width) {
7844 
7845  var colWidth;
7846 
7847  if (typeof width == "string") {
7848 
7849  if (width.indexOf("%") > -1) {
7850 
7851  colWidth = totalWidth / 100 * parseInt(width);
7852  } else {
7853 
7854  colWidth = parseInt(width);
7855  }
7856  } else {
7857 
7858  colWidth = width;
7859  }
7860 
7861  return colWidth;
7862  }
7863 
7864  //ensure columns resize to take up the correct amount of space
7865 
7866  function scaleColumns(columns, freeSpace, colWidth, shrinkCols) {
7867 
7868  var oversizeCols = [],
7869  oversizeSpace = 0,
7870  remainingSpace = 0,
7871  nextColWidth = 0,
7872  gap = 0,
7873  changeUnits = 0,
7874  undersizeCols = [];
7875 
7876  function calcGrow(col) {
7877 
7878  return colWidth * (col.column.definition.widthGrow || 1);
7879  }
7880 
7881  function calcShrink(col) {
7882 
7883  return calcWidth(col.width) - colWidth * (col.column.definition.widthShrink || 0);
7884  }
7885 
7886  columns.forEach(function (col, i) {
7887 
7888  var width = shrinkCols ? calcShrink(col) : calcGrow(col);
7889 
7890  if (col.column.minWidth >= width) {
7891 
7892  oversizeCols.push(col);
7893  } else {
7894 
7895  undersizeCols.push(col);
7896 
7897  changeUnits += shrinkCols ? col.column.definition.widthShrink || 1 : col.column.definition.widthGrow || 1;
7898  }
7899  });
7900 
7901  if (oversizeCols.length) {
7902 
7903  oversizeCols.forEach(function (col) {
7904 
7905  oversizeSpace += shrinkCols ? col.width - col.column.minWidth : col.column.minWidth;
7906 
7907  col.width = col.column.minWidth;
7908  });
7909 
7910  remainingSpace = freeSpace - oversizeSpace;
7911 
7912  nextColWidth = changeUnits ? Math.floor(remainingSpace / changeUnits) : remainingSpace;
7913 
7914  gap = remainingSpace - nextColWidth * changeUnits;
7915 
7916  gap += scaleColumns(undersizeCols, remainingSpace, nextColWidth, shrinkCols);
7917  } else {
7918 
7919  gap = changeUnits ? freeSpace - Math.floor(freeSpace / changeUnits) * changeUnits : freeSpace;
7920 
7921  undersizeCols.forEach(function (column) {
7922 
7923  column.width = shrinkCols ? calcShrink(column) : calcGrow(column);
7924  });
7925  }
7926 
7927  return gap;
7928  }
7929 
7930  if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) {
7931 
7932  this.table.modules.responsiveLayout.update();
7933  }
7934 
7935  //adjust for vertical scrollbar if present
7936 
7937  if (this.table.rowManager.element.scrollHeight > this.table.rowManager.element.clientHeight) {
7938 
7939  totalWidth -= this.table.rowManager.element.offsetWidth - this.table.rowManager.element.clientWidth;
7940  }
7941 
7942  columns.forEach(function (column) {
7943 
7944  var width, minWidth, colWidth;
7945 
7946  if (column.visible) {
7947 
7948  width = column.definition.width;
7949 
7950  minWidth = parseInt(column.minWidth);
7951 
7952  if (width) {
7953 
7954  colWidth = calcWidth(width);
7955 
7956  fixedWidth += colWidth > minWidth ? colWidth : minWidth;
7957 
7958  if (column.definition.widthShrink) {
7959 
7960  fixedShrinkColumns.push({
7961 
7962  column: column,
7963 
7964  width: colWidth > minWidth ? colWidth : minWidth
7965 
7966  });
7967 
7968  flexShrinkUnits += column.definition.widthShrink;
7969  }
7970  } else {
7971 
7972  flexColumns.push({
7973 
7974  column: column,
7975 
7976  width: 0
7977 
7978  });
7979 
7980  flexGrowUnits += column.definition.widthGrow || 1;
7981  }
7982  }
7983  });
7984 
7985  //calculate available space
7986 
7987  flexWidth = totalWidth - fixedWidth;
7988 
7989  //calculate correct column size
7990 
7991  flexColWidth = Math.floor(flexWidth / flexGrowUnits);
7992 
7993  //generate column widths
7994 
7995  var gapFill = scaleColumns(flexColumns, flexWidth, flexColWidth, false);
7996 
7997  //increase width of last column to account for rounding errors
7998 
7999  if (flexColumns.length && gapFill > 0) {
8000 
8001  flexColumns[flexColumns.length - 1].width += +gapFill;
8002  }
8003 
8004  //caculate space for columns to be shrunk into
8005 
8006  flexColumns.forEach(function (col) {
8007 
8008  flexWidth -= col.width;
8009  });
8010 
8011  overflowWidth = Math.abs(gapFill) + flexWidth;
8012 
8013  //shrink oversize columns if there is no available space
8014 
8015  if (overflowWidth > 0 && flexShrinkUnits) {
8016 
8017  gapFill = scaleColumns(fixedShrinkColumns, overflowWidth, Math.floor(overflowWidth / flexShrinkUnits), true);
8018  }
8019 
8020  //decrease width of last column to account for rounding errors
8021 
8022  if (fixedShrinkColumns.length) {
8023 
8024  fixedShrinkColumns[fixedShrinkColumns.length - 1].width -= gapFill;
8025  }
8026 
8027  flexColumns.forEach(function (col) {
8028 
8029  col.column.setWidth(col.width);
8030  });
8031 
8032  fixedShrinkColumns.forEach(function (col) {
8033 
8034  col.column.setWidth(col.width);
8035  });
8036  }
8037 
8038 };
8039 
8040 Tabulator.prototype.registerModule("layout", Layout);
8041 var Localize = function Localize(table) {
8042  this.table = table; //hold Tabulator object
8043  this.locale = "default"; //current locale
8044  this.lang = false; //current language
8045  this.bindings = {}; //update events to call when locale is changed
8046 };
8047 
8048 //set header placehoder
8049 Localize.prototype.setHeaderFilterPlaceholder = function (placeholder) {
8050  this.langs.default.headerFilters.default = placeholder;
8051 };
8052 
8053 //set header filter placeholder by column
8054 Localize.prototype.setHeaderFilterColumnPlaceholder = function (column, placeholder) {
8055  this.langs.default.headerFilters.columns[column] = placeholder;
8056 
8057  if (this.lang && !this.lang.headerFilters.columns[column]) {
8058  this.lang.headerFilters.columns[column] = placeholder;
8059  }
8060 };
8061 
8062 //setup a lang description object
8063 Localize.prototype.installLang = function (locale, lang) {
8064  if (this.langs[locale]) {
8065  this._setLangProp(this.langs[locale], lang);
8066  } else {
8067  this.langs[locale] = lang;
8068  }
8069 };
8070 
8071 Localize.prototype._setLangProp = function (lang, values) {
8072  for (var key in values) {
8073  if (lang[key] && _typeof(lang[key]) == "object") {
8074  this._setLangProp(lang[key], values[key]);
8075  } else {
8076  lang[key] = values[key];
8077  }
8078  }
8079 };
8080 
8081 //set current locale
8082 Localize.prototype.setLocale = function (desiredLocale) {
8083  var self = this;
8084 
8085  desiredLocale = desiredLocale || "default";
8086 
8087  //fill in any matching languge values
8088  function traverseLang(trans, path) {
8089  for (var prop in trans) {
8090 
8091  if (_typeof(trans[prop]) == "object") {
8092  if (!path[prop]) {
8093  path[prop] = {};
8094  }
8095  traverseLang(trans[prop], path[prop]);
8096  } else {
8097  path[prop] = trans[prop];
8098  }
8099  }
8100  }
8101 
8102  //determing correct locale to load
8103  if (desiredLocale === true && navigator.language) {
8104  //get local from system
8105  desiredLocale = navigator.language.toLowerCase();
8106  }
8107 
8108  if (desiredLocale) {
8109 
8110  //if locale is not set, check for matching top level locale else use default
8111  if (!self.langs[desiredLocale]) {
8112  var prefix = desiredLocale.split("-")[0];
8113 
8114  if (self.langs[prefix]) {
8115  console.warn("Localization Error - Exact matching locale not found, using closest match: ", desiredLocale, prefix);
8116  desiredLocale = prefix;
8117  } else {
8118  console.warn("Localization Error - Matching locale not found, using default: ", desiredLocale);
8119  desiredLocale = "default";
8120  }
8121  }
8122  }
8123 
8124  self.locale = desiredLocale;
8125 
8126  //load default lang template
8127  self.lang = Tabulator.prototype.helpers.deepClone(self.langs.default || {});
8128 
8129  if (desiredLocale != "default") {
8130  traverseLang(self.langs[desiredLocale], self.lang);
8131  }
8132 
8133  self.table.options.localized.call(self.table, self.locale, self.lang);
8134 
8135  self._executeBindings();
8136 };
8137 
8138 //get current locale
8139 Localize.prototype.getLocale = function (locale) {
8140  return self.locale;
8141 };
8142 
8143 //get lang object for given local or current if none provided
8144 Localize.prototype.getLang = function (locale) {
8145  return locale ? this.langs[locale] : this.lang;
8146 };
8147 
8148 //get text for current locale
8149 Localize.prototype.getText = function (path, value) {
8150  var path = value ? path + "|" + value : path,
8151  pathArray = path.split("|"),
8152  text = this._getLangElement(pathArray, this.locale);
8153 
8154  // if(text === false){
8155  // console.warn("Localization Error - Matching localized text not found for given path: ", path);
8156  // }
8157 
8158  return text || "";
8159 };
8160 
8161 //traverse langs object and find localized copy
8162 Localize.prototype._getLangElement = function (path, locale) {
8163  var self = this;
8164  var root = self.lang;
8165 
8166  path.forEach(function (level) {
8167  var rootPath;
8168 
8169  if (root) {
8170  rootPath = root[level];
8171 
8172  if (typeof rootPath != "undefined") {
8173  root = rootPath;
8174  } else {
8175  root = false;
8176  }
8177  }
8178  });
8179 
8180  return root;
8181 };
8182 
8183 //set update binding
8184 Localize.prototype.bind = function (path, callback) {
8185  if (!this.bindings[path]) {
8186  this.bindings[path] = [];
8187  }
8188 
8189  this.bindings[path].push(callback);
8190 
8191  callback(this.getText(path), this.lang);
8192 };
8193 
8194 //itterate through bindings and trigger updates
8195 Localize.prototype._executeBindings = function () {
8196  var self = this;
8197 
8198  var _loop = function _loop(path) {
8199  self.bindings[path].forEach(function (binding) {
8200  binding(self.getText(path), self.lang);
8201  });
8202  };
8203 
8204  for (var path in self.bindings) {
8205  _loop(path);
8206  }
8207 };
8208 
8209 //Localized text listings
8210 Localize.prototype.langs = {
8211  "default": { //hold default locale text
8212  "groups": {
8213  "item": "item",
8214  "items": "items"
8215  },
8216  "columns": {},
8217  "ajax": {
8218  "loading": "Loading",
8219  "error": "Error"
8220  },
8221  "pagination": {
8222  "page_size": "Page Size",
8223  "first": "First",
8224  "first_title": "First Page",
8225  "last": "Last",
8226  "last_title": "Last Page",
8227  "prev": "Prev",
8228  "prev_title": "Prev Page",
8229  "next": "Next",
8230  "next_title": "Next Page"
8231  },
8232  "headerFilters": {
8233  "default": "filter column...",
8234  "columns": {}
8235  }
8236  }
8237 };
8238 
8239 Tabulator.prototype.registerModule("localize", Localize);
8240 var Comms = function Comms(table) {
8241  this.table = table;
8242 };
8243 
8244 Comms.prototype.getConnections = function (selectors) {
8245  var self = this,
8246  connections = [],
8247  connection;
8248 
8249  connection = Tabulator.prototype.comms.lookupTable(selectors);
8250 
8251  connection.forEach(function (con) {
8252  if (self.table !== con) {
8253  connections.push(con);
8254  }
8255  });
8256 
8257  return connections;
8258 };
8259 
8260 Comms.prototype.send = function (selectors, module, action, data) {
8261  var self = this,
8262  connections = this.getConnections(selectors);
8263 
8264  connections.forEach(function (connection) {
8265  connection.tableComms(self.table.element, module, action, data);
8266  });
8267 
8268  if (!connections.length && selectors) {
8269  console.warn("Table Connection Error - No tables matching selector found", selectors);
8270  }
8271 };
8272 
8273 Comms.prototype.receive = function (table, module, action, data) {
8274  if (this.table.modExists(module)) {
8275  return this.table.modules[module].commsReceived(table, action, data);
8276  } else {
8277  console.warn("Inter-table Comms Error - no such module:", module);
8278  }
8279 };
8280 
8281 Tabulator.prototype.registerModule("comms", Comms);