tabulator-tables 5.1.7 → 5.2.1

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 (103) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +3 -2
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +1 -1
  3. package/bower.json +1 -1
  4. package/dist/css/tabulator.css +64 -51
  5. package/dist/css/tabulator.css.map +1 -1
  6. package/dist/css/tabulator.min.css +1 -1
  7. package/dist/css/tabulator.min.css.map +1 -1
  8. package/dist/css/tabulator_bootstrap3.css +64 -51
  9. package/dist/css/tabulator_bootstrap3.css.map +1 -1
  10. package/dist/css/tabulator_bootstrap3.min.css +1 -1
  11. package/dist/css/tabulator_bootstrap3.min.css.map +1 -1
  12. package/dist/css/tabulator_bootstrap4.css +64 -51
  13. package/dist/css/tabulator_bootstrap4.css.map +1 -1
  14. package/dist/css/tabulator_bootstrap4.min.css +1 -1
  15. package/dist/css/tabulator_bootstrap4.min.css.map +1 -1
  16. package/dist/css/tabulator_bootstrap5.css +1580 -0
  17. package/dist/css/tabulator_bootstrap5.css.map +1 -0
  18. package/dist/css/tabulator_bootstrap5.min.css +2 -0
  19. package/dist/css/tabulator_bootstrap5.min.css.map +1 -0
  20. package/dist/css/tabulator_bulma.css +64 -51
  21. package/dist/css/tabulator_bulma.css.map +1 -1
  22. package/dist/css/tabulator_bulma.min.css +1 -1
  23. package/dist/css/tabulator_bulma.min.css.map +1 -1
  24. package/dist/css/tabulator_materialize.css +64 -51
  25. package/dist/css/tabulator_materialize.css.map +1 -1
  26. package/dist/css/tabulator_materialize.min.css +1 -1
  27. package/dist/css/tabulator_materialize.min.css.map +1 -1
  28. package/dist/css/tabulator_midnight.css +64 -51
  29. package/dist/css/tabulator_midnight.css.map +1 -1
  30. package/dist/css/tabulator_midnight.min.css +1 -1
  31. package/dist/css/tabulator_midnight.min.css.map +1 -1
  32. package/dist/css/tabulator_modern.css +64 -51
  33. package/dist/css/tabulator_modern.css.map +1 -1
  34. package/dist/css/tabulator_modern.min.css +1 -1
  35. package/dist/css/tabulator_modern.min.css.map +1 -1
  36. package/dist/css/tabulator_semanticui.css +64 -51
  37. package/dist/css/tabulator_semanticui.css.map +1 -1
  38. package/dist/css/tabulator_semanticui.min.css +1 -1
  39. package/dist/css/tabulator_semanticui.min.css.map +1 -1
  40. package/dist/css/tabulator_simple.css +64 -51
  41. package/dist/css/tabulator_simple.css.map +1 -1
  42. package/dist/css/tabulator_simple.min.css +1 -1
  43. package/dist/css/tabulator_simple.min.css.map +1 -1
  44. package/dist/css/tabulator_site.css +64 -51
  45. package/dist/css/tabulator_site.css.map +1 -1
  46. package/dist/css/tabulator_site.min.css +1 -1
  47. package/dist/css/tabulator_site.min.css.map +1 -1
  48. package/dist/js/tabulator.js +2543 -1658
  49. package/dist/js/tabulator.js.map +1 -1
  50. package/dist/js/tabulator.min.js +2 -2
  51. package/dist/js/tabulator.min.js.map +1 -1
  52. package/dist/js/tabulator_esm.js +2746 -2069
  53. package/dist/js/tabulator_esm.js.map +1 -1
  54. package/dist/js/tabulator_esm.min.js +2 -2
  55. package/dist/js/tabulator_esm.min.js.map +1 -1
  56. package/package.json +1 -1
  57. package/src/js/core/FooterManager.js +6 -13
  58. package/src/js/core/Module.js +44 -2
  59. package/src/js/core/Tabulator.js +341 -289
  60. package/src/js/core/cell/Cell.js +9 -38
  61. package/src/js/core/column/Column.js +8 -44
  62. package/src/js/core/column/defaults/options.js +0 -2
  63. package/src/js/core/defaults/options.js +5 -2
  64. package/src/js/core/modules/optional.js +2 -0
  65. package/src/js/core/row/Row.js +127 -118
  66. package/src/js/core/tools/Alert.js +63 -0
  67. package/src/js/core/tools/ComponentFunctionBinder.js +3 -3
  68. package/src/js/core/tools/DataLoader.js +12 -84
  69. package/src/js/core/tools/InteractionMonitor.js +1 -1
  70. package/src/js/core/tools/ModuleBinder.js +30 -23
  71. package/src/js/core/tools/Popup.js +251 -0
  72. package/src/js/modules/ColumnCalcs/ColumnCalcs.js +2 -2
  73. package/src/js/modules/Edit/Edit.js +6 -25
  74. package/src/js/modules/Edit/List.js +997 -0
  75. package/src/js/modules/Edit/defaults/editors/autocomplete.js +6 -446
  76. package/src/js/modules/Edit/defaults/editors/input.js +4 -0
  77. package/src/js/modules/Edit/defaults/editors/list.js +7 -0
  78. package/src/js/modules/Edit/defaults/editors/number.js +4 -0
  79. package/src/js/modules/Edit/defaults/editors/select.js +5 -584
  80. package/src/js/modules/Edit/defaults/editors/textarea.js +4 -0
  81. package/src/js/modules/Edit/defaults/editors/tickCross.js +17 -5
  82. package/src/js/modules/Edit/defaults/editors.js +2 -0
  83. package/src/js/modules/Filter/Filter.js +7 -4
  84. package/src/js/modules/Format/defaults/formatters/datetime.js +10 -4
  85. package/src/js/modules/Format/defaults/formatters/datetimediff.js +10 -3
  86. package/src/js/modules/Format/defaults/formatters/link.js +12 -1
  87. package/src/js/modules/Format/defaults/formatters/money.js +5 -3
  88. package/src/js/modules/Format/defaults/formatters/tickCross.js +2 -1
  89. package/src/js/modules/FrozenColumns/FrozenColumns.js +30 -8
  90. package/src/js/modules/HtmlTableImport/HtmlTableImport.js +5 -1
  91. package/src/js/modules/Menu/Menu.js +59 -157
  92. package/src/js/modules/Mutator/Mutator.js +20 -0
  93. package/src/js/modules/Page/Page.js +7 -3
  94. package/src/js/modules/Persistence/Persistence.js +1 -1
  95. package/src/js/modules/Popup/Popup.js +194 -0
  96. package/src/js/modules/ResizeColumns/ResizeColumns.js +138 -81
  97. package/src/js/modules/Sort/defaults/sorters/datetime.js +15 -2
  98. package/src/js/modules/Tooltip/Tooltip.js +132 -0
  99. package/src/js/modules/Validate/Validate.js +107 -71
  100. package/src/scss/tabulator.scss +354 -349
  101. package/src/scss/themes/bootstrap/functions5.scss +302 -0
  102. package/src/scss/themes/bootstrap/tabulator_bootstrap5.scss +546 -0
  103. package/src/scss/themes/bootstrap/variables5.scss +1641 -0
