tabulator-tables 5.1.1 → 5.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/bower.json +1 -1
  2. package/dist/js/tabulator.js +233 -148
  3. package/dist/js/tabulator.js.map +1 -1
  4. package/dist/js/tabulator.min.js +2 -2
  5. package/dist/js/tabulator.min.js.map +1 -1
  6. package/dist/js/tabulator_esm.js +551 -485
  7. package/dist/js/tabulator_esm.js.map +1 -1
  8. package/dist/js/tabulator_esm.min.js +2 -2
  9. package/dist/js/tabulator_esm.min.js.map +1 -1
  10. package/package.json +5 -2
  11. package/src/js/core/FooterManager.js +2 -4
  12. package/src/js/core/RowManager.js +0 -6
  13. package/src/js/core/Tabulator.js +13 -30
  14. package/src/js/core/rendering/renderers/VirtualDomHorizontal.js +1 -1
  15. package/src/js/core/row/Row.js +2 -2
  16. package/src/js/core/tools/InteractionMonitor.js +1 -1
  17. package/src/js/core/tools/ModuleBinder.js +15 -3
  18. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +9 -4
  19. package/src/js/modules/Export/Export.js +5 -4
  20. package/src/js/modules/Filter/Filter.js +4 -3
  21. package/src/js/modules/Format/defaults/formatters/rowSelection.js +19 -1
  22. package/src/js/modules/Format/defaults/formatters/rownum.js +1 -1
  23. package/src/js/modules/FrozenColumns/FrozenColumns.js +101 -83
  24. package/src/js/modules/GroupRows/Group.js +144 -142
  25. package/src/js/modules/Layout/Layout.js +1 -0
  26. package/src/js/modules/Page/Page.js +6 -3
  27. package/src/js/modules/Page/defaults/pageCounters/rows.js +21 -13
  28. package/src/js/modules/Persistence/Persistence.js +6 -4
  29. package/src/js/modules/Persistence/defaults/readers.js +3 -3
  30. package/src/js/modules/ResizeColumns/ResizeColumns.js +61 -51
  31. package/src/js/modules/ResponsiveLayout/ResponsiveLayout.js +1 -1
  32. package/src/js/modules/SelectRow/SelectRow.js +132 -128