@@ -4,55 +4,11 @@ export default class DataLoader extends CoreFeature{
4
4
  constructor(table){
5
5
  super(table);
6
6
 
7
- this.loaderElement = this.createLoaderElement(); //loader message div
8
- this.msgElement = this.createMsgElement(); //message element
9
- this.loadingElement = null;
10
- this.errorElement = null;
11
-
12
- this.requestOrder = 0; //prevent requests comming out of sequence if overridden by another load request
7
+ this.requestOrder = 0; //prevent requests coming out of sequence if overridden by another load request
13
8
  this.loading = false;
14
9
  }
15
10
 
16
- initialize(){
17
- var template;
18
-
19
- this.loaderElement.appendChild(this.msgElement);
20
-
21
- if(this.table.options.dataLoaderLoading){
22
- if(typeof this.table.options.dataLoaderLoading == "string"){
23
- template = document.createElement('template');
24
- template.innerHTML = this.table.options.dataLoaderLoading.trim();
25
- this.loadingElement = template.firstElementChild;
26
- }else{
27
- this.loadingElement = this.table.options.dataLoaderLoading;
28
- }
29
- }
30
-
31
- if(this.table.options.dataLoaderError){
32
- if(typeof this.table.options.dataLoaderError == "string"){
33
- template = document.createElement('template');
34
- template.innerHTML = this.table.options.dataLoaderError.trim();
35
- this.errorElement = template.firstElementChild;
36
- }else{
37
- this.errorElement = this.table.options.dataLoaderError;
38
- }
39
- }
40
- }
41
-
42
- createLoaderElement(){
43
- var el = document.createElement("div");
44
- el.classList.add("tabulator-loader");
45
- return el;
46
- }
47
-
48
- createMsgElement(){
49
- var el = document.createElement("div");
50
-
51
- el.classList.add("tabulator-loader-msg");
52
- el.setAttribute("role", "alert");
53
-
54
- return el;
55
- }
11
+ initialize(){}
56
12
 
57
13
  load(data, params, config, replace, silent){
58
14
  var requestNo = ++this.requestOrder;
@@ -68,7 +24,7 @@ export default class DataLoader extends CoreFeature{
68
24
  this.loading = true;
69
25
 
70
26
  if(!silent){
71
- this.showLoader();
27
+ this.alertLoader();
72
28
  }
73
29
 
74
30
  //get params for request
@@ -86,7 +42,7 @@ export default class DataLoader extends CoreFeature{
86
42
  var rowData = this.chain("data-loaded", response, null, response);
87
43
 
88
44
  if(requestNo == this.requestOrder){
89
- this.hideLoader();
45
+ this.clearAlert();
90
46
 
91
47
  if(rowData !== false){
92
48
  this.dispatchExternal("dataLoaded", rowData);
@@ -100,11 +56,11 @@ export default class DataLoader extends CoreFeature{
100
56
  this.dispatchExternal("dataLoadError", error);
101
57
 
102
58
  if(!silent){
103
- this.showError();
59
+ this.alertError();
104
60
  }
105
61
 
106
62
  setTimeout(() => {
107
- this.hideLoader();
63
+ this.clearAlert();
108
64
  }, this.table.options.dataLoaderErrorTimeout);
109
65
  })
110
66
  .finally(() => {
@@ -146,47 +102,19 @@ export default class DataLoader extends CoreFeature{
146
102
  this.requestOrder++;
147
103
  }
148
104
 
149
- showLoader(){
105
+ alertLoader(){
150
106
  var shouldLoad = typeof this.table.options.dataLoader === "function" ? this.table.options.dataLoader() : this.table.options.dataLoader;
151
107
 
152
108
  if(shouldLoad){
153
- this.hideLoader();
154
-
155
- while(this.msgElement.firstChild) this.msgElement.removeChild(this.msgElement.firstChild);
156
-
157
- this.msgElement.classList.remove("tabulator-error");
158
- this.msgElement.classList.add("tabulator-loading");
159
-
160
- if(this.loadingElement){
161
- this.msgElement.appendChild(this.loadingElement);
162
- }else{
163
- this.msgElement.innerHTML = this.langText("data|loading");
164
- }
165
-
166
- this.table.element.appendChild(this.loaderElement);
109
+ this.table.alertManager.alert(this.table.options.dataLoaderLoading || this.langText("data|loading"));
167
110
  }
168
111
  }
169
112
 
170
- showError(){
171
- this.hideLoader();
172
-
173
- while(this.msgElement.firstChild) this.msgElement.removeChild(this.msgElement.firstChild);
174
- this.msgElement.classList.remove("tabulator-loading");
175
- this.msgElement.classList.add("tabulator-error");
176
-
177
- if(this.errorElement){
178
- this.msgElement.appendChild(this.errorElement);
179
- }else{
180
- this.msgElement.innerHTML = this.langText("data|error");
181
- }
182
-
183
- this.table.element.appendChild(this.loaderElement);
113
+ alertError(){
114
+ this.table.alertManager.alert(this.table.options.dataLoaderError || this.langText("data|error"), "error");
184
115
  }
185
116
 
186
-
187
- hideLoader(){
188
- if(this.loaderElement.parentNode){
189
- this.loaderElement.parentNode.removeChild(this.loaderElement);
190
- }
117
+ clearAlert(){
118
+ this.table.alertManager.clear();
191
119
  }
192
120
  }
@@ -88,7 +88,7 @@ export default class InteractionManager extends CoreFeature {
88
88
  if(this.pseudoTrackers[key].target !== target){
89
89
 
90
90
  if(this.pseudoTrackers[key].target){
91
- this.dispatch(key + "-mouseleave", e, target);
91
+ this.dispatch(key + "-mouseleave", e, this.pseudoTrackers[key].target);
92
92
  }
93
93
 
94
94
  this.pseudoMouseLeave(key, e);
@@ -2,23 +2,23 @@ import * as coreModules from '../modules/core.js';
2
2
  import TableRegistry from './TableRegistry.js';
3
3
 
4
4
  export default class ModuleBinder {
5
-
5
+
6
6
  constructor(tabulator, modules){
7
7
  this.bindStaticFuctionality(tabulator);
8
8
  this.bindModules(tabulator, coreModules, true);
9
-
9
+
10
10
  if(modules){
11
11
  this.bindModules(tabulator, modules);
12
12
  }
13
13
  }
14
-
14
+
15
15
  bindStaticFuctionality(tabulator){
16
16
  tabulator.moduleBindings = {};
17
-
17
+
18
18
  tabulator.extendModule = function(name, property, values){
19
19
  if(tabulator.moduleBindings[name]){
20
20
  var source = tabulator.moduleBindings[name][property];
21
-
21
+
22
22
  if(source){
23
23
  if(typeof values == "object"){
24
24
  for(let key in values){
@@ -34,65 +34,72 @@ export default class ModuleBinder {
34
34
  console.warn("Module Error - module does not exist:", name);
35
35
  }
36
36
  };
37
-
37
+
38
38
  tabulator.registerModule = function(modules){
39
39
  if(!Array.isArray(modules)){
40
40
  modules = [modules];
41
41
  }
42
-
42
+
43
43
  modules.forEach((mod) => {
44
44
  tabulator.registerModuleBinding(mod)
45
45
  });
46
46
  }
47
-
47
+
48
48
  tabulator.registerModuleBinding = function(mod){
49
49
  tabulator.moduleBindings[mod.moduleName] = mod;
50
50
  };
51
-
51
+
52
52
  tabulator.findTable = function(query){
53
53
  var results = TableRegistry.lookupTable(query, true);
54
54
  return Array.isArray(results) && !results.length ? false : results;
55
55
  }
56
-
56
+
57
57
  //ensure that module are bound to instantiated function
58
58
  tabulator.prototype.bindModules = function(){
59
- var orderedMods = [],
59
+ var orderedStartMods = [],
60
+ orderedEndMods = [],
60
61
  unOrderedMods = [];
61
-
62
+
62
63
  this.modules = {};
63
-
64
+
64
65
  for(var name in tabulator.moduleBindings){
65
66
  let mod = tabulator.moduleBindings[name];
66
67
  let module = new mod(this);
67
-
68
+
68
69
  this.modules[name] = module;
69
-
70
+
70
71
  if(mod.prototype.moduleCore){
71
72
  this.modulesCore.push(module);
72
73
  }else{
73
74
  if(mod.moduleInitOrder){
74
- orderedMods.push(module);
75
+ if(mod.moduleInitOrder < 0){
76
+ orderedStartMods.push(module);
77
+ }else{
78
+ orderedEndMods.push(module);
79
+ }
80
+
75
81
  }else{
76
82
  unOrderedMods.push(module);
77
83
  }
78
84
  }
79
85
  }
80
-
81
- orderedMods.sort((a, b) => a.moduleInitOrder > b.moduleInitOrder ? 1 : -1);
82
-
83
- this.modulesRegular = orderedMods.concat(unOrderedMods);
86
+
87
+ orderedStartMods.sort((a, b) => a.moduleInitOrder > b.moduleInitOrder ? 1 : -1);
88
+ orderedEndMods.sort((a, b) => a.moduleInitOrder > b.moduleInitOrder ? 1 : -1);
89
+
90
+ this.modulesRegular = orderedStartMods.concat(unOrderedMods.concat(orderedEndMods));
84
91
  }
85
92
  }
86
-
93
+
87
94
  bindModules(tabulator, modules, core){
88
95
  var mods = Object.values(modules);
89
-
96
+
90
97
  if(core){
91
98
  mods.forEach((mod) => {
92
99
  mod.prototype.moduleCore = true;
93
100
  });
94
101
  }
95
-
102
+
96
103
  tabulator.registerModule(mods);
97
104
  }
98
105
  }
@@ -0,0 +1,251 @@
1
+ import CoreFeature from '../CoreFeature.js';
2
+ import Helpers from './Helpers.js';
3
+
4
+ export default class Popup extends CoreFeature{
5
+ constructor(table, element, parent){
6
+ super(table);
7
+
8
+ this.element = element;
9
+ this.container = this._lookupContainer();
10
+
11
+ this.parent = parent;
12
+
13
+ this.reversedX = false;
14
+ this.childPopup = null;
15
+ this.blurable = false;
16
+ this.blurCallback = null;
17
+ this.renderedCallback = null;
18
+
19
+ this.visible = false;
20
+
21
+ this.element.classList.add("tabulator-popup-container");
22
+
23
+ this.blurEvent = this.hide.bind(this, false);
24
+ this.escEvent = this._escapeCheck.bind(this);
25
+ }
26
+
27
+ _lookupContainer(){
28
+ var container = this.table.options.popupContainer;
29
+
30
+ if(typeof container === "string"){
31
+ container = document.querySelector(container);
32
+
33
+ if(!container){
34
+ console.warn("Menu Error - no container element found matching selector:", this.table.options.popupContainer , "(defaulting to document body)");
35
+ }
36
+ }else if (container === true){
37
+ container = this.table.element;
38
+ }
39
+
40
+ if(container && !this._checkContainerIsParent(container)){
41
+ container = false;
42
+ console.warn("Menu Error - container element does not contain this table:", this.table.options.popupContainer , "(defaulting to document body)");
43
+ }
44
+
45
+ if(!container){
46
+ container = document.body;
47
+ }
48
+
49
+ return container;
50
+ }
51
+
52
+ _checkContainerIsParent(container, element = this.table.element){
53
+ if(container === element){
54
+ return true;
55
+ }else{
56
+ return element.parentNode ? this._checkContainerIsParent(container, element.parentNode) : false;
57
+ }
58
+ }
59
+
60
+ renderCallback(callback){
61
+ this.renderedCallback = callback;
62
+ }
63
+
64
+ containerEventCoords(e){
65
+ var touch = !(e instanceof MouseEvent);
66
+
67
+ var x = touch ? e.touches[0].pageX : e.pageX;
68
+ var y = touch ? e.touches[0].pageY : e.pageY;
69
+
70
+ if(this.container !== document.body){
71
+ let parentOffset = Helpers.elOffset(this.container);
72
+
73
+ x -= parentOffset.left;
74
+ y -= parentOffset.top;
75
+ }
76
+
77
+ return {x, y};
78
+ }
79
+
80
+ elementPositionCoords(element, position = "right"){
81
+ var offset = Helpers.elOffset(element),
82
+ containerOffset, x, y;
83
+
84
+ if(this.container !== document.body){
85
+ containerOffset = Helpers.elOffset(this.container);
86
+
87
+ offset.left -= containerOffset.left;
88
+ offset.top -= containerOffset.top;
89
+ }
90
+
91
+ switch(position){
92
+ case "right":
93
+ x = offset.left + element.offsetWidth;
94
+ y = offset.top - 1;
95
+ break;
96
+
97
+ case "bottom":
98
+ x = offset.left;
99
+ y = offset.top + element.offsetHeight;
100
+ break;
101
+ }
102
+
103
+ return {x, y, offset};
104
+ }
105
+
106
+ show(origin, position){
107
+ var x, y, parentEl, parentOffset, containerOffset, coords;
108
+
109
+ if(origin instanceof HTMLElement){
110
+ parentEl = origin;
111
+ coords = this.elementPositionCoords(origin, position);
112
+
113
+ parentOffset = coords.offset;
114
+ x = coords.x;
115
+ y = coords.y;
116
+
117
+ }else if(typeof origin === "number"){
118
+ parentOffset = {top:0, left:0};
119
+ x = origin;
120
+ y = position;
121
+ }else{
122
+ coords = this.containerEventCoords(origin);
123
+
124
+ x = coords.x;
125
+ y = coords.y;
126
+
127
+ this.reversedX = false;
128
+ }
129
+
130
+ this.element.style.top = y + "px";
131
+ this.element.style.left = x + "px";
132
+
133
+ this.container.appendChild(this.element);
134
+
135
+ if(typeof this.renderedCallback === "function"){
136
+ this.renderedCallback();
137
+ }
138
+
139
+ this._fitToScreen(x, y, parentEl, parentOffset, position);
140
+
141
+ this.visible = true;
142
+
143
+ return this;
144
+ }
145
+
146
+ _fitToScreen(x, y, parentEl, parentOffset, position){
147
+ var scrollTop = this.container === document.body ? document.documentElement.scrollTop : this.container.scrollTop;
148
+
149
+ //move menu to start on right edge if it is too close to the edge of the screen
150
+ if((x + this.element.offsetWidth) >= this.container.offsetWidth || this.reversedX){
151
+ this.element.style.left = "";
152
+
153
+ if(parentEl){
154
+ this.element.style.right = (this.container.offsetWidth - parentOffset.left) + "px";
155
+ }else{
156
+ this.element.style.right = (this.container.offsetWidth - x) + "px";
157
+ }
158
+
159
+ this.reversedX = true;
160
+ }
161
+
162
+ //move menu to start on bottom edge if it is too close to the edge of the screen
163
+ if((y + this.element.offsetHeight) > Math.max(this.container.offsetHeight, scrollTop ? this.container.scrollHeight : 0)) {
164
+ if(parentEl){
165
+ switch(position){
166
+ case "bottom":
167
+ this.element.style.top = (parseInt(this.element.style.top) - this.element.offsetHeight - parentEl.offsetHeight - 1) + "px";
168
+ break;
169
+
170
+ default:
171
+ this.element.style.top = (parseInt(this.element.style.top) - this.element.offsetHeight + parentEl.offsetHeight + 1) + "px";
172
+ }
173
+
174
+ }else{
175
+ this.element.style.top = (parseInt(this.element.style.top) - this.element.offsetHeight) + "px";
176
+ }
177
+ }
178
+ }
179
+
180
+ isVisible(){
181
+ return this.visible;
182
+ }
183
+
184
+ hideOnBlur(callback){
185
+ this.blurable = true;
186
+
187
+ if(this.visible){
188
+ setTimeout(() => {
189
+ this.table.rowManager.element.addEventListener("scroll", this.blurEvent);
190
+ this.subscribe("cell-editing", this.blurEvent);
191
+ document.body.addEventListener("click", this.blurEvent);
192
+ document.body.addEventListener("contextmenu", this.blurEvent);
193
+ window.addEventListener("resize", this.blurEvent);
194
+ document.body.addEventListener("keydown", this.escEvent);
195
+ }, 100);
196
+
197
+ this.blurCallback = callback;
198
+ }
199
+
200
+ return this;
201
+ }
202
+
203
+ _escapeCheck(e){
204
+ if(e.keyCode == 27){
205
+ this.hide();
206
+ }
207
+ }
208
+
209
+ hide(silent = false){
210
+ if(this.visible){
211
+ if(this.blurable){
212
+ document.body.removeEventListener("keydown", this.escEvent);
213
+ document.body.removeEventListener("click", this.blurEvent);
214
+ document.body.removeEventListener("contextmenu", this.blurEvent);
215
+ window.removeEventListener("resize", this.blurEvent);
216
+ this.table.rowManager.element.removeEventListener("scroll", this.blurEvent);
217
+ this.unsubscribe("cell-editing", this.blurEvent);
218
+ }
219
+
220
+ if(this.childPopup){
221
+ this.childPopup.hide();
222
+ }
223
+
224
+ if(this.parent){
225
+ this.parent.childPopup = null;
226
+ }
227
+
228
+ if(this.element.parentNode){
229
+ this.element.parentNode.removeChild(this.element);
230
+ }
231
+
232
+ this.visible = false;
233
+
234
+ if(this.blurCallback && !silent){
235
+ this.blurCallback();
236
+ }
237
+ }
238
+
239
+ return this;
240
+ }
241
+
242
+ child(element){
243
+ if(this.childPopup){
244
+ this.childPopup.hide();
245
+ }
246
+
247
+ this.childPopup = new Popup(this.table, element, this);
248
+
249
+ return this.childPopup;
250
+ }
251
+ }
@@ -212,7 +212,7 @@ class ColumnCalcs extends Module{
212
212
 
213
213
  if(this.botInitialized){
214
214
  this.botInitialized = false;
215
- this.table.footerManager.remove(this.botElement);
215
+ this.footerRemove(this.botElement);
216
216
  changed = true;
217
217
  }
218
218
 
@@ -230,7 +230,7 @@ class ColumnCalcs extends Module{
230
230
 
231
231
  initializeBottomRow(){
232
232
  if(!this.botInitialized){
233
- this.table.footerManager.prepend(this.botElement);
233
+ this.footerPrepend(this.botElement);
234
234
  this.botInitialized = true;
235
235
  }
236
236
  }
@@ -404,13 +404,7 @@ class Edit extends Module{
404
404
 
405
405
  cellEl = cell.getElement();
406
406
 
407
- if(cancel){
408
- if(cell.column.modules.validate && this.table.modExists("validate")){
409
- this.table.modules.validate.cellValidate(cell);
410
- }
411
- }else{
412
- cellEl.classList.remove("tabulator-validation-fail");
413
- }
407
+ this.dispatch("edit-editor-clear", cell, cancel);
414
408
 
415
409
  cellEl.classList.remove("tabulator-editing");
416
410
 
@@ -543,14 +537,10 @@ class Edit extends Module{
543
537
  return;
544
538
  }
545
539
 
546
- //handle successfull value change
540
+ //handle successful value change
547
541
  function success(value){
548
542
  if(self.currentCell === cell){
549
- var valid = true;
550
-
551
- if(cell.column.modules.validate && self.table.modExists("validate") && self.table.options.validationMode != "manual"){
552
- valid = self.table.modules.validate.validate(cell.column.modules.validate, cell, value);
553
- }
543
+ var valid = self.chain("edit-success", [cell, value], true, true);
554
544
 
555
545
  if(valid === true || self.table.options.validationMode === "highlight"){
556
546
  self.clearEditor();
@@ -568,19 +558,11 @@ class Edit extends Module{
568
558
 
569
559
  cell.setValue(value, true);
570
560
 
571
- if(valid !== true){
572
- element.classList.add("tabulator-validation-fail");
573
- self.table.externalEvents.dispatch("validationFailed", cell.getComponent(), value, valid);
574
- return false;
575
- }
576
-
577
- return true;
561
+ return valid === true;
578
562
  }else{
579
563
  self.invalidEdit = true;
580
- element.classList.add("tabulator-validation-fail");
581
564
  self.focusCellNoEvent(cell, true);
582
565
  rendered();
583
- self.table.externalEvents.dispatch("validationFailed", cell.getComponent(), value, valid);
584
566
  return false;
585
567
  }
586
568
  }else{
@@ -638,6 +620,7 @@ class Edit extends Module{
638
620
  cell.column.definition.cellEditing.call(this.table, component);
639
621
  }
640
622
 
623
+ this.dispatch("cell-editing", cell);
641
624
  this.dispatchExternal("cellEditing", component);
642
625
 
643
626
  params = typeof cell.column.modules.edit.params === "function" ? cell.column.modules.edit.params(component) : cell.column.modules.edit.params;
@@ -704,9 +687,7 @@ class Edit extends Module{
704
687
  if(cell.modules.edit && cell.modules.edit.edited){
705
688
  cell.modules.edit.edited = false;
706
689
 
707
- if(cell.modules.validate){
708
- cell.modules.validate.invalid = false;
709
- }
690
+ this.dispatch("edit-edited-clear", cell);
710
691
  }
711
692
 
712
693
  editIndex = this.editedCells.indexOf(cell);