@@ -1,4 +1,4 @@
1
- /* Tabulator v5.1.1 (c) Oliver Folkerd 2022 */
1
+ /* Tabulator v5.1.4 (c) Oliver Folkerd 2022 */
2
2
  class CoreFeature{
3
3
 
4
4
  constructor(table){
@@ -2847,6 +2847,8 @@ class Row extends CoreFeature{
2847
2847
 
2848
2848
  this.generateCells();
2849
2849
 
2850
+ this.initialized = true;
2851
+
2850
2852
  this.table.columnManager.renderer.renderRowCells(this);
2851
2853
 
2852
2854
  if(force){
@@ -2855,8 +2857,6 @@ class Row extends CoreFeature{
2855
2857
 
2856
2858
  this.dispatch("row-layout", this);
2857
2859
 
2858
- this.initialized = true;
2859
-
2860
2860
  if(this.table.options.rowFormatter){
2861
2861
  this.table.options.rowFormatter(this.getComponent());
2862
2862
  }
@@ -3324,7 +3324,7 @@ class ColumnCalcs extends Module{
3324
3324
  this.subscribe("row-added", this.rowsUpdated.bind(this));
3325
3325
  this.subscribe("column-moved", this.recalcActiveRows.bind(this));
3326
3326
  this.subscribe("column-add", this.recalcActiveRows.bind(this));
3327
- this.subscribe("data-refreshed", this.recalcActiveRows.bind(this));
3327
+ this.subscribe("data-refreshed", this.recalcActiveRowsRefresh.bind(this));
3328
3328
  this.subscribe("table-redraw", this.tableRedraw.bind(this));
3329
3329
  this.subscribe("rows-visible", this.visibleRows.bind(this));
3330
3330
 
@@ -3372,6 +3372,14 @@ class ColumnCalcs extends Module{
3372
3372
  }
3373
3373
  }
3374
3374
 
3375
+ recalcActiveRowsRefresh(){
3376
+ if(this.table.options.groupBy && this.table.options.dataTreeStartExpanded && this.table.options.dataTree){
3377
+ this.recalcAll();
3378
+ }else {
3379
+ this.recalcActiveRows();
3380
+ }
3381
+ }
3382
+
3375
3383
  recalcActiveRows(){
3376
3384
  this.recalc(this.table.rowManager.activeRows);
3377
3385
  }
@@ -3379,7 +3387,6 @@ class ColumnCalcs extends Module{
3379
3387
  cellValueChanged(cell){
3380
3388
  if(cell.column.definition.topCalc || cell.column.definition.bottomCalc){
3381
3389
  if(this.table.options.groupBy){
3382
-
3383
3390
  if(this.table.options.columnCalcs == "table" || this.table.options.columnCalcs == "both"){
3384
3391
  this.recalcActiveRows();
3385
3392
  }
@@ -3387,7 +3394,6 @@ class ColumnCalcs extends Module{
3387
3394
  if(this.table.options.columnCalcs != "table"){
3388
3395
  this.recalcRowGroup(cell.row);
3389
3396
  }
3390
-
3391
3397
  }else {
3392
3398
  this.recalcActiveRows();
3393
3399
  }
@@ -3559,7 +3565,6 @@ class ColumnCalcs extends Module{
3559
3565
 
3560
3566
  if(this.table.options.groupBy && this.table.options.columnCalcs !== "table"){
3561
3567
 
3562
-
3563
3568
  var groups = this.table.modules.groupRows.getChildGroups();
3564
3569
 
3565
3570
  groups.forEach((group) => {
@@ -7645,7 +7650,8 @@ class Export extends Module{
7645
7650
 
7646
7651
  header.forEach((col) => {
7647
7652
  if(col){
7648
- columns.push(new ExportColumn(col.title, col.column.getComponent(), col.width, col.height, col.depth));
7653
+ let title = typeof col.title === "undefined" ? "" : col.title;
7654
+ columns.push(new ExportColumn(title, col.column.getComponent(), col.width, col.height, col.depth));
7649
7655
  }else {
7650
7656
  columns.push(null);
7651
7657
  }
@@ -7900,10 +7906,10 @@ class Export extends Module{
7900
7906
  rowEl.classList.add("tabulator-print-table-row");
7901
7907
 
7902
7908
  row.columns.forEach((col) => {
7903
-
7904
7909
  if(col){
7905
7910
  var cellEl = document.createElement("td"),
7906
7911
  column = col.component._column,
7912
+ index = this.table.columnManager.findColumnIndex(column),
7907
7913
  value = col.value;
7908
7914
 
7909
7915
  var cellWrapper = {
@@ -7962,8 +7968,8 @@ class Export extends Module{
7962
7968
  cellEl.innerHTML = value;
7963
7969
  }
7964
7970
 
7965
- if(styles.firstCell){
7966
- this.mapElementStyles(styles.firstCell, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom", "border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size"]);
7971
+ if(styles.styleCells[index] || styles.firstCell){
7972
+ this.mapElementStyles(styles.styleCells[index] || styles.firstCell, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom", "border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "text-align"]);
7967
7973
 
7968
7974
  if(column.definition.align){
7969
7975
  cellEl.style.textAlign = column.definition.align;
@@ -8566,7 +8572,9 @@ class Filter extends Module{
8566
8572
  editorElement.addEventListener("focus", (e) => {
8567
8573
  var left = this.table.columnManager.element.scrollLeft;
8568
8574
 
8569
- if(left !== this.table.rowManager.element.scrollLeft){
8575
+ var headerPos = this.table.rowManager.element.scrollLeft + parseInt(this.table.columnManager.element.style.marginLeft);
8576
+
8577
+ if(left !== headerPos){
8570
8578
  this.table.rowManager.scrollHorizontal(left);
8571
8579
  this.table.columnManager.scrollHorizontal(left);
8572
8580
  }
@@ -8738,20 +8746,24 @@ class Filter extends Module{
8738
8746
 
8739
8747
  //add filter to array
8740
8748
  addFilter(field, type, value, params){
8749
+ var changed = false;
8741
8750
 
8742
8751
  if(!Array.isArray(field)){
8743
8752
  field = [{field:field, type:type, value:value, params:params}];
8744
8753
  }
8745
8754
 
8746
8755
  field.forEach((filter) => {
8747
-
8748
8756
  filter = this.findFilter(filter);
8749
8757
 
8750
8758
  if(filter){
8751
8759
  this.filterList.push(filter);
8752
- this.changed = true;
8760
+ changed = true;
8753
8761
  }
8754
8762
  });
8763
+
8764
+ if(changed){
8765
+ this.trackChanges();
8766
+ }
8755
8767
  }
8756
8768
 
8757
8769
  findFilter(filter){
@@ -9523,7 +9535,7 @@ function buttonCross(cell, formatterParams, onRendered){
9523
9535
  }
9524
9536
 
9525
9537
  function rownum(cell, formatterParams, onRendered){
9526
- return this.table.rowManager.activeRows.indexOf(cell.getRow()._getSelf()) + 1;
9538
+ return this.table.rowManager.activeRows.indexOf(cell.getRow()._getSelf()) + 1 || "";
9527
9539
  }
9528
9540
 
9529
9541
  function handle(cell, formatterParams, onRendered){
@@ -9569,9 +9581,12 @@ function responsiveCollapse(cell, formatterParams, onRendered){
9569
9581
 
9570
9582
  function rowSelection(cell, formatterParams, onRendered){
9571
9583
  var checkbox = document.createElement("input");
9584
+ var blocked = false;
9572
9585
 
9573
9586
  checkbox.type = 'checkbox';
9574
9587
 
9588
+ checkbox.setAttribute("aria-label", "Select Row");
9589
+
9575
9590
  if(this.table.modExists("selectRow", true)){
9576
9591
 
9577
9592
  checkbox.addEventListener("click", (e) => {
@@ -9584,9 +9599,24 @@ function rowSelection(cell, formatterParams, onRendered){
9584
9599
  if(row instanceof RowComponent$1){
9585
9600
 
9586
9601
  checkbox.addEventListener("change", (e) => {
9587
- row.toggleSelect();
9602
+ if(this.table.options.selectableRangeMode === "click"){
9603
+ if(!blocked){
9604
+ row.toggleSelect();
9605
+ }else {
9606
+ blocked = false;
9607
+ }
9608
+ }else {
9609
+ row.toggleSelect();
9610
+ }
9588
9611
  });
9589
9612
 
9613
+ if(this.table.options.selectableRangeMode === "click"){
9614
+ checkbox.addEventListener("click", (e) => {
9615
+ blocked = true;
9616
+ this.table.modules.selectRow.handleComplexRowClick(row._row, e);
9617
+ });
9618
+ }
9619
+
9590
9620
  checkbox.checked = row.isSelected && row.isSelected();
9591
9621
  this.table.modules.selectRow.registerRowSelectCheckbox(row, checkbox);
9592
9622
  }else {
@@ -9836,10 +9866,10 @@ Format.moduleName = "format";
9836
9866
  Format.formatters = defaultFormatters;
9837
9867
 
9838
9868
  class FrozenColumns extends Module{
9839
-
9869
+
9840
9870
  constructor(table){
9841
9871
  super(table);
9842
-
9872
+
9843
9873
  this.leftColumns = [];
9844
9874
  this.rightColumns = [];
9845
9875
  this.leftMargin = 0;
@@ -9848,10 +9878,11 @@ class FrozenColumns extends Module{
9848
9878
  this.initializationMode = "left";
9849
9879
  this.active = false;
9850
9880
  this.scrollEndTimer = false;
9851
-
9881
+ this.blocked = true;
9882
+
9852
9883
  this.registerColumnOption("frozen");
9853
9884
  }
9854
-
9885
+
9855
9886
  //reset initial state
9856
9887
  reset(){
9857
9888
  this.initializationMode = "left";
@@ -9861,11 +9892,11 @@ class FrozenColumns extends Module{
9861
9892
  this.rightMargin = 0;
9862
9893
  this.rightMargin = 0;
9863
9894
  this.active = false;
9864
-
9895
+
9865
9896
  this.table.columnManager.headersElement.style.marginLeft = 0;
9866
9897
  this.table.columnManager.element.style.paddingRight = 0;
9867
9898
  }
9868
-
9899
+
9869
9900
  initialize(){
9870
9901
  this.subscribe("cell-layout", this.layoutCell.bind(this));
9871
9902
  this.subscribe("column-init", this.initializeColumn.bind(this));
@@ -9875,176 +9906,194 @@ class FrozenColumns extends Module{
9875
9906
  this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this));
9876
9907
  this.subscribe("columns-loading", this.reset.bind(this));
9877
9908
  this.subscribe("table-redraw", this.layout.bind(this));
9909
+ this.subscribe("layout-refreshing", this.blockLayout.bind(this));
9910
+ this.subscribe("layout-refreshed", this.unblockLayout.bind(this));
9878
9911
  }
9879
-
9912
+
9913
+ blockLayout(){
9914
+ this.blocked = true;
9915
+ }
9916
+
9917
+ unblockLayout(){
9918
+ this.blocked = false;
9919
+ }
9920
+
9880
9921
  layoutCell(cell){
9881
9922
  this.layoutElement(cell.element, cell.column);
9882
9923
  }
9883
-
9924
+
9884
9925
  //initialize specific column
9885
9926
  initializeColumn(column){
9886
9927
  var config = {margin:0, edge:false};
9887
-
9928
+
9888
9929
  if(!column.isGroup){
9889
-
9930
+
9890
9931
  if(this.frozenCheck(column)){
9891
-
9932
+
9892
9933
  config.position = this.initializationMode;
9893
-
9934
+
9894
9935
  if(this.initializationMode == "left"){
9895
9936
  this.leftColumns.push(column);
9896
9937
  }else {
9897
9938
  this.rightColumns.unshift(column);
9898
9939
  }
9899
-
9940
+
9900
9941
  this.active = true;
9901
-
9942
+
9902
9943
  column.modules.frozen = config;
9903
9944
  }else {
9904
9945
  this.initializationMode = "right";
9905
9946
  }
9906
9947
  }
9907
9948
  }
9908
-
9949
+
9909
9950
  frozenCheck(column){
9910
-
9951
+
9911
9952
  if(column.parent.isGroup && column.definition.frozen){
9912
9953
  console.warn("Frozen Column Error - Parent column group must be frozen, not individual columns or sub column groups");
9913
9954
  }
9914
-
9955
+
9915
9956
  if(column.parent.isGroup){
9916
9957
  return this.frozenCheck(column.parent);
9917
9958
  }else {
9918
9959
  return column.definition.frozen;
9919
9960
  }
9920
9961
  }
9921
-
9962
+
9922
9963
  //quick layout to smooth horizontal scrolling
9923
9964
  scrollHorizontal(){
9924
9965
  var rows;
9925
-
9966
+
9926
9967
  if(this.active){
9927
9968
  clearTimeout(this.scrollEndTimer);
9928
9969
 
9929
- //layout all rows after scroll is complete
9930
- this.scrollEndTimer = setTimeout(() => {
9931
- this.layout();
9932
- }, 100);
9933
-
9934
9970
  rows = this.table.rowManager.getVisibleRows();
9935
-
9936
- this.calcMargins();
9937
-
9971
+
9972
+ this.calcMargins(true);
9973
+
9938
9974
  this.layoutColumnPosition();
9939
-
9975
+
9940
9976
  this.layoutCalcRows();
9941
-
9977
+
9942
9978
  rows.forEach((row) => {
9943
9979
  if(row.type === "row"){
9944
9980
  this.layoutRow(row);
9945
9981
  }
9946
9982
  });
9947
-
9948
- this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
9949
9983
  }
9950
9984
  }
9951
-
9985
+
9952
9986
  //calculate margins for rows
9953
- calcMargins(){
9954
- this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px";
9955
- this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
9956
-
9957
- this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px";
9958
- this.table.columnManager.element.style.paddingRight = this.rightMargin;
9959
-
9987
+ calcMargins(scroll){
9988
+
9989
+ if(!scroll){
9990
+ this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px";
9991
+ this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px";
9992
+ this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
9993
+ }
9994
+
9960
9995
  //calculate right frozen columns
9961
9996
  this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft;
9962
9997
  }
9963
-
9998
+
9964
9999
  //layout calculation rows
9965
10000
  layoutCalcRows(){
9966
10001
  if(this.table.modExists("columnCalcs")){
9967
10002
  if(this.table.modules.columnCalcs.topInitialized && this.table.modules.columnCalcs.topRow){
9968
10003
  this.layoutRow(this.table.modules.columnCalcs.topRow);
9969
10004
  }
9970
-
10005
+
9971
10006
  if(this.table.modules.columnCalcs.botInitialized && this.table.modules.columnCalcs.botRow){
9972
10007
  this.layoutRow(this.table.modules.columnCalcs.botRow);
9973
10008
  }
9974
-
10009
+
9975
10010
  if(this.table.modExists("groupRows")){
9976
10011
  this.layoutGroupCalcs(this.table.modules.groupRows.getGroups());
9977
10012
  }
9978
10013
  }
9979
10014
  }
9980
-
10015
+
9981
10016
  layoutGroupCalcs(groups){
9982
10017
  groups.forEach((group) => {
9983
10018
  if(group.calcs.top){
9984
10019
  this.layoutRow(group.calcs.top);
9985
10020
  }
9986
-
10021
+
9987
10022
  if(group.calcs.bottom){
9988
10023
  this.layoutRow(group.calcs.bottom);
9989
10024
  }
9990
-
10025
+
9991
10026
  if(group.groupList && group.groupList.length){
9992
10027
  this.layoutGroupCalcs(group.groupList && group.groupList);
9993
10028
  }
9994
10029
  });
9995
10030
  }
9996
-
10031
+
9997
10032
  //calculate column positions and layout headers
9998
10033
  layoutColumnPosition(allCells){
9999
-
10000
10034
  var leftParents = [];
10035
+
10036
+ var leftMargin = 0;
10037
+ var rightMargin = 0;
10038
+
10039
+ this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
10040
+ this.table.columnManager.element.style.paddingRight = this.rightMargin;
10001
10041
 
10002
- this.leftColumns.forEach((column, i) => {
10003
- column.modules.frozen.margin = (this._calcSpace(this.leftColumns, i) + this.table.columnManager.scrollLeft) + "px";
10042
+ this.leftColumns.forEach((column, i) => {
10043
+ column.modules.frozen.margin = (leftMargin + this.table.columnManager.scrollLeft) + "px";
10004
10044
 
10045
+ if(column.visible){
10046
+ leftMargin += column.getWidth();
10047
+ }
10048
+
10005
10049
  if(i == this.leftColumns.length - 1){
10006
10050
  column.modules.frozen.edge = true;
10007
10051
  }else {
10008
10052
  column.modules.frozen.edge = false;
10009
10053
  }
10010
-
10054
+
10011
10055
  if(column.parent.isGroup){
10012
10056
  var parentEl = this.getColGroupParentElement(column);
10013
10057
  if(!leftParents.includes(parentEl)){
10014
10058
  this.layoutElement(parentEl, column);
10015
10059
  leftParents.push(parentEl);
10016
10060
  }
10017
-
10061
+
10018
10062
  if(column.modules.frozen.edge){
10019
10063
  parentEl.classList.add("tabulator-frozen-" + column.modules.frozen.position);
10020
10064
  }
10021
10065
  }else {
10022
10066
  this.layoutElement(column.getElement(), column);
10023
10067
  }
10024
-
10068
+
10025
10069
  if(allCells){
10026
10070
  column.cells.forEach((cell) => {
10027
10071
  this.layoutElement(cell.getElement(true), column);
10028
10072
  });
10029
10073
  }
10030
10074
  });
10031
-
10075
+
10032
10076
  this.rightColumns.forEach((column, i) => {
10033
- column.modules.frozen.margin = (this.rightPadding - this._calcSpace(this.rightColumns, i + 1)) + "px";
10034
10077
 
10078
+ if(column.visible){
10079
+ rightMargin += column.getWidth();
10080
+ }
10081
+
10082
+ column.modules.frozen.margin = (this.rightPadding - rightMargin) + "px";
10083
+
10035
10084
  if(i == this.rightColumns.length - 1){
10036
10085
  column.modules.frozen.edge = true;
10037
10086
  }else {
10038
10087
  column.modules.frozen.edge = false;
10039
10088
  }
10040
-
10041
-
10089
+
10090
+
10042
10091
  if(column.parent.isGroup){
10043
10092
  this.layoutElement(this.getColGroupParentElement(column), column);
10044
10093
  }else {
10045
10094
  this.layoutElement(column.getElement(), column);
10046
10095
  }
10047
-
10096
+
10048
10097
  if(allCells){
10049
10098
  column.cells.forEach((cell) => {
10050
10099
  this.layoutElement(cell.getElement(true), column);
@@ -10052,79 +10101,79 @@ class FrozenColumns extends Module{
10052
10101
  }
10053
10102
  });
10054
10103
  }
10055
-
10104
+
10056
10105
  getColGroupParentElement(column){
10057
10106
  return column.parent.isGroup ? this.getColGroupParentElement(column.parent) : column.getElement();
10058
10107
  }
10059
-
10060
- //layout columns appropropriatly
10108
+
10109
+ //layout columns appropriately
10061
10110
  layout(){
10062
-
10063
- if(this.active){
10064
-
10111
+ if(this.active && !this.blocked){
10065
10112
  //calculate row padding
10066
10113
  this.calcMargins();
10067
-
10114
+
10068
10115
  this.table.rowManager.getDisplayRows().forEach((row) =>{
10069
10116
  if(row.type === "row"){
10070
10117
  this.layoutRow(row);
10071
10118
  }
10072
10119
  });
10073
-
10120
+
10074
10121
  this.layoutCalcRows();
10075
-
10122
+
10076
10123
  //calculate left columns
10077
10124
  this.layoutColumnPosition(true);
10078
-
10079
- this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
10080
10125
  }
10081
10126
  }
10082
-
10127
+
10083
10128
  layoutRow(row){
10084
10129
  var rowEl = row.getElement();
10085
-
10130
+
10086
10131
  rowEl.style.paddingLeft = this.leftMargin;
10087
-
10132
+
10133
+ if(this.table.options.layout === "fitDataFill" && this.rightColumns.length){
10134
+ this.table.rowManager.getTableElement().style.minWidth = "calc(100% - " + this.rightMargin + ")";
10135
+ }
10136
+
10088
10137
  this.leftColumns.forEach((column) => {
10089
10138
  var cell = row.getCell(column);
10090
-
10139
+
10091
10140
  if(cell){
10092
10141
  this.layoutElement(cell.getElement(true), column);
10093
10142
  }
10094
10143
  });
10095
-
10144
+
10096
10145
  this.rightColumns.forEach((column) => {
10097
10146
  var cell = row.getCell(column);
10098
-
10147
+
10099
10148
  if(cell){
10100
10149
  this.layoutElement(cell.getElement(true), column);
10101
10150
  }
10102
10151
  });
10103
10152
  }
10104
-
10153
+
10105
10154
  layoutElement(element, column){
10106
-
10155
+
10107
10156
  if(column.modules.frozen){
10108
10157
  element.style.position = "absolute";
10109
10158
  element.style.left = column.modules.frozen.margin;
10110
-
10159
+
10111
10160
  element.classList.add("tabulator-frozen");
10112
-
10161
+
10113
10162
  if(column.modules.frozen.edge){
10114
10163
  element.classList.add("tabulator-frozen-" + column.modules.frozen.position);
10115
10164
  }
10116
10165
  }
10117
10166
  }
10118
-
10167
+
10119
10168
  _calcSpace(columns, index){
10120
10169
  var width = 0;
10121
-
10170
+
10122
10171
  for (let i = 0; i < index; i++){
10123
10172
  if(columns[i].visible){
10124
10173
  width += columns[i].getWidth();
10125
10174
  }
10126
10175
  }
10127
-
10176
+
10128
10177
  return width;
10129
10178
  }
10130
10179
  }
@@ -10323,7 +10372,7 @@ class GroupComponent {
10323
10372
 
10324
10373
  //Group functions
10325
10374
  class Group{
10326
-
10375
+
10327
10376
  constructor(groupManager, parent, level, key, field, generator, oldGroup){
10328
10377
  this.groupManager = groupManager;
10329
10378
  this.parent = parent;
@@ -10347,17 +10396,17 @@ class Group{
10347
10396
  this.initialized = false;
10348
10397
  this.modules = {};
10349
10398
  this.arrowElement = false;
10350
-
10399
+
10351
10400
  this.visible = oldGroup ? oldGroup.visible : (typeof groupManager.startOpen[level] !== "undefined" ? groupManager.startOpen[level] : groupManager.startOpen[0]);
10352
-
10401
+
10353
10402
  this.component = null;
10354
-
10403
+
10355
10404
  this.createElements();
10356
10405
  this.addBindings();
10357
-
10406
+
10358
10407
  this.createValueGroups();
10359
10408
  }
10360
-
10409
+
10361
10410
  wipe(){
10362
10411
  if(this.groupList.length){
10363
10412
  this.groupList.forEach(function(group){
@@ -10370,32 +10419,32 @@ class Group{
10370
10419
  }
10371
10420
  });
10372
10421
  }
10373
-
10422
+
10374
10423
  this.element = false;
10375
10424
  this.arrowElement = false;
10376
10425
  this.elementContents = false;
10377
10426
  }
10378
-
10427
+
10379
10428
  createElements(){
10380
10429
  var arrow = document.createElement("div");
10381
10430
  arrow.classList.add("tabulator-arrow");
10382
-
10431
+
10383
10432
  this.element = document.createElement("div");
10384
10433
  this.element.classList.add("tabulator-row");
10385
10434
  this.element.classList.add("tabulator-group");
10386
10435
  this.element.classList.add("tabulator-group-level-" + this.level);
10387
10436
  this.element.setAttribute("role", "rowgroup");
10388
-
10437
+
10389
10438
  this.arrowElement = document.createElement("div");
10390
10439
  this.arrowElement.classList.add("tabulator-group-toggle");
10391
10440
  this.arrowElement.appendChild(arrow);
10392
-
10441
+
10393
10442
  //setup movable rows
10394
10443
  if(this.groupManager.table.options.movableRows !== false && this.groupManager.table.modExists("moveRow")){
10395
10444
  this.groupManager.table.modules.moveRow.initializeGroupHeader(this);
10396
10445
  }
10397
10446
  }
10398
-
10447
+
10399
10448
  createValueGroups(){
10400
10449
  var level = this.level + 1;
10401
10450
  if(this.groupManager.allowedValues && this.groupManager.allowedValues[level]){
@@ -10404,13 +10453,13 @@ class Group{
10404
10453
  });
10405
10454
  }
10406
10455
  }
10407
-
10456
+
10408
10457
  addBindings(){
10409
10458
  var toggleElement;
10410
-
10459
+
10411
10460
  if(this.groupManager.table.options.groupToggleElement){
10412
10461
  toggleElement = this.groupManager.table.options.groupToggleElement == "arrow" ? this.arrowElement : this.element;
10413
-
10462
+
10414
10463
  toggleElement.addEventListener("click", (e) => {
10415
10464
  e.stopPropagation();
10416
10465
  e.stopImmediatePropagation();
@@ -10418,23 +10467,23 @@ class Group{
10418
10467
  });
10419
10468
  }
10420
10469
  }
10421
-
10470
+
10422
10471
  _createGroup(groupID, level){
10423
10472
  var groupKey = level + "_" + groupID;
10424
10473
  var group = new Group(this.groupManager, this, level, groupID, this.groupManager.groupIDLookups[level].field, this.groupManager.headerGenerator[level] || this.groupManager.headerGenerator[0], this.old ? this.old.groups[groupKey] : false);
10425
-
10474
+
10426
10475
  this.groups[groupKey] = group;
10427
10476
  this.groupList.push(group);
10428
10477
  }
10429
-
10478
+
10430
10479
  _addRowToGroup(row){
10431
-
10480
+
10432
10481
  var level = this.level + 1;
10433
-
10482
+
10434
10483
  if(this.hasSubGroups){
10435
10484
  var groupID = this.groupManager.groupIDLookups[level].func(row.getData()),
10436
10485
  groupKey = level + "_" + groupID;
10437
-
10486
+
10438
10487
  if(this.groupManager.allowedValues && this.groupManager.allowedValues[level]){
10439
10488
  if(this.groups[groupKey]){
10440
10489
  this.groups[groupKey].addRow(row);
@@ -10443,24 +10492,24 @@ class Group{
10443
10492
  if(!this.groups[groupKey]){
10444
10493
  this._createGroup(groupID, level);
10445
10494
  }
10446
-
10495
+
10447
10496
  this.groups[groupKey].addRow(row);
10448
10497
  }
10449
10498
  }
10450
10499
  }
10451
-
10500
+
10452
10501
  _addRow(row){
10453
10502
  this.rows.push(row);
10454
10503
  row.modules.group = this;
10455
10504
  }
10456
-
10505
+
10457
10506
  insertRow(row, to, after){
10458
10507
  var data = this.conformRowData({});
10459
-
10508
+
10460
10509
  row.updateData(data);
10461
-
10510
+
10462
10511
  var toIndex = this.rows.indexOf(to);
10463
-
10512
+
10464
10513
  if(toIndex > -1){
10465
10514
  if(after){
10466
10515
  this.rows.splice(toIndex+1, 0, row);
@@ -10474,28 +10523,30 @@ class Group{
10474
10523
  this.rows.unshift(row);
10475
10524
  }
10476
10525
  }
10477
-
10526
+
10478
10527
  row.modules.group = this;
10479
-
10528
+
10480
10529
  this.generateGroupHeaderContents();
10481
-
10530
+
10482
10531
  if(this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table"){
10483
10532
  this.groupManager.table.modules.columnCalcs.recalcGroup(this);
10484
10533
  }
10485
-
10534
+
10486
10535
  this.groupManager.updateGroupRows(true);
10487
10536
  }
10488
-
10537
+
10489
10538
  scrollHeader(left){
10490
- this.arrowElement.style.marginLeft = left;
10491
-
10492
- this.groupList.forEach(function(child){
10493
- child.scrollHeader(left);
10494
- });
10539
+ if(this.arrowElement){
10540
+ this.arrowElement.style.marginLeft = left;
10541
+
10542
+ this.groupList.forEach(function(child){
10543
+ child.scrollHeader(left);
10544
+ });
10545
+ }
10495
10546
  }
10496
-
10547
+
10497
10548
  getRowIndex(row){}
10498
-
10549
+
10499
10550
  //update row data to match grouping contraints
10500
10551
  conformRowData(data){
10501
10552
  if(this.field){
@@ -10503,59 +10554,59 @@ class Group{
10503
10554
  }else {
10504
10555
  console.warn("Data Conforming Error - Cannot conform row data to match new group as groupBy is a function");
10505
10556
  }
10506
-
10557
+
10507
10558
  if(this.parent){
10508
10559
  data = this.parent.conformRowData(data);
10509
10560
  }
10510
-
10561
+
10511
10562
  return data;
10512
10563
  }
10513
-
10564
+
10514
10565
  removeRow(row){
10515
10566
  var index = this.rows.indexOf(row);
10516
10567
  var el = row.getElement();
10517
-
10518
-
10568
+
10569
+
10519
10570
  if(index > -1){
10520
10571
  this.rows.splice(index, 1);
10521
10572
  }
10522
-
10573
+
10523
10574
  if(!this.groupManager.table.options.groupValues && !this.rows.length){
10524
10575
  if(this.parent){
10525
10576
  this.parent.removeGroup(this);
10526
10577
  }else {
10527
10578
  this.groupManager.removeGroup(this);
10528
10579
  }
10529
-
10580
+
10530
10581
  this.groupManager.updateGroupRows(true);
10531
10582
  }else {
10532
-
10583
+
10533
10584
  if(el.parentNode){
10534
10585
  el.parentNode.removeChild(el);
10535
10586
  }
10536
-
10587
+
10537
10588
  this.generateGroupHeaderContents();
10538
10589
 
10539
10590
  if(this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table"){
10540
10591
  this.groupManager.table.modules.columnCalcs.recalcGroup(this);
10541
10592
  }
10542
-
10593
+
10543
10594
  }
10544
10595
  }
10545
-
10596
+
10546
10597
  removeGroup(group){
10547
10598
  var groupKey = group.level + "_" + group.key,
10548
10599
  index;
10549
-
10600
+
10550
10601
  if(this.groups[groupKey]){
10551
10602
  delete this.groups[groupKey];
10552
-
10603
+
10553
10604
  index = this.groupList.indexOf(group);
10554
-
10605
+
10555
10606
  if(index > -1){
10556
10607
  this.groupList.splice(index, 1);
10557
10608
  }
10558
-
10609
+
10559
10610
  if(!this.groupList.length){
10560
10611
  if(this.parent){
10561
10612
  this.parent.removeGroup(this);
@@ -10565,66 +10616,66 @@ class Group{
10565
10616
  }
10566
10617
  }
10567
10618
  }
10568
-
10619
+
10569
10620
  getHeadersAndRows(noCalc){
10570
10621
  var output = [];
10571
-
10622
+
10572
10623
  output.push(this);
10573
-
10624
+
10574
10625
  this._visSet();
10575
-
10626
+
10576
10627
  if(this.visible){
10577
10628
  if(this.groupList.length){
10578
10629
  this.groupList.forEach(function(group){
10579
10630
  output = output.concat(group.getHeadersAndRows(noCalc));
10580
10631
  });
10581
-
10632
+
10582
10633
  }else {
10583
10634
  if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
10584
10635
  if(this.calcs.top){
10585
10636
  this.calcs.top.detachElement();
10586
10637
  this.calcs.top.deleteCells();
10587
10638
  }
10588
-
10639
+
10589
10640
  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
10590
10641
  output.push(this.calcs.top);
10591
10642
  }
10592
-
10643
+
10593
10644
  output = output.concat(this.rows);
10594
-
10645
+
10595
10646
  if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
10596
10647
  if(this.calcs.bottom){
10597
10648
  this.calcs.bottom.detachElement();
10598
10649
  this.calcs.bottom.deleteCells();
10599
10650
  }
10600
-
10651
+
10601
10652
  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
10602
10653
  output.push(this.calcs.bottom);
10603
10654
  }
10604
10655
  }
10605
10656
  }else {
10606
10657
  if(!this.groupList.length && this.groupManager.table.options.columnCalcs != "table"){
10607
-
10658
+
10608
10659
  if(this.groupManager.table.modExists("columnCalcs")){
10609
-
10660
+
10610
10661
  if(!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){
10611
10662
  if(this.calcs.top){
10612
10663
  this.calcs.top.detachElement();
10613
10664
  this.calcs.top.deleteCells();
10614
10665
  }
10615
-
10666
+
10616
10667
  if(this.groupManager.table.options.groupClosedShowCalcs){
10617
10668
  this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
10618
10669
  output.push(this.calcs.top);
10619
10670
  }
10620
10671
  }
10621
-
10672
+
10622
10673
  if(!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){
10623
10674
  if(this.calcs.bottom){
10624
10675
  this.calcs.bottom.detachElement();
10625
10676
  this.calcs.bottom.deleteCells();
10626
10677
  }
10627
-
10678
+
10628
10679
  if(this.groupManager.table.options.groupClosedShowCalcs){
10629
10680
  this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
10630
10681
  output.push(this.calcs.bottom);
@@ -10632,29 +10683,29 @@ class Group{
10632
10683
  }
10633
10684
  }
10634
10685
  }
10635
-
10686
+
10636
10687
  }
10637
-
10688
+
10638
10689
  return output;
10639
10690
  }
10640
-
10691
+
10641
10692
  getData(visible, transform){
10642
10693
  var output = [];
10643
-
10694
+
10644
10695
  this._visSet();
10645
-
10696
+
10646
10697
  if(!visible || (visible && this.visible)){
10647
10698
  this.rows.forEach((row) => {
10648
10699
  output.push(row.getData(transform || "data"));
10649
10700
  });
10650
10701
  }
10651
-
10702
+
10652
10703
  return output;
10653
10704
  }
10654
-
10705
+
10655
10706
  getRowCount(){
10656
10707
  var count = 0;
10657
-
10708
+
10658
10709
  if(this.groupList.length){
10659
10710
  this.groupList.forEach((group) => {
10660
10711
  count += group.getRowCount();
@@ -10664,7 +10715,7 @@ class Group{
10664
10715
  }
10665
10716
  return count;
10666
10717
  }
10667
-
10718
+
10668
10719
  toggleVisibility(){
10669
10720
  if(this.visible){
10670
10721
  this.hide();
@@ -10672,55 +10723,55 @@ class Group{
10672
10723
  this.show();
10673
10724
  }
10674
10725
  }
10675
-
10726
+
10676
10727
  hide(){
10677
10728
  this.visible = false;
10678
-
10729
+
10679
10730
  if(this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination){
10680
-
10731
+
10681
10732
  this.element.classList.remove("tabulator-group-visible");
10682
-
10733
+
10683
10734
  if(this.groupList.length){
10684
10735
  this.groupList.forEach((group) => {
10685
-
10736
+
10686
10737
  var rows = group.getHeadersAndRows();
10687
-
10738
+
10688
10739
  rows.forEach((row) => {
10689
10740
  row.detachElement();
10690
10741
  });
10691
10742
  });
10692
-
10743
+
10693
10744
  }else {
10694
10745
  this.rows.forEach((row) => {
10695
10746
  var rowEl = row.getElement();
10696
10747
  rowEl.parentNode.removeChild(rowEl);
10697
10748
  });
10698
10749
  }
10699
-
10750
+
10700
10751
  this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
10701
-
10752
+
10702
10753
  this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
10703
-
10754
+
10704
10755
  }else {
10705
10756
  this.groupManager.updateGroupRows(true);
10706
10757
  }
10707
-
10758
+
10708
10759
  this.groupManager.table.externalEvents.dispatch("groupVisibilityChanged", this.getComponent(), false);
10709
10760
  }
10710
-
10761
+
10711
10762
  show(){
10712
10763
  this.visible = true;
10713
-
10764
+
10714
10765
  if(this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination){
10715
-
10766
+
10716
10767
  this.element.classList.add("tabulator-group-visible");
10717
-
10768
+
10718
10769
  var prev = this.generateElement();
10719
-
10770
+
10720
10771
  if(this.groupList.length){
10721
10772
  this.groupList.forEach((group) => {
10722
10773
  var rows = group.getHeadersAndRows();
10723
-
10774
+
10724
10775
  rows.forEach((row) => {
10725
10776
  var rowEl = row.getElement();
10726
10777
  prev.parentNode.insertBefore(rowEl, prev.nextSibling);
@@ -10728,7 +10779,7 @@ class Group{
10728
10779
  prev = rowEl;
10729
10780
  });
10730
10781
  });
10731
-
10782
+
10732
10783
  }else {
10733
10784
  this.rows.forEach((row) => {
10734
10785
  var rowEl = row.getElement();
@@ -10737,36 +10788,36 @@ class Group{
10737
10788
  prev = rowEl;
10738
10789
  });
10739
10790
  }
10740
-
10791
+
10741
10792
  this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
10742
-
10793
+
10743
10794
  this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
10744
10795
  }else {
10745
10796
  this.groupManager.updateGroupRows(true);
10746
10797
  }
10747
-
10798
+
10748
10799
  this.groupManager.table.externalEvents.dispatch("groupVisibilityChanged", this.getComponent(), true);
10749
10800
  }
10750
-
10801
+
10751
10802
  _visSet(){
10752
10803
  var data = [];
10753
-
10804
+
10754
10805
  if(typeof this.visible == "function"){
10755
-
10806
+
10756
10807
  this.rows.forEach(function(row){
10757
10808
  data.push(row.getData());
10758
10809
  });
10759
-
10810
+
10760
10811
  this.visible = this.visible(this.key, this.getRowCount(), data, this.getComponent());
10761
10812
  }
10762
10813
  }
10763
-
10814
+
10764
10815
  getRowGroup(row){
10765
10816
  var match = false;
10766
10817
  if(this.groupList.length){
10767
10818
  this.groupList.forEach(function(group){
10768
10819
  var result = group.getRowGroup(row);
10769
-
10820
+
10770
10821
  if(result){
10771
10822
  match = result;
10772
10823
  }
@@ -10778,50 +10829,50 @@ class Group{
10778
10829
  match = this;
10779
10830
  }
10780
10831
  }
10781
-
10832
+
10782
10833
  return match;
10783
10834
  }
10784
-
10835
+
10785
10836
  getSubGroups(component){
10786
10837
  var output = [];
10787
-
10838
+
10788
10839
  this.groupList.forEach(function(child){
10789
10840
  output.push(component ? child.getComponent() : child);
10790
10841
  });
10791
-
10842
+
10792
10843
  return output;
10793
10844
  }
10794
-
10845
+
10795
10846
  getRows(compoment){
10796
10847
  var output = [];
10797
-
10848
+
10798
10849
  this.rows.forEach(function(row){
10799
10850
  output.push(compoment ? row.getComponent() : row);
10800
10851
  });
10801
-
10852
+
10802
10853
  return output;
10803
10854
  }
10804
-
10855
+
10805
10856
  generateGroupHeaderContents(){
10806
10857
  var data = [];
10807
-
10858
+
10808
10859
  this.rows.forEach(function(row){
10809
10860
  data.push(row.getData());
10810
10861
  });
10811
-
10862
+
10812
10863
  this.elementContents = this.generator(this.key, this.getRowCount(), data, this.getComponent());
10813
-
10864
+
10814
10865
  while(this.element.firstChild) this.element.removeChild(this.element.firstChild);
10815
-
10866
+
10816
10867
  if(typeof this.elementContents === "string"){
10817
10868
  this.element.innerHTML = this.elementContents;
10818
10869
  }else {
10819
10870
  this.element.appendChild(this.elementContents);
10820
10871
  }
10821
-
10872
+
10822
10873
  this.element.insertBefore(this.arrowElement, this.element.firstChild);
10823
10874
  }
10824
-
10875
+
10825
10876
  getPath(path = []) {
10826
10877
  path.unshift(this.key);
10827
10878
  if(this.parent) {
@@ -10829,94 +10880,94 @@ class Group{
10829
10880
  }
10830
10881
  return path;
10831
10882
  }
10832
-
10883
+
10833
10884
  ////////////// Standard Row Functions //////////////
10834
-
10885
+
10835
10886
  getElement(){
10836
10887
  return this.elementContents ? this.element : this.generateElement();
10837
10888
  }
10838
-
10889
+
10839
10890
  generateElement(){
10840
10891
  this.addBindings = false;
10841
-
10892
+
10842
10893
  this._visSet();
10843
-
10894
+
10844
10895
  if(this.visible){
10845
10896
  this.element.classList.add("tabulator-group-visible");
10846
10897
  }else {
10847
10898
  this.element.classList.remove("tabulator-group-visible");
10848
10899
  }
10849
-
10900
+
10850
10901
  for(var i = 0; i < this.element.childNodes.length; ++i){
10851
10902
  this.element.childNodes[i].parentNode.removeChild(this.element.childNodes[i]);
10852
10903
  }
10853
-
10904
+
10854
10905
  this.generateGroupHeaderContents();
10855
-
10906
+
10856
10907
  // this.addBindings();
10857
-
10908
+
10858
10909
  return this.element;
10859
10910
  }
10860
-
10911
+
10861
10912
  detachElement(){
10862
10913
  if (this.element && this.element.parentNode){
10863
10914
  this.element.parentNode.removeChild(this.element);
10864
10915
  }
10865
10916
  }
10866
-
10917
+
10867
10918
  //normalize the height of elements in the row
10868
10919
  normalizeHeight(){
10869
10920
  this.setHeight(this.element.clientHeight);
10870
10921
  }
10871
-
10922
+
10872
10923
  initialize(force){
10873
10924
  if(!this.initialized || force){
10874
10925
  this.normalizeHeight();
10875
10926
  this.initialized = true;
10876
10927
  }
10877
10928
  }
10878
-
10929
+
10879
10930
  reinitialize(){
10880
10931
  this.initialized = false;
10881
10932
  this.height = 0;
10882
-
10933
+
10883
10934
  if(Helpers.elVisible(this.element)){
10884
10935
  this.initialize(true);
10885
10936
  }
10886
10937
  }
10887
-
10938
+
10888
10939
  setHeight(height){
10889
10940
  if(this.height != height){
10890
10941
  this.height = height;
10891
10942
  this.outerHeight = this.element.offsetHeight;
10892
10943
  }
10893
10944
  }
10894
-
10945
+
10895
10946
  //return rows outer height
10896
10947
  getHeight(){
10897
10948
  return this.outerHeight;
10898
10949
  }
10899
-
10950
+
10900
10951
  getGroup(){
10901
10952
  return this;
10902
10953
  }
10903
-
10954
+
10904
10955
  reinitializeHeight(){}
10905
-
10956
+
10906
10957
  calcHeight(){}
10907
-
10958
+
10908
10959
  setCellHeight(){}
10909
-
10960
+
10910
10961
  clearCellHeight(){}
10911
-
10962
+
10912
10963
  deinitializeHeight(){}
10913
-
10964
+
10914
10965
  //////////////// Object Generation /////////////////
10915
10966
  getComponent(){
10916
10967
  if(!this.component){
10917
10968
  this.component = new GroupComponent(this);
10918
10969
  }
10919
-
10970
+
10920
10971
  return this.component;
10921
10972
  }
10922
10973
  }
@@ -14210,28 +14261,36 @@ function rows(pageSize, currentRow, currentPage, totalRows, totalPages){
14210
14261
  ofEl = document.createElement("span"),
14211
14262
  totalEl = document.createElement("span"),
14212
14263
  rowsEl = document.createElement("span");
14213
-
14264
+
14214
14265
  this.table.modules.localize.langBind("pagination|counter|showing", (value) => {
14215
14266
  showingEl.innerHTML = value;
14216
14267
  });
14217
-
14218
- valueEl.innerHTML = " " + currentRow + "-" + Math.min((currentRow + pageSize - 1), totalRows) + " ";
14219
-
14268
+
14220
14269
  this.table.modules.localize.langBind("pagination|counter|of", (value) => {
14221
14270
  ofEl.innerHTML = value;
14222
14271
  });
14223
-
14224
- totalEl.innerHTML = " " + totalRows + " ";
14225
-
14272
+
14226
14273
  this.table.modules.localize.langBind("pagination|counter|rows", (value) => {
14227
14274
  rowsEl.innerHTML = value;
14228
14275
  });
14229
-
14230
- el.appendChild(showingEl);
14231
- el.appendChild(valueEl);
14232
- el.appendChild(ofEl);
14233
- el.appendChild(totalEl);
14234
- el.appendChild(rowsEl);
14276
+
14277
+ if(totalRows){
14278
+ valueEl.innerHTML = " " + currentRow + "-" + Math.min((currentRow + pageSize - 1), totalRows) + " ";
14279
+
14280
+ totalEl.innerHTML = " " + totalRows + " ";
14281
+
14282
+ el.appendChild(showingEl);
14283
+ el.appendChild(valueEl);
14284
+ el.appendChild(ofEl);
14285
+ el.appendChild(totalEl);
14286
+ el.appendChild(rowsEl);
14287
+ }else {
14288
+ valueEl.innerHTML = " 0 ";
14289
+
14290
+ el.appendChild(showingEl);
14291
+ el.appendChild(valueEl);
14292
+ el.appendChild(rowsEl);
14293
+ }
14235
14294
 
14236
14295
  return el;
14237
14296
  }
@@ -14335,10 +14394,13 @@ class Page extends Module{
14335
14394
  initialize(){
14336
14395
  if(this.table.options.pagination){
14337
14396
  this.subscribe("row-deleted", this.rowsUpdated.bind(this));
14338
- this.subscribe("row-adding-position", this.rowAddingPosition.bind(this));
14339
14397
  this.subscribe("row-added", this.rowsUpdated.bind(this));
14340
14398
  this.subscribe("data-processed", this.initialLoadComplete.bind(this));
14341
14399
  this.subscribe("table-built", this.calculatePageSizes.bind(this));
14400
+
14401
+ if(this.table.options.paginationAddRow == "page"){
14402
+ this.subscribe("row-adding-position", this.rowAddingPosition.bind(this));
14403
+ }
14342
14404
 
14343
14405
  if(this.table.options.paginationMode === "remote"){
14344
14406
  this.subscribe("data-params", this.remotePageParams.bind(this));
@@ -15118,8 +15180,8 @@ class Page extends Module{
15118
15180
 
15119
15181
  //handle the footer element being redrawn
15120
15182
  footerRedraw(){
15121
- var footer = this.table.footerManager.element;
15122
-
15183
+ var footer = this.table.footerManager.containerElement;
15184
+
15123
15185
  if((Math.ceil(footer.clientWidth) - footer.scrollWidth) < 0){
15124
15186
  this.pagesElement.style.display = 'none';
15125
15187
  }else {
@@ -15152,12 +15214,12 @@ var defaultReaders = {
15152
15214
 
15153
15215
  //if cookie exists, decode and load column data into tabulator
15154
15216
  if(cookiePos > -1){
15155
- cookie = cookie.substr(cookiePos);
15217
+ cookie = cookie.slice(cookiePos);
15156
15218
 
15157
15219
  end = cookie.indexOf(";");
15158
15220
 
15159
15221
  if(end > -1){
15160
- cookie = cookie.substr(0, end);
15222
+ cookie = cookie.slice(0, end);
15161
15223
  }
15162
15224
 
15163
15225
  data = cookie.replace(key + "=", "");
@@ -15309,11 +15371,11 @@ class Persistence extends Module{
15309
15371
  this.subscribe("column-show", this.save.bind(this, "columns"));
15310
15372
  this.subscribe("column-hide", this.save.bind(this, "columns"));
15311
15373
  this.subscribe("column-moved", this.save.bind(this, "columns"));
15312
- this.subscribe("table-built", this.tableBuilt.bind(this), 0);
15313
15374
  }
15314
15375
 
15315
- this.subscribe("table-redraw", this.tableRedraw.bind(this));
15376
+ this.subscribe("table-built", this.tableBuilt.bind(this), 0);
15316
15377
 
15378
+ this.subscribe("table-redraw", this.tableRedraw.bind(this));
15317
15379
 
15318
15380
  this.subscribe("filter-changed", this.eventSave.bind(this, "filter"));
15319
15381
  this.subscribe("sort-changed", this.eventSave.bind(this, "sort"));
@@ -15341,7 +15403,7 @@ class Persistence extends Module{
15341
15403
  sorters = this.load("sort");
15342
15404
 
15343
15405
  if(!sorters === false){
15344
- this.table.initialSort = sorters;
15406
+ this.table.options.initialSort = sorters;
15345
15407
  }
15346
15408
  }
15347
15409
 
@@ -15349,7 +15411,7 @@ class Persistence extends Module{
15349
15411
  filters = this.load("filter");
15350
15412
 
15351
15413
  if(!filters === false){
15352
- this.table.initialFilter = filters;
15414
+ this.table.options.initialFilter = filters;
15353
15415
  }
15354
15416
  }
15355
15417
  }
@@ -15626,6 +15688,8 @@ class Persistence extends Module{
15626
15688
 
15627
15689
  Persistence.moduleName = "persistence";
15628
15690
 
15691
+ Persistence.moduleInitOrder = 1;
15692
+
15629
15693
  //load defaults
15630
15694
  Persistence.readers = defaultReaders;
15631
15695
  Persistence.writers = defaultWriters;
@@ -16092,186 +16156,196 @@ class ReactiveData extends Module{
16092
16156
  ReactiveData.moduleName = "reactiveData";
16093
16157
 
16094
16158
  class ResizeColumns extends Module{
16095
-
16159
+
16096
16160
  constructor(table){
16097
16161
  super(table);
16098
-
16162
+
16099
16163
  this.startColumn = false;
16100
16164
  this.startX = false;
16101
16165
  this.startWidth = false;
16102
16166
  this.handle = null;
16103
16167
  this.prevHandle = null;
16104
-
16168
+
16105
16169
  this.registerColumnOption("resizable", true);
16106
16170
  }
16107
-
16171
+
16108
16172
  initialize(){
16109
16173
  // if(this.table.options.resizableColumns){
16110
- this.subscribe("cell-layout", this.layoutCellHandles.bind(this));
16111
- this.subscribe("column-init", this.layoutColumnHeader.bind(this));
16174
+ this.subscribe("cell-layout", this.layoutCellHandles.bind(this));
16175
+ this.subscribe("column-init", this.layoutColumnHeader.bind(this));
16112
16176
  // }
16113
16177
  }
16114
-
16178
+
16115
16179
  layoutCellHandles(cell){
16116
16180
  if(cell.row.type === "row"){
16117
16181
  this.initializeColumn("cell", cell.column, cell.element);
16118
16182
  }
16119
16183
  }
16120
-
16184
+
16121
16185
  layoutColumnHeader(column){
16122
16186
  this.initializeColumn("header", column, column.element);
16123
16187
  }
16124
-
16188
+
16125
16189
  initializeColumn(type, column, element){
16126
16190
  var self = this,
16127
16191
  variableHeight = false,
16128
16192
  mode = column.definition.resizable;
16129
-
16193
+
16130
16194
  //set column resize mode
16131
16195
  if(type === "header"){
16132
16196
  variableHeight = column.definition.formatter == "textarea" || column.definition.variableHeight;
16133
16197
  column.modules.resize = {variableHeight:variableHeight};
16134
16198
  }
16135
-
16199
+
16136
16200
  if(mode === true || mode == type){
16137
-
16201
+
16138
16202
  var handle = document.createElement('div');
16139
16203
  handle.className = "tabulator-col-resize-handle";
16140
-
16141
-
16204
+
16205
+
16142
16206
  var prevHandle = document.createElement('div');
16143
16207
  prevHandle.className = "tabulator-col-resize-handle prev";
16144
-
16208
+
16145
16209
  handle.addEventListener("click", function(e){
16146
16210
  e.stopPropagation();
16147
16211
  });
16148
-
16212
+
16149
16213
  var handleDown = function(e){
16150
16214
  var nearestColumn = column.getLastColumn();
16151
-
16215
+
16152
16216
  if(nearestColumn && self._checkResizability(nearestColumn)){
16153
16217
  self.startColumn = column;
16154
16218
  self._mouseDown(e, nearestColumn, handle);
16155
16219
  }
16156
16220
  };
16157
-
16221
+
16158
16222
  handle.addEventListener("mousedown", handleDown);
16159
16223
  handle.addEventListener("touchstart", handleDown, {passive: true});
16160
-
16224
+
16161
16225
  //reszie column on double click
16162
16226
  handle.addEventListener("dblclick", function(e){
16163
- var col = column.getLastColumn();
16164
-
16227
+ var col = column.getLastColumn(),
16228
+ oldWidth;
16229
+
16165
16230
  if(col && self._checkResizability(col)){
16231
+ oldWidth = col.getWidth();
16232
+
16166
16233
  e.stopPropagation();
16167
16234
  col.reinitializeWidth(true);
16235
+
16236
+ if(oldWidth !== col.getWidth()){
16237
+ self.dispatch("column-resized", col);
16238
+ self.table.externalEvents.dispatch("columnResized", col.getComponent());
16239
+ }
16168
16240
  }
16169
16241
  });
16170
-
16171
-
16242
+
16243
+
16172
16244
  prevHandle.addEventListener("click", function(e){
16173
16245
  e.stopPropagation();
16174
16246
  });
16175
-
16247
+
16176
16248
  var prevHandleDown = function(e){
16177
16249
  var nearestColumn, colIndex, prevColumn;
16178
-
16250
+
16179
16251
  nearestColumn = column.getFirstColumn();
16180
-
16252
+
16181
16253
  if(nearestColumn){
16182
16254
  colIndex = self.table.columnManager.findColumnIndex(nearestColumn);
16183
16255
  prevColumn = colIndex > 0 ? self.table.columnManager.getColumnByIndex(colIndex - 1) : false;
16184
-
16256
+
16185
16257
  if(prevColumn && self._checkResizability(prevColumn)){
16186
16258
  self.startColumn = column;
16187
16259
  self._mouseDown(e, prevColumn, prevHandle);
16188
16260
  }
16189
16261
  }
16190
16262
  };
16191
-
16263
+
16192
16264
  prevHandle.addEventListener("mousedown", prevHandleDown);
16193
16265
  prevHandle.addEventListener("touchstart", prevHandleDown, {passive: true});
16194
-
16266
+
16195
16267
  //resize column on double click
16196
16268
  prevHandle.addEventListener("dblclick", function(e){
16197
16269
  var nearestColumn, colIndex, prevColumn;
16198
-
16270
+
16199
16271
  nearestColumn = column.getFirstColumn();
16200
-
16272
+
16201
16273
  if(nearestColumn){
16202
16274
  colIndex = self.table.columnManager.findColumnIndex(nearestColumn);
16203
16275
  prevColumn = colIndex > 0 ? self.table.columnManager.getColumnByIndex(colIndex - 1) : false;
16204
-
16276
+
16205
16277
  if(prevColumn && self._checkResizability(prevColumn)){
16206
16278
  e.stopPropagation();
16207
16279
  prevColumn.reinitializeWidth(true);
16208
16280
  }
16209
16281
  }
16210
16282
  });
16211
-
16283
+
16212
16284
  element.appendChild(handle);
16213
16285
  element.appendChild(prevHandle);
16214
16286
  }
16215
16287
  }
16216
-
16288
+
16217
16289
  _checkResizability(column){
16218
16290
  return column.definition.resizable;
16219
16291
  }
16220
-
16292
+
16221
16293
  _mouseDown(e, column, handle){
16222
16294
  var self = this;
16223
-
16295
+
16224
16296
  self.table.element.classList.add("tabulator-block-select");
16225
16297
 
16226
16298
  function mouseMove(e){
16227
16299
  // self.table.columnManager.tempScrollBlock();
16228
-
16300
+
16229
16301
  if(self.table.rtl){
16230
16302
  column.setWidth(self.startWidth - ((typeof e.screenX === "undefined" ? e.touches[0].screenX : e.screenX) - self.startX));
16231
16303
  }else {
16232
16304
  column.setWidth(self.startWidth + ((typeof e.screenX === "undefined" ? e.touches[0].screenX : e.screenX) - self.startX));
16233
16305
  }
16234
-
16306
+
16235
16307
  self.table.columnManager.renderer.rerenderColumns(true);
16236
-
16308
+
16237
16309
  if(!self.table.browserSlow && column.modules.resize && column.modules.resize.variableHeight){
16238
16310
  column.checkCellHeights();
16239
16311
  }
16240
16312
  }
16241
-
16313
+
16242
16314
  function mouseUp(e){
16243
-
16315
+
16244
16316
  //block editor from taking action while resizing is taking place
16245
16317
  if(self.startColumn.modules.edit){
16246
16318
  self.startColumn.modules.edit.blocked = false;
16247
16319
  }
16248
-
16320
+
16249
16321
  if(self.table.browserSlow && column.modules.resize && column.modules.resize.variableHeight){
16250
16322
  column.checkCellHeights();
16251
16323
  }
16252
-
16324
+
16253
16325
  document.body.removeEventListener("mouseup", mouseUp);
16254
16326
  document.body.removeEventListener("mousemove", mouseMove);
16255
-
16327
+
16256
16328
  handle.removeEventListener("touchmove", mouseMove);
16257
16329
  handle.removeEventListener("touchend", mouseUp);
16258
-
16330
+
16259
16331
  self.table.element.classList.remove("tabulator-block-select");
16260
16332
 
16261
- self.dispatch("column-resized", column);
16262
- self.table.externalEvents.dispatch("columnResized", column.getComponent());
16333
+ if(self.startWidth !== column.getWidth()){
16334
+ self.dispatch("column-resized", column);
16335
+ self.table.externalEvents.dispatch("columnResized", column.getComponent());
16336
+ }
16263
16337
  }
16264
-
16338
+
16265
16339
  e.stopPropagation(); //prevent resize from interfereing with movable columns
16266
-
16340
+
16267
16341
  //block editor from taking action while resizing is taking place
16268
16342
  if(self.startColumn.modules.edit){
16269
16343
  self.startColumn.modules.edit.blocked = true;
16270
16344
  }
16271
-
16345
+
16272
16346
  self.startX = typeof e.screenX === "undefined" ? e.touches[0].screenX : e.screenX;
16273
16347
  self.startWidth = column.getWidth();
16274
-
16348
+
16275
16349
  document.body.addEventListener("mousemove", mouseMove);
16276
16350
  document.body.addEventListener("mouseup", mouseUp);
16277
16351
  handle.addEventListener("touchmove", mouseMove, {passive: true});
@@ -16837,7 +16911,7 @@ class ResponsiveLayout extends Module{
16837
16911
  var titleHighlight = document.createElement("strong");
16838
16912
  titleData.appendChild(titleHighlight);
16839
16913
  this.langBind("columns|" + item.field, function(text){
16840
- titleHighlight.innerText = text || item.title;
16914
+ titleHighlight.innerHTML = text || item.title;
16841
16915
  });
16842
16916
 
16843
16917
  if(item.value instanceof Node){
@@ -16860,179 +16934,130 @@ class ResponsiveLayout extends Module{
16860
16934
  ResponsiveLayout.moduleName = "responsiveLayout";
16861
16935
 
16862
16936
  class SelectRow extends Module{
16863
-
16937
+
16864
16938
  constructor(table){
16865
16939
  super(table);
16866
-
16940
+
16867
16941
  this.selecting = false; //flag selecting in progress
16868
16942
  this.lastClickedRow = false; //last clicked row
16869
16943
  this.selectPrev = []; //hold previously selected element for drag drop selection
16870
16944
  this.selectedRows = []; //hold selected rows
16871
16945
  this.headerCheckboxElement = null; // hold header select element
16872
-
16946
+
16873
16947
  this.registerTableOption("selectable", "highlight"); //highlight rows on hover
16874
16948
  this.registerTableOption("selectableRangeMode", "drag"); //highlight rows on hover
16875
16949
  this.registerTableOption("selectableRollingSelection", true); //roll selection once maximum number of selectable rows is reached
16876
16950
  this.registerTableOption("selectablePersistence", true); // maintain selection when table view is updated
16877
16951
  this.registerTableOption("selectableCheck", function(data, row){return true;}); //check wheather row is selectable
16878
-
16952
+
16879
16953
  this.registerTableFunction("selectRow", this.selectRows.bind(this));
16880
16954
  this.registerTableFunction("deselectRow", this.deselectRows.bind(this));
16881
16955
  this.registerTableFunction("toggleSelectRow", this.toggleRow.bind(this));
16882
16956
  this.registerTableFunction("getSelectedRows", this.getSelectedRows.bind(this));
16883
16957
  this.registerTableFunction("getSelectedData", this.getSelectedData.bind(this));
16884
-
16958
+
16885
16959
  //register component functions
16886
16960
  this.registerComponentFunction("row", "select", this.selectRows.bind(this));
16887
16961
  this.registerComponentFunction("row", "deselect", this.deselectRows.bind(this));
16888
16962
  this.registerComponentFunction("row", "toggleSelect", this.toggleRow.bind(this));
16889
16963
  this.registerComponentFunction("row", "isSelected", this.isRowSelected.bind(this));
16890
16964
  }
16891
-
16965
+
16892
16966
  initialize(){
16893
16967
  if(this.table.options.selectable !== false){
16894
16968
  this.subscribe("row-init", this.initializeRow.bind(this));
16895
16969
  this.subscribe("row-deleting", this.rowDeleted.bind(this));
16896
16970
  this.subscribe("rows-wipe", this.clearSelectionData.bind(this));
16897
16971
  this.subscribe("rows-retrieve", this.rowRetrieve.bind(this));
16898
-
16972
+
16899
16973
  if(this.table.options.selectable && !this.table.options.selectablePersistence){
16900
16974
  this.subscribe("data-refreshing", this.deselectRows.bind(this));
16901
16975
  }
16902
16976
  }
16903
16977
  }
16904
-
16978
+
16905
16979
  rowRetrieve(type, prevValue){
16906
16980
  return type === "selected" ? this.selectedRows : prevValue;
16907
16981
  }
16908
-
16982
+
16909
16983
  rowDeleted(row){
16910
16984
  this._deselectRow(row, true);
16911
16985
  }
16912
-
16986
+
16913
16987
  clearSelectionData(silent){
16914
16988
  this.selecting = false;
16915
16989
  this.lastClickedRow = false;
16916
16990
  this.selectPrev = [];
16917
16991
  this.selectedRows = [];
16918
-
16992
+
16919
16993
  if(silent !== true){
16920
16994
  this._rowSelectionChanged();
16921
16995
  }
16922
16996
  }
16923
-
16997
+
16924
16998
  initializeRow(row){
16925
16999
  var self = this,
16926
17000
  element = row.getElement();
16927
-
17001
+
16928
17002
  // trigger end of row selection
16929
17003
  var endSelect = function(){
16930
-
17004
+
16931
17005
  setTimeout(function(){
16932
17006
  self.selecting = false;
16933
17007
  }, 50);
16934
-
17008
+
16935
17009
  document.body.removeEventListener("mouseup", endSelect);
16936
17010
  };
16937
-
17011
+
16938
17012
  row.modules.select = {selected:false};
16939
-
17013
+
16940
17014
  //set row selection class
16941
17015
  if(self.table.options.selectableCheck.call(this.table, row.getComponent())){
16942
17016
  element.classList.add("tabulator-selectable");
16943
17017
  element.classList.remove("tabulator-unselectable");
16944
-
17018
+
16945
17019
  if(self.table.options.selectable && self.table.options.selectable != "highlight"){
16946
17020
  if(self.table.options.selectableRangeMode === "click"){
16947
- element.addEventListener("click", function(e){
16948
- if(e.shiftKey){
16949
- self.table._clearSelection();
16950
- self.lastClickedRow = self.lastClickedRow || row;
16951
-
16952
- var lastClickedRowIdx = self.table.rowManager.getDisplayRowIndex(self.lastClickedRow);
16953
- var rowIdx = self.table.rowManager.getDisplayRowIndex(row);
16954
-
16955
- var fromRowIdx = lastClickedRowIdx <= rowIdx ? lastClickedRowIdx : rowIdx;
16956
- var toRowIdx = lastClickedRowIdx >= rowIdx ? lastClickedRowIdx : rowIdx;
16957
-
16958
- var rows = self.table.rowManager.getDisplayRows().slice(0);
16959
- var toggledRows = rows.splice(fromRowIdx, toRowIdx - fromRowIdx + 1);
16960
-
16961
- if(e.ctrlKey || e.metaKey){
16962
- toggledRows.forEach(function(toggledRow){
16963
- if(toggledRow !== self.lastClickedRow){
16964
-
16965
- if(self.table.options.selectable !== true && !self.isRowSelected(row)){
16966
- if(self.selectedRows.length < self.table.options.selectable){
16967
- self.toggleRow(toggledRow);
16968
- }
16969
- }else {
16970
- self.toggleRow(toggledRow);
16971
- }
16972
- }
16973
- });
16974
- self.lastClickedRow = row;
16975
- }else {
16976
- self.deselectRows(undefined, true);
16977
-
16978
- if(self.table.options.selectable !== true){
16979
- if(toggledRows.length > self.table.options.selectable){
16980
- toggledRows = toggledRows.slice(0, self.table.options.selectable);
16981
- }
16982
- }
16983
-
16984
- self.selectRows(toggledRows);
16985
- }
16986
- self.table._clearSelection();
16987
- }
16988
- else if(e.ctrlKey || e.metaKey){
16989
- self.toggleRow(row);
16990
- self.lastClickedRow = row;
16991
- }else {
16992
- self.deselectRows(undefined, true);
16993
- self.selectRows(row);
16994
- self.lastClickedRow = row;
16995
- }
16996
- });
17021
+ element.addEventListener("click", this.handleComplexRowClick.bind(this, row));
16997
17022
  }else {
16998
17023
  element.addEventListener("click", function(e){
16999
17024
  if(!self.table.modExists("edit") || !self.table.modules.edit.getCurrentCell()){
17000
17025
  self.table._clearSelection();
17001
17026
  }
17002
-
17027
+
17003
17028
  if(!self.selecting){
17004
17029
  self.toggleRow(row);
17005
17030
  }
17006
17031
  });
17007
-
17032
+
17008
17033
  element.addEventListener("mousedown", function(e){
17009
17034
  if(e.shiftKey){
17010
17035
  self.table._clearSelection();
17011
-
17036
+
17012
17037
  self.selecting = true;
17013
-
17038
+
17014
17039
  self.selectPrev = [];
17015
-
17040
+
17016
17041
  document.body.addEventListener("mouseup", endSelect);
17017
17042
  document.body.addEventListener("keyup", endSelect);
17018
-
17043
+
17019
17044
  self.toggleRow(row);
17020
-
17045
+
17021
17046
  return false;
17022
17047
  }
17023
17048
  });
17024
-
17049
+
17025
17050
  element.addEventListener("mouseenter", function(e){
17026
17051
  if(self.selecting){
17027
17052
  self.table._clearSelection();
17028
17053
  self.toggleRow(row);
17029
-
17054
+
17030
17055
  if(self.selectPrev[1] == row){
17031
17056
  self.toggleRow(self.selectPrev[0]);
17032
17057
  }
17033
17058
  }
17034
17059
  });
17035
-
17060
+
17036
17061
  element.addEventListener("mouseout", function(e){
17037
17062
  if(self.selecting){
17038
17063
  self.table._clearSelection();
@@ -17041,13 +17066,64 @@ class SelectRow extends Module{
17041
17066
  });
17042
17067
  }
17043
17068
  }
17044
-
17069
+
17045
17070
  }else {
17046
17071
  element.classList.add("tabulator-unselectable");
17047
17072
  element.classList.remove("tabulator-selectable");
17048
17073
  }
17049
17074
  }
17050
-
17075
+
17076
+ handleComplexRowClick(row, e){
17077
+ if(e.shiftKey){
17078
+ this.table._clearSelection();
17079
+ this.lastClickedRow = this.lastClickedRow || row;
17080
+
17081
+ var lastClickedRowIdx = this.table.rowManager.getDisplayRowIndex(this.lastClickedRow);
17082
+ var rowIdx = this.table.rowManager.getDisplayRowIndex(row);
17083
+
17084
+ var fromRowIdx = lastClickedRowIdx <= rowIdx ? lastClickedRowIdx : rowIdx;
17085
+ var toRowIdx = lastClickedRowIdx >= rowIdx ? lastClickedRowIdx : rowIdx;
17086
+
17087
+ var rows = this.table.rowManager.getDisplayRows().slice(0);
17088
+ var toggledRows = rows.splice(fromRowIdx, toRowIdx - fromRowIdx + 1);
17089
+
17090
+ if(e.ctrlKey || e.metaKey){
17091
+ toggledRows.forEach((toggledRow)=>{
17092
+ if(toggledRow !== this.lastClickedRow){
17093
+
17094
+ if(this.table.options.selectable !== true && !this.isRowSelected(row)){
17095
+ if(this.selectedRows.length < this.table.options.selectable){
17096
+ this.toggleRow(toggledRow);
17097
+ }
17098
+ }else {
17099
+ this.toggleRow(toggledRow);
17100
+ }
17101
+ }
17102
+ });
17103
+ this.lastClickedRow = row;
17104
+ }else {
17105
+ this.deselectRows(undefined, true);
17106
+
17107
+ if(this.table.options.selectable !== true){
17108
+ if(toggledRows.length > this.table.options.selectable){
17109
+ toggledRows = toggledRows.slice(0, this.table.options.selectable);
17110
+ }
17111
+ }
17112
+
17113
+ this.selectRows(toggledRows);
17114
+ }
17115
+ this.table._clearSelection();
17116
+ }
17117
+ else if(e.ctrlKey || e.metaKey){
17118
+ this.toggleRow(row);
17119
+ this.lastClickedRow = row;
17120
+ }else {
17121
+ this.deselectRows(undefined, true);
17122
+ this.selectRows(row);
17123
+ this.lastClickedRow = row;
17124
+ }
17125
+ }
17126
+
17051
17127
  //toggle row selection
17052
17128
  toggleRow(row){
17053
17129
  if(this.table.options.selectableCheck.call(this.table, row.getComponent())){
@@ -17058,24 +17134,24 @@ class SelectRow extends Module{
17058
17134
  }
17059
17135
  }
17060
17136
  }
17061
-
17137
+
17062
17138
  //select a number of rows
17063
17139
  selectRows(rows){
17064
17140
  var rowMatch;
17065
-
17141
+
17066
17142
  switch(typeof rows){
17067
17143
  case "undefined":
17068
17144
  this.table.rowManager.rows.forEach((row) => {
17069
17145
  this._selectRow(row, true, true);
17070
17146
  });
17071
-
17147
+
17072
17148
  this._rowSelectionChanged();
17073
17149
  break;
17074
-
17150
+
17075
17151
  case "string":
17076
-
17152
+
17077
17153
  rowMatch = this.table.rowManager.findRow(rows);
17078
-
17154
+
17079
17155
  if(rowMatch){
17080
17156
  this._selectRow(rowMatch, true, true);
17081
17157
  }else {
@@ -17083,16 +17159,16 @@ class SelectRow extends Module{
17083
17159
  this._selectRow(row, true, true);
17084
17160
  });
17085
17161
  }
17086
-
17162
+
17087
17163
  this._rowSelectionChanged();
17088
17164
  break;
17089
-
17165
+
17090
17166
  default:
17091
17167
  if(Array.isArray(rows)){
17092
17168
  rows.forEach((row) => {
17093
17169
  this._selectRow(row, true, true);
17094
17170
  });
17095
-
17171
+
17096
17172
  this._rowSelectionChanged();
17097
17173
  }else {
17098
17174
  this._selectRow(rows, false, true);
@@ -17100,10 +17176,10 @@ class SelectRow extends Module{
17100
17176
  break;
17101
17177
  }
17102
17178
  }
17103
-
17179
+
17104
17180
  //select an individual row
17105
17181
  _selectRow(rowInfo, silent, force){
17106
-
17182
+
17107
17183
  //handle max row count
17108
17184
  if(!isNaN(this.table.options.selectable) && this.table.options.selectable !== true && !force){
17109
17185
  if(this.selectedRows.length >= this.table.options.selectable){
@@ -17114,29 +17190,29 @@ class SelectRow extends Module{
17114
17190
  }
17115
17191
  }
17116
17192
  }
17117
-
17193
+
17118
17194
  var row = this.table.rowManager.findRow(rowInfo);
17119
-
17195
+
17120
17196
  if(row){
17121
17197
  if(this.selectedRows.indexOf(row) == -1){
17122
17198
  row.getElement().classList.add("tabulator-selected");
17123
17199
  if(!row.modules.select){
17124
17200
  row.modules.select = {};
17125
17201
  }
17126
-
17202
+
17127
17203
  row.modules.select.selected = true;
17128
17204
  if(row.modules.select.checkboxEl){
17129
17205
  row.modules.select.checkboxEl.checked = true;
17130
17206
  }
17131
-
17207
+
17132
17208
  this.selectedRows.push(row);
17133
-
17209
+
17134
17210
  if(this.table.options.dataTreeSelectPropagate){
17135
17211
  this.childRowSelection(row, true);
17136
17212
  }
17137
-
17213
+
17138
17214
  this.dispatchExternal("rowSelected", row.getComponent());
17139
-
17215
+
17140
17216
  this._rowSelectionChanged(silent);
17141
17217
  }
17142
17218
  }else {
@@ -17145,69 +17221,71 @@ class SelectRow extends Module{
17145
17221
  }
17146
17222
  }
17147
17223
  }
17148
-
17224
+
17149
17225
  isRowSelected(row){
17150
17226
  return this.selectedRows.indexOf(row) !== -1;
17151
17227
  }
17152
-
17228
+
17153
17229
  //deselect a number of rows
17154
17230
  deselectRows(rows, silent){
17155
17231
  var self = this,
17156
17232
  rowCount;
17157
17233
 
17158
17234
  if(typeof rows == "undefined"){
17159
-
17235
+
17160
17236
  rowCount = self.selectedRows.length;
17161
-
17237
+
17162
17238
  for(let i = 0; i < rowCount; i++){
17163
17239
  self._deselectRow(self.selectedRows[0], true);
17164
17240
  }
17165
-
17166
- self._rowSelectionChanged(silent);
17167
-
17241
+
17242
+ if(rowCount){
17243
+ self._rowSelectionChanged(silent);
17244
+ }
17245
+
17168
17246
  }else {
17169
17247
  if(Array.isArray(rows)){
17170
17248
  rows.forEach(function(row){
17171
17249
  self._deselectRow(row, true);
17172
17250
  });
17173
-
17251
+
17174
17252
  self._rowSelectionChanged(silent);
17175
17253
  }else {
17176
17254
  self._deselectRow(rows, silent);
17177
17255
  }
17178
17256
  }
17179
17257
  }
17180
-
17258
+
17181
17259
  //deselect an individual row
17182
17260
  _deselectRow(rowInfo, silent){
17183
17261
  var self = this,
17184
17262
  row = self.table.rowManager.findRow(rowInfo),
17185
17263
  index;
17186
-
17264
+
17187
17265
  if(row){
17188
17266
  index = self.selectedRows.findIndex(function(selectedRow){
17189
17267
  return selectedRow == row;
17190
17268
  });
17191
-
17269
+
17192
17270
  if(index > -1){
17193
-
17271
+
17194
17272
  row.getElement().classList.remove("tabulator-selected");
17195
17273
  if(!row.modules.select){
17196
17274
  row.modules.select = {};
17197
17275
  }
17198
-
17276
+
17199
17277
  row.modules.select.selected = false;
17200
17278
  if(row.modules.select.checkboxEl){
17201
17279
  row.modules.select.checkboxEl.checked = false;
17202
17280
  }
17203
17281
  self.selectedRows.splice(index, 1);
17204
-
17282
+
17205
17283
  if(this.table.options.dataTreeSelectPropagate){
17206
17284
  this.childRowSelection(row, false);
17207
17285
  }
17208
-
17286
+
17209
17287
  this.dispatchExternal("rowDeselected", row.getComponent());
17210
-
17288
+
17211
17289
  self._rowSelectionChanged(silent);
17212
17290
  }
17213
17291
  }else {
@@ -17216,28 +17294,28 @@ class SelectRow extends Module{
17216
17294
  }
17217
17295
  }
17218
17296
  }
17219
-
17297
+
17220
17298
  getSelectedData(){
17221
17299
  var data = [];
17222
-
17300
+
17223
17301
  this.selectedRows.forEach(function(row){
17224
17302
  data.push(row.getData());
17225
17303
  });
17226
-
17304
+
17227
17305
  return data;
17228
17306
  }
17229
-
17307
+
17230
17308
  getSelectedRows(){
17231
-
17309
+
17232
17310
  var rows = [];
17233
-
17311
+
17234
17312
  this.selectedRows.forEach(function(row){
17235
17313
  rows.push(row.getComponent());
17236
17314
  });
17237
-
17315
+
17238
17316
  return rows;
17239
17317
  }
17240
-
17318
+
17241
17319
  _rowSelectionChanged(silent){
17242
17320
  if(this.headerCheckboxElement){
17243
17321
  if(this.selectedRows.length === 0){
@@ -17251,27 +17329,27 @@ class SelectRow extends Module{
17251
17329
  this.headerCheckboxElement.checked = false;
17252
17330
  }
17253
17331
  }
17254
-
17332
+
17255
17333
  if(!silent){
17256
17334
  this.dispatchExternal("rowSelectionChanged", this.getSelectedData(), this.getSelectedRows());
17257
17335
  }
17258
17336
  }
17259
-
17337
+
17260
17338
  registerRowSelectCheckbox (row, element) {
17261
17339
  if(!row._row.modules.select){
17262
17340
  row._row.modules.select = {};
17263
17341
  }
17264
-
17342
+
17265
17343
  row._row.modules.select.checkboxEl = element;
17266
17344
  }
17267
-
17345
+
17268
17346
  registerHeaderSelectCheckbox (element) {
17269
17347
  this.headerCheckboxElement = element;
17270
17348
  }
17271
-
17349
+
17272
17350
  childRowSelection(row, select){
17273
17351
  var children = this.table.modules.dataTree.getChildren(row, true);
17274
-
17352
+
17275
17353
  if(select){
17276
17354
  for(let child of children){
17277
17355
  this._selectRow(child, true);
@@ -18934,7 +19012,7 @@ class VirtualDomHorizontal extends Renderer{
18934
19012
  this.vDomScrollPosRight = this.scrollLeft + this.elementVertical.clientWidth + this.window;
18935
19013
 
18936
19014
  var row = this.chain("rows-sample", [1], [], () => {
18937
- return this.table.rowManager.getDisplayRows()[0];
19015
+ return this.table.rowManager.getDisplayRows();
18938
19016
  })[0];
18939
19017
 
18940
19018
  if(row){
@@ -21562,12 +21640,6 @@ class RowManager extends CoreFeature{
21562
21640
  if(!force){
21563
21641
  this.reRenderInPosition();
21564
21642
  this.scrollHorizontal(left);
21565
-
21566
- if(!this.displayRowsCount){
21567
- if(this.table.options.placeholder){
21568
- this.getElement().appendChild(this.table.options.placeholder);
21569
- }
21570
- }
21571
21643
  }else {
21572
21644
  this.renderTable();
21573
21645
  }
@@ -21597,8 +21669,6 @@ class FooterManager extends CoreFeature{
21597
21669
  this.containerElement = this.createContainerElement(); //containing element
21598
21670
  this.external = false;
21599
21671
  this.links = [];
21600
-
21601
- this.initializeElement();
21602
21672
  }
21603
21673
 
21604
21674
  initialize(){
@@ -21630,10 +21700,10 @@ class FooterManager extends CoreFeature{
21630
21700
  switch(typeof this.table.options.footerElement){
21631
21701
  case "string":
21632
21702
  if(this.table.options.footerElement[0] === "<"){
21633
- this.element.innerHTML = this.table.options.footerElement;
21703
+ this.containerElement.innerHTML = this.table.options.footerElement;
21634
21704
  }else {
21635
21705
  this.external = true;
21636
- this.element = document.querySelector(this.table.options.footerElement);
21706
+ this.containerElement = document.querySelector(this.table.options.footerElement);
21637
21707
  }
21638
21708
  break;
21639
21709
 
@@ -21950,7 +22020,7 @@ class InteractionManager extends CoreFeature {
21950
22020
  return row.getElement() === target;
21951
22021
  });
21952
22022
 
21953
- if(targets["row"].parentNode && targets["row"].parentNode.closest(".tabulator-row")){
22023
+ if(targets["row"] && targets["row"].parentNode && targets["row"].parentNode.closest(".tabulator-row")){
21954
22024
  targets[key] = false;
21955
22025
  }
21956
22026
  }
@@ -22840,6 +22910,7 @@ class Layout extends Module{
22840
22910
 
22841
22911
  //trigger table layout
22842
22912
  layout(){
22913
+ this.dispatch("layout-refreshing");
22843
22914
  Layout.modes[this.mode].call(this, this.table.columnManager.columnsByIndex);
22844
22915
 
22845
22916
  this.dispatch("layout-refreshed");
@@ -23187,19 +23258,31 @@ class ModuleBinder {
23187
23258
 
23188
23259
  //ensure that module are bound to instantiated function
23189
23260
  tabulator.prototype.bindModules = function(){
23261
+ var orderedMods = [],
23262
+ unOrderedMods = [];
23263
+
23190
23264
  this.modules = {};
23191
23265
 
23192
23266
  for(var name in tabulator.moduleBindings){
23193
23267
  let mod = tabulator.moduleBindings[name];
23268
+ let module = new mod(this);
23194
23269
 
23195
- this.modules[name] = new mod(this);
23270
+ this.modules[name] = module;
23196
23271
 
23197
23272
  if(mod.prototype.moduleCore){
23198
- this.modulesCore[name] = this.modules[name];
23273
+ this.modulesCore.push(module);
23199
23274
  }else {
23200
- this.modulesRegular[name] = this.modules[name];
23275
+ if(mod.moduleInitOrder){
23276
+ orderedMods.push(module);
23277
+ }else {
23278
+ unOrderedMods.push(module);
23279
+ }
23201
23280
  }
23202
23281
  }
23282
+
23283
+ orderedMods.sort((a, b) => a.moduleInitOrder > b.moduleInitOrder ? 1 : -1);
23284
+
23285
+ this.modulesRegular = orderedMods.concat(unOrderedMods);
23203
23286
  };
23204
23287
  }
23205
23288
 
@@ -23239,8 +23322,8 @@ class Tabulator {
23239
23322
  this.dataLoader = false; //bind component functions
23240
23323
 
23241
23324
  this.modules = {}; //hold all modules bound to this table
23242
- this.modulesCore = {}; //hold core modules bound to this table (for initialization purposes)
23243
- this.modulesRegular = {}; //hold regular modules bound to this table (for initialization purposes)
23325
+ this.modulesCore = []; //hold core modules bound to this table (for initialization purposes)
23326
+ this.modulesRegular = []; //hold regular modules bound to this table (for initialization purposes)
23244
23327
 
23245
23328
  this.optionsList = new OptionsList(this, "table constructor");
23246
23329
 
@@ -23248,7 +23331,7 @@ class Tabulator {
23248
23331
 
23249
23332
  if(this.initializeElement(element)){
23250
23333
 
23251
- this.initialzeCoreSystems(options);
23334
+ this.initializeCoreSystems(options);
23252
23335
 
23253
23336
  //delay table creation to allow event bindings immediately after the constructor
23254
23337
  setTimeout(() => {
@@ -23278,7 +23361,7 @@ class Tabulator {
23278
23361
  }
23279
23362
  }
23280
23363
 
23281
- initialzeCoreSystems(options){
23364
+ initializeCoreSystems(options){
23282
23365
  this.columnManager = new ColumnManager(this);
23283
23366
  this.rowManager = new RowManager(this);
23284
23367
  this.footerManager = new FooterManager(this);
@@ -23298,8 +23381,8 @@ class Tabulator {
23298
23381
  this.interactionMonitor = new InteractionManager(this);
23299
23382
 
23300
23383
  this.dataLoader.initialize();
23301
- this.columnManager.initialize();
23302
- this.rowManager.initialize();
23384
+ // this.columnManager.initialize();
23385
+ // this.rowManager.initialize();
23303
23386
  this.footerManager.initialize();
23304
23387
  }
23305
23388
 
@@ -23368,7 +23451,7 @@ class Tabulator {
23368
23451
  _clearObjectPointers(){
23369
23452
  this.options.columns = this.options.columns.slice(0);
23370
23453
 
23371
- if(this.options.data && !this.options.reactiveData){
23454
+ if(Array.isArray(this.options.data) && !this.options.reactiveData){
23372
23455
  this.options.data = this.options.data.slice(0);
23373
23456
  }
23374
23457
  }
@@ -23437,24 +23520,9 @@ class Tabulator {
23437
23520
  this._detectBrowser();
23438
23521
 
23439
23522
  //initialize core modules
23440
- for (let key in this.modulesCore){
23441
- let mod = this.modulesCore[key];
23442
-
23523
+ this.modulesCore.forEach((mod) => {
23443
23524
  mod.initialize();
23444
- }
23445
-
23446
- //configure placeholder element
23447
- if(typeof options.placeholder == "string"){
23448
- var el = document.createElement("div");
23449
- el.classList.add("tabulator-placeholder");
23450
-
23451
- var span = document.createElement("span");
23452
- span.innerHTML = options.placeholder;
23453
-
23454
- el.appendChild(span);
23455
-
23456
- options.placeholder = el;
23457
- }
23525
+ });
23458
23526
 
23459
23527
  //build table elements
23460
23528
  element.appendChild(this.columnManager.getElement());
@@ -23470,11 +23538,9 @@ class Tabulator {
23470
23538
  }
23471
23539
 
23472
23540
  //initialize regular modules
23473
- for (let key in this.modulesRegular){
23474
- let mod = this.modulesRegular[key];
23475
-
23541
+ this.modulesRegular.forEach((mod) => {
23476
23542
  mod.initialize();
23477
- }
23543
+ });
23478
23544
 
23479
23545
  this.columnManager.setColumns(options.columns);
23480
23546
 
@@ -23524,7 +23590,7 @@ class Tabulator {
23524
23590
  this.browserSlow = false;
23525
23591
  }
23526
23592
 
23527
- 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));
23593
+ 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.slice(0,4));
23528
23594
  }
23529
23595
 
23530
23596
  ////////////////// Data Handling //////////////////