1 var Edit =
function(table){
3 this.currentCell =
false;
4 this.mouseClick =
false;
5 this.recursionBlock =
false;
6 this.invalidEdit =
false;
11 Edit.prototype.initializeColumn =
function(column){
16 check:column.definition.editable,
17 params:column.definition.editorParams || {}
21 switch(typeof column.definition.editor){
24 if(column.definition.editor ===
"tick"){
25 column.definition.editor =
"tickCross";
26 console.warn(
"DEPRECATION WARNING - the tick editor has been deprecated, please use the tickCross editor");
29 if(
self.editors[column.definition.editor]){
30 config.editor =
self.editors[column.definition.editor];
32 console.warn(
"Editor Error - No such editor found: ", column.definition.editor);
37 config.editor = column.definition.editor;
42 if(column.definition.editor ===
true){
44 if(typeof column.definition.formatter !==
"function"){
46 if(column.definition.formatter ===
"tick"){
47 column.definition.formatter =
"tickCross";
48 console.warn(
"DEPRECATION WARNING - the tick editor has been deprecated, please use the tickCross editor");
51 if(
self.editors[column.definition.formatter]){
52 config.editor =
self.editors[column.definition.formatter];
54 config.editor =
self.editors[
"input"];
57 console.warn(
"Editor Error - Cannot auto lookup editor for a custom formatter: ", column.definition.formatter);
64 column.modules.edit = config;
68 Edit.prototype.getCurrentCell =
function(){
69 return this.currentCell ? this.currentCell.getComponent() :
false;
72 Edit.prototype.clearEditor =
function(){
73 var cell = this.currentCell,
76 this.invalidEdit =
false;
79 this.currentCell =
false;
81 cellEl = cell.getElement();
82 cellEl.classList.remove(
"tabulator-validation-fail");
83 cellEl.classList.remove(
"tabulator-editing");
84 while(cellEl.firstChild) cellEl.removeChild(cellEl.firstChild);
86 cell.row.getElement().classList.remove(
"tabulator-row-editing");
90 Edit.prototype.cancelEdit =
function(){
93 var cell = this.currentCell;
94 var component = this.currentCell.getComponent();
97 cell.setValueActual(cell.getValue());
99 if(cell.column.cellEvents.cellEditCancelled){
100 cell.column.cellEvents.cellEditCancelled.call(this.table, component);
103 this.table.options.cellEditCancelled.call(this.table, component);
108 Edit.prototype.bindEditor =
function(cell){
110 element = cell.getElement();
112 element.setAttribute(
"tabindex", 0);
114 element.addEventListener(
"click",
function(e){
115 if(!element.classList.contains(
"tabulator-editing")){
120 element.addEventListener(
"mousedown",
function(e){
121 self.mouseClick =
true;
124 element.addEventListener(
"focus",
function(e){
125 if(!
self.recursionBlock){
126 self.edit(cell, e,
false);
131 Edit.prototype.focusCellNoEvent =
function(cell, block){
132 this.recursionBlock =
true;
133 if(!(block && this.table.browser ===
"ie")){
134 cell.getElement().focus();
136 this.recursionBlock =
false;
139 Edit.prototype.editCell =
function(cell, forceEdit){
140 this.focusCellNoEvent(cell);
141 this.edit(cell,
false, forceEdit);
144 Edit.prototype.edit =
function(cell, e, forceEdit){
147 rendered =
function(){},
148 element = cell.getElement(),
149 cellEditor, component, params;
152 if(this.currentCell){
153 if(!this.invalidEdit){
160 function success(value){
162 if(
self.currentCell === cell){
165 if(cell.column.modules.validate &&
self.table.modExists(
"validate")){
166 valid =
self.table.modules.validate.validate(cell.column.modules.validate, cell.getComponent(), value);
171 cell.setValue(value,
true);
173 if(
self.table.options.dataTree &&
self.table.modExists(
"dataTree")){
174 self.table.modules.dataTree.checkForRestyle(cell);
179 self.invalidEdit =
true;
180 element.classList.add(
"tabulator-validation-fail");
181 self.focusCellNoEvent(cell,
true);
183 self.table.options.validationFailed.call(
self.table, cell.getComponent(), value, valid);
194 if(
self.currentCell === cell){
197 if(
self.table.options.dataTree &&
self.table.modExists(
"dataTree")){
198 self.table.modules.dataTree.checkForRestyle(cell);
205 function onRendered(callback){
209 if(!cell.column.modules.edit.blocked){
214 switch(typeof cell.column.modules.edit.check){
216 allowEdit = cell.column.modules.edit.check(cell.getComponent());
220 allowEdit = cell.column.modules.edit.check;
224 if(allowEdit || forceEdit){
228 self.currentCell = cell;
230 component = cell.getComponent();
233 this.mouseClick =
false;
235 if(cell.column.cellEvents.cellClick){
236 cell.column.cellEvents.cellClick.call(this.table, e, component);
240 if(cell.column.cellEvents.cellEditing){
241 cell.column.cellEvents.cellEditing.call(this.table, component);
244 self.table.options.cellEditing.call(this.table, component);
246 params = typeof cell.column.modules.edit.params ===
"function" ? cell.column.modules.edit.params(component) : cell.column.modules.edit.params;
248 cellEditor = cell.column.modules.edit.editor.call(
self, component, onRendered, success, cancel, params);
251 if(cellEditor !==
false){
253 if(cellEditor instanceof Node){
254 element.classList.add(
"tabulator-editing");
255 cell.row.getElement().classList.add(
"tabulator-row-editing");
256 while(element.firstChild) element.removeChild(element.firstChild);
257 element.appendChild(cellEditor);
263 var children = element.children;
265 for (var i = 0; i < children.length; i++) {
266 children[i].addEventListener(
"click",
function(e){
271 console.warn(
"Edit Error - Editor should return an instance of Node, the editor returned:", cellEditor);
283 this.mouseClick =
false;
288 this.mouseClick =
false;
295 Edit.prototype.editors = {
298 input:
function(cell, onRendered, success, cancel, editorParams){
301 var cellValue = cell.getValue(),
302 input = document.createElement(
"input");
304 input.setAttribute(
"type", editorParams.search ?
"search" :
"text");
306 input.style.padding =
"4px";
307 input.style.width =
"100%";
308 input.style.boxSizing =
"border-box";
310 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
311 for (let key in editorParams.elementAttributes){
312 if(key.charAt(0) ==
"+"){
314 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
316 input.setAttribute(key, editorParams.elementAttributes[key]);
321 input.value = typeof cellValue !==
"undefined" ? cellValue :
"";
323 onRendered(
function(){
325 input.style.height =
"100%";
328 function onChange(e){
329 if(((cellValue === null || typeof cellValue ===
"undefined") && input.value !==
"") || input.value != cellValue){
331 if(success(input.value)){
332 cellValue = input.value;
340 input.addEventListener(
"change", onChange);
341 input.addEventListener(
"blur", onChange);
344 input.addEventListener(
"keydown",
function(e){
360 textarea:
function(cell, onRendered, success, cancel, editorParams){
362 cellValue = cell.getValue(),
363 vertNav = editorParams.verticalNavigation ||
"hybrid",
364 value = String(cellValue !== null && typeof cellValue !==
"undefined" ? cellValue :
""),
365 count = (value.match(/(?:\r\n|\r|\n)/g) || []).length + 1,
366 input = document.createElement(
"textarea"),
370 input.style.display =
"block";
371 input.style.padding =
"2px";
372 input.style.height =
"100%";
373 input.style.width =
"100%";
374 input.style.boxSizing =
"border-box";
375 input.style.whiteSpace =
"pre-wrap";
376 input.style.resize =
"none";
378 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
379 for (let key in editorParams.elementAttributes){
380 if(key.charAt(0) ==
"+"){
382 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
384 input.setAttribute(key, editorParams.elementAttributes[key]);
391 onRendered(
function(){
393 input.style.height =
"100%";
396 function onChange(e){
398 if(((cellValue === null || typeof cellValue ===
"undefined") && input.value !==
"") || input.value != cellValue){
400 if(success(input.value)){
401 cellValue = input.value;
404 setTimeout(
function(){
405 cell.getRow().normalizeHeight();
413 input.addEventListener(
"change", onChange);
414 input.addEventListener(
"blur", onChange);
416 input.addEventListener(
"keyup",
function(){
418 input.style.height =
"";
420 var heightNow = input.scrollHeight;
422 input.style.height = heightNow +
"px";
424 if(heightNow != scrollHeight){
425 scrollHeight = heightNow;
426 cell.getRow().normalizeHeight();
430 input.addEventListener(
"keydown",
function(e){
438 if(vertNav ==
"editor" || (vertNav ==
"hybrid" && input.selectionStart)){
439 e.stopImmediatePropagation();
446 if(vertNav ==
"editor" || (vertNav ==
"hybrid" && input.selectionStart !== input.value.length)){
447 e.stopImmediatePropagation();
458 number:
function(cell, onRendered, success, cancel, editorParams){
460 var cellValue = cell.getValue(),
461 vertNav = editorParams.verticalNavigation ||
"editor",
462 input = document.createElement(
"input");
464 input.setAttribute(
"type",
"number");
466 if(typeof editorParams.max !=
"undefined"){
467 input.setAttribute(
"max", editorParams.max);
470 if(typeof editorParams.min !=
"undefined"){
471 input.setAttribute(
"min", editorParams.min);
474 if(typeof editorParams.step !=
"undefined"){
475 input.setAttribute(
"step", editorParams.step);
479 input.style.padding =
"4px";
480 input.style.width =
"100%";
481 input.style.boxSizing =
"border-box";
483 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
484 for (let key in editorParams.elementAttributes){
485 if(key.charAt(0) ==
"+"){
487 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
489 input.setAttribute(key, editorParams.elementAttributes[key]);
494 input.value = cellValue;
496 var blurFunc =
function(e){
500 onRendered(
function () {
502 input.removeEventListener(
"blur", blurFunc);
505 input.style.height =
"100%";
508 input.addEventListener(
"blur", blurFunc);
512 var value = input.value;
514 if(!isNaN(value) && value !==
""){
515 value = Number(value);
518 if(value != cellValue){
528 input.addEventListener(
"keydown",
function(e){
541 if(vertNav ==
"editor"){
542 e.stopImmediatePropagation();
553 range:
function(cell, onRendered, success, cancel, editorParams){
555 var cellValue = cell.getValue(),
556 input = document.createElement(
"input");
558 input.setAttribute(
"type",
"range");
560 if (typeof editorParams.max !=
"undefined") {
561 input.setAttribute(
"max", editorParams.max);
564 if (typeof editorParams.min !=
"undefined") {
565 input.setAttribute(
"min", editorParams.min);
568 if (typeof editorParams.step !=
"undefined") {
569 input.setAttribute(
"step", editorParams.step);
573 input.style.padding =
"4px";
574 input.style.width =
"100%";
575 input.style.boxSizing =
"border-box";
577 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
578 for (let key in editorParams.elementAttributes){
579 if(key.charAt(0) ==
"+"){
581 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
583 input.setAttribute(key, editorParams.elementAttributes[key]);
588 input.value = cellValue;
590 onRendered(
function () {
592 input.style.height =
"100%";
596 var value = input.value;
598 if(!isNaN(value) && value !==
""){
599 value = Number(value);
602 if(value != cellValue){
612 input.addEventListener(
"blur",
function(e){
617 input.addEventListener(
"keydown",
function(e){
634 select:
function(cell, onRendered, success, cancel, editorParams){
636 cellEl = cell.getElement(),
637 initialValue = cell.getValue(),
638 vertNav = editorParams.verticalNavigation ||
"editor",
639 initialDisplayValue = typeof initialValue !==
"undefined" || initialValue === null ? initialValue : (typeof editorParams.defaultValue !==
"undefined" ? editorParams.defaultValue :
""),
640 input = document.createElement(
"input"),
641 listEl = document.createElement(
"div"),
647 this.table.rowManager.element.addEventListener(
"scroll", cancelItem);
649 if(Array.isArray(editorParams) || (!Array.isArray(editorParams) && typeof editorParams ===
"object" && !editorParams.values)){
650 console.warn(
"DEPRECATION WANRING - values for the select editor must now be passed into the values property of the editorParams object, not as the editorParams object");
651 editorParams = {values:editorParams};
654 function getUniqueColumnValues(field){
656 data =
self.table.getData(),
660 column =
self.table.columnManager.getColumnByField(field);
662 column = cell.getColumn()._getSelf();
666 data.forEach(
function(row){
667 var val = column.getFieldValue(row);
669 if(val !== null && typeof val !==
"undefined" && val !==
""){
674 if(editorParams.sortValuesList){
675 if(editorParams.sortValuesList ==
"asc"){
676 output = Object.keys(output).sort();
678 output = Object.keys(output).sort().reverse();
681 output = Object.keys(output);
684 console.warn(
"unable to find matching column to create select lookup list:", field);
690 function parseItems(inputValues, curentValue){
692 var displayList = [];
694 function processComplexListItem(item){
696 label:editorParams.listItemFormatter ? editorParams.listItemFormatter(item.value, item.label) : item.label,
701 if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
702 setCurrentItem(item);
706 displayList.push(item);
711 if(typeof inputValues ==
"function"){
712 inputValues = inputValues(cell);
715 if(Array.isArray(inputValues)){
716 inputValues.forEach(
function(value){
719 if(typeof value ===
"object"){
728 displayList.push(item);
730 value.options.forEach(
function(item){
731 processComplexListItem(item);
734 processComplexListItem(value);
740 label:editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value,
745 if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
746 setCurrentItem(item);
750 displayList.push(item);
754 for(var key in inputValues){
756 label:editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key],
761 if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
762 setCurrentItem(item);
766 displayList.push(item);
770 dataItems = dataList;
771 displayItems = displayList;
777 while(listEl.firstChild) listEl.removeChild(listEl.firstChild);
779 displayItems.forEach(
function(item){
780 var el = item.element;
785 el = document.createElement(
"div");
786 el.classList.add(
"tabulator-edit-select-list-group");
788 el.innerHTML = item.label ===
"" ?
" " : item.label;
790 el = document.createElement(
"div");
791 el.classList.add(
"tabulator-edit-select-list-item");
793 el.innerHTML = item.label ===
"" ?
" " : item.label;
795 el.addEventListener(
"click",
function(){
796 setCurrentItem(item);
800 if(item === currentItem){
801 el.classList.add(
"active");
805 el.addEventListener(
"mousedown",
function(){
808 setTimeout(
function(){
818 listEl.appendChild(el);
823 function setCurrentItem(item){
825 if(currentItem && currentItem.element){
826 currentItem.element.classList.remove(
"active");
831 input.value = item.label ===
" " ?
"" : item.label;
834 item.element.classList.add(
"active");
839 function chooseItem(){
842 if(initialValue !== currentItem.value){
843 initialValue = currentItem.value;
844 success(currentItem.value);
850 function cancelItem(){
856 if(!listEl.parentNode){
858 if(editorParams.values ===
true){
859 parseItems(getUniqueColumnValues(), initialDisplayValue);
860 }
else if(typeof editorParams.values ===
"string"){
861 parseItems(getUniqueColumnValues(editorParams.values), initialDisplayValue);
863 parseItems(editorParams.values || [], initialDisplayValue);
867 var offset = Tabulator.prototype.helpers.elOffset(cellEl);
869 listEl.style.minWidth = cellEl.offsetWidth +
"px";
871 listEl.style.top = (offset.top + cellEl.offsetHeight) +
"px";
872 listEl.style.left = offset.left +
"px";
873 document.body.appendChild(listEl);
878 if(listEl.parentNode){
879 listEl.parentNode.removeChild(listEl);
882 removeScrollListener();
885 function removeScrollListener() {
886 self.table.rowManager.element.removeEventListener(
"scroll", cancelItem);
890 input.setAttribute(
"type",
"text");
892 input.style.padding =
"4px";
893 input.style.width =
"100%";
894 input.style.boxSizing =
"border-box";
895 input.style.cursor =
"default";
896 input.readOnly = (this.currentCell !=
false);
898 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
899 for (let key in editorParams.elementAttributes){
900 if(key.charAt(0) ==
"+"){
902 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
904 input.setAttribute(key, editorParams.elementAttributes[key]);
909 input.value = typeof initialValue !==
"undefined" || initialValue === null ? initialValue :
"";
920 input.addEventListener(
"keydown",
function(e){
925 index = dataItems.indexOf(currentItem);
927 if(vertNav ==
"editor" || (vertNav ==
"hybrid" && index)){
928 e.stopImmediatePropagation();
933 setCurrentItem(dataItems[index - 1]);
939 index = dataItems.indexOf(currentItem);
941 if(vertNav ==
"editor" || (vertNav ==
"hybrid" && index < dataItems.length - 1)){
942 e.stopImmediatePropagation();
946 if(index < dataItems.length - 1){
948 setCurrentItem(dataItems[0]);
950 setCurrentItem(dataItems[index + 1]);
958 e.stopImmediatePropagation();
973 input.addEventListener(
"blur",
function(e){
979 input.addEventListener(
"focus",
function(e){
984 listEl = document.createElement(
"div");
985 listEl.classList.add(
"tabulator-edit-select-list");
987 onRendered(
function(){
988 input.style.height =
"100%";
997 autocomplete:
function(cell, onRendered, success, cancel, editorParams){
999 cellEl = cell.getElement(),
1000 initialValue = cell.getValue(),
1001 vertNav = editorParams.verticalNavigation ||
"editor",
1002 initialDisplayValue = typeof initialValue !==
"undefined" || initialValue === null ? initialValue : (typeof editorParams.defaultValue !==
"undefined" ? editorParams.defaultValue :
""),
1003 input = document.createElement(
"input"),
1004 listEl = document.createElement(
"div"),
1011 this.table.rowManager.element.addEventListener(
"scroll", cancelItem);
1013 function getUniqueColumnValues(field){
1015 data =
self.table.getData(),
1019 column =
self.table.columnManager.getColumnByField(field);
1021 column = cell.getColumn()._getSelf();
1025 data.forEach(
function(row){
1026 var val = column.getFieldValue(row);
1028 if(val !== null && typeof val !==
"undefined" && val !==
""){
1033 if(editorParams.sortValuesList){
1034 if(editorParams.sortValuesList ==
"asc"){
1035 output = Object.keys(output).sort();
1037 output = Object.keys(output).sort().reverse();
1040 output = Object.keys(output);
1043 console.warn(
"unable to find matching column to create autocomplete lookup list:", field);
1050 function parseItems(inputValues, curentValue){
1053 if(Array.isArray(inputValues)){
1054 inputValues.forEach(
function(value){
1056 title:editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value,
1061 if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
1062 setCurrentItem(item);
1065 itemList.push(item);
1068 for(var key in inputValues){
1070 title:editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key],
1075 if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
1076 setCurrentItem(item);
1079 itemList.push(item);
1083 if(editorParams.searchFunc){
1084 itemList.forEach(
function(item){
1092 allItems = itemList;
1095 function filterList(term, intialLoad){
1100 if(editorParams.searchFunc){
1102 allItems.forEach(
function(item){
1103 searchObjs.push(item.search);
1106 searchResults = editorParams.searchFunc(term, searchObjs);
1108 searchResults.forEach(
function(result){
1109 var match = allItems.find(
function(item){
1110 return item.search === result;
1114 matches.push(match);
1120 if(editorParams.showListOnEmpty){
1121 allItems.forEach(
function(item){
1126 allItems.forEach(
function(item){
1128 if(item.value !== null || typeof item.value !==
"undefined"){
1129 if(String(item.value).toLowerCase().indexOf(String(term).toLowerCase()) > -1 || String(item.title).toLowerCase().indexOf(String(term).toLowerCase()) > -1){
1137 displayItems = matches;
1139 fillList(intialLoad);
1142 function fillList(intialLoad){
1143 var current =
false;
1145 while(listEl.firstChild) listEl.removeChild(listEl.firstChild);
1147 displayItems.forEach(
function(item){
1148 var el = item.element;
1151 el = document.createElement(
"div");
1152 el.classList.add(
"tabulator-edit-select-list-item");
1154 el.innerHTML = item.title;
1156 el.addEventListener(
"click",
function(){
1157 setCurrentItem(item);
1161 el.addEventListener(
"mousedown",
function(){
1164 setTimeout(
function(){
1171 if(intialLoad && item.value == initialValue){
1172 input.value = item.title;
1173 item.element.classList.add(
"active");
1177 if(item === currentItem){
1178 item.element.classList.add(
"active");
1183 listEl.appendChild(el);
1187 setCurrentItem(
false);
1192 function setCurrentItem(item, showInputValue){
1193 if(currentItem && currentItem.element){
1194 currentItem.element.classList.remove(
"active");
1199 if(item && item.element){
1200 item.element.classList.add(
"active");
1205 function chooseItem(){
1209 if(initialValue !== currentItem.value){
1210 initialValue = currentItem.value;
1211 input.value = currentItem.title;
1212 success(currentItem.value);
1217 if(editorParams.freetext){
1218 initialValue = input.value;
1219 success(input.value);
1221 if(editorParams.allowEmpty && input.value ===
""){
1222 initialValue = input.value;
1223 success(input.value);
1231 function cancelItem(){
1236 function showList(){
1237 if(!listEl.parentNode){
1238 while(listEl.firstChild) listEl.removeChild(listEl.firstChild);
1240 if(editorParams.values ===
true){
1241 values = getUniqueColumnValues();
1242 }
else if(typeof editorParams.values ===
"string"){
1243 values = getUniqueColumnValues(editorParams.values);
1245 values = editorParams.values || [];
1248 parseItems(values, initialValue);
1250 var offset = Tabulator.prototype.helpers.elOffset(cellEl);
1252 listEl.style.minWidth = cellEl.offsetWidth +
"px";
1254 listEl.style.top = (offset.top + cellEl.offsetHeight) +
"px";
1255 listEl.style.left = offset.left +
"px";
1256 document.body.appendChild(listEl);
1260 function hideList(){
1261 if(listEl.parentNode){
1262 listEl.parentNode.removeChild(listEl);
1265 removeScrollListener();
1268 function removeScrollListener() {
1269 self.table.rowManager.element.removeEventListener(
"scroll", cancelItem);
1273 input.setAttribute(
"type",
"search");
1275 input.style.padding =
"4px";
1276 input.style.width =
"100%";
1277 input.style.boxSizing =
"border-box";
1279 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
1280 for (let key in editorParams.elementAttributes){
1281 if(key.charAt(0) ==
"+"){
1283 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
1285 input.setAttribute(key, editorParams.elementAttributes[key]);
1291 input.addEventListener(
"keydown",
function(e){
1296 index = displayItems.indexOf(currentItem);
1298 if(vertNav ==
"editor" || (vertNav ==
"hybrid" && index)){
1299 e.stopImmediatePropagation();
1300 e.stopPropagation();
1305 setCurrentItem(displayItems[index - 1]);
1307 setCurrentItem(
false);
1314 index = displayItems.indexOf(currentItem);
1316 if(vertNav ==
"editor" || (vertNav ==
"hybrid" && index < displayItems.length - 1)){
1318 e.stopImmediatePropagation();
1319 e.stopPropagation();
1322 if(index < displayItems.length - 1){
1324 setCurrentItem(displayItems[0]);
1326 setCurrentItem(displayItems[index + 1]);
1335 e.stopImmediatePropagation();
1336 e.stopPropagation();
1351 e.stopImmediatePropagation();
1356 input.addEventListener(
"keyup",
function(e){
1368 filterList(input.value);
1373 input.addEventListener(
"search",
function(e){
1374 filterList(input.value);
1377 input.addEventListener(
"blur",
function(e){
1383 input.addEventListener(
"focus",
function(e){
1384 var value = initialDisplayValue;
1386 input.value = value;
1387 filterList(value,
true);
1391 listEl = document.createElement(
"div");
1392 listEl.classList.add(
"tabulator-edit-select-list");
1394 onRendered(
function(){
1395 input.style.height =
"100%";
1403 star:
function(cell, onRendered, success, cancel, editorParams){
1405 element = cell.getElement(),
1406 value = cell.getValue(),
1407 maxStars = element.getElementsByTagName(
"svg").length || 5,
1408 size = element.getElementsByTagName(
"svg")[0] ? element.getElementsByTagName(
"svg")[0].getAttribute(
"width") : 14,
1410 starsHolder = document.createElement(
"div"),
1411 star = document.createElementNS(
'http://www.w3.org/2000/svg',
"svg");
1415 function starChange(val){
1416 stars.forEach(
function(star, i){
1418 if(
self.table.browser ==
"ie"){
1419 star.setAttribute(
"class",
"tabulator-star-active");
1421 star.classList.replace(
"tabulator-star-inactive",
"tabulator-star-active");
1424 star.innerHTML =
'<polygon fill="#488CE9" stroke="#014AAE" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
1426 if(
self.table.browser ==
"ie"){
1427 star.setAttribute(
"class",
"tabulator-star-inactive");
1429 star.classList.replace(
"tabulator-star-active",
"tabulator-star-inactive");
1432 star.innerHTML =
'<polygon fill="#010155" stroke="#686868" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
1438 function buildStar(i){
1440 var starHolder = document.createElement(
"span");
1441 var nextStar = star.cloneNode(
true);
1443 stars.push(nextStar);
1445 starHolder.addEventListener(
"mouseenter",
function(e){
1446 e.stopPropagation();
1447 e.stopImmediatePropagation();
1451 starHolder.addEventListener(
"mousemove",
function(e){
1452 e.stopPropagation();
1453 e.stopImmediatePropagation();
1456 starHolder.addEventListener(
"click",
function(e){
1457 e.stopPropagation();
1458 e.stopImmediatePropagation();
1462 starHolder.appendChild(nextStar);
1463 starsHolder.appendChild(starHolder);
1468 function changeValue(val){
1474 element.style.whiteSpace =
"nowrap";
1475 element.style.overflow =
"hidden";
1476 element.style.textOverflow =
"ellipsis";
1479 starsHolder.style.verticalAlign =
"middle";
1480 starsHolder.style.display =
"inline-block";
1481 starsHolder.style.padding =
"4px";
1484 star.setAttribute(
"width", size);
1485 star.setAttribute(
"height", size);
1486 star.setAttribute(
"viewBox",
"0 0 512 512");
1487 star.setAttribute(
"xml:space",
"preserve");
1488 star.style.padding =
"0 1px";
1490 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
1491 for (let key in editorParams.elementAttributes){
1492 if(key.charAt(0) ==
"+"){
1494 starsHolder.setAttribute(key, starsHolder.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
1496 starsHolder.setAttribute(key, editorParams.elementAttributes[key]);
1502 for(var i=1;i<= maxStars;i++){
1507 value = Math.min(parseInt(value), maxStars);
1512 starsHolder.addEventListener(
"mousemove",
function(e){
1516 starsHolder.addEventListener(
"click",
function(e){
1520 element.addEventListener(
"blur",
function(e){
1525 element.addEventListener(
"keydown",
function(e){
1528 changeValue(value + 1);
1532 changeValue(value - 1);
1549 progress:
function(cell, onRendered, success, cancel, editorParams){
1550 var element = cell.getElement(),
1551 max = typeof editorParams.max ===
"undefined" ? ( element.getElementsByTagName(
"div")[0].getAttribute(
"max") || 100) : editorParams.max,
1552 min = typeof editorParams.min ===
"undefined" ? ( element.getElementsByTagName(
"div")[0].getAttribute(
"min") || 0) : editorParams.min,
1553 percent = (max - min) / 100,
1554 value = cell.getValue() || 0,
1555 handle = document.createElement(
"div"),
1556 bar = document.createElement(
"div"),
1557 mouseDrag, mouseDragWidth;
1560 function updateValue(){
1561 var calcVal = (percent * Math.round(bar.offsetWidth / (element.clientWidth/100))) + min;
1563 element.setAttribute(
"aria-valuenow", calcVal);
1564 element.setAttribute(
"aria-label", value);
1568 handle.style.position =
"absolute";
1569 handle.style.right =
"0";
1570 handle.style.top =
"0";
1571 handle.style.bottom =
"0";
1572 handle.style.width =
"5px";
1573 handle.classList.add(
"tabulator-progress-handle");
1576 bar.style.display =
"inline-block";
1577 bar.style.position =
"relative";
1582 bar.style.height =
"100%";
1583 bar.style.backgroundColor =
"#488CE9";
1584 bar.style.maxWidth =
"100%";
1585 bar.style.minWidth =
"0%";
1587 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
1588 for (let key in editorParams.elementAttributes){
1589 if(key.charAt(0) ==
"+"){
1591 bar.setAttribute(key, bar.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
1593 bar.setAttribute(key, editorParams.elementAttributes[key]);
1599 element.style.padding =
"4px 4px";
1602 value = Math.min(parseFloat(value), max);
1603 value = Math.max(parseFloat(value), min);
1606 value = Math.round((value - min) / percent);
1608 bar.style.width = value +
"%";
1610 element.setAttribute(
"aria-valuemin", min);
1611 element.setAttribute(
"aria-valuemax", max);
1613 bar.appendChild(handle);
1615 handle.addEventListener(
"mousedown",
function(e){
1616 mouseDrag = e.screenX;
1617 mouseDragWidth = bar.offsetWidth;
1620 handle.addEventListener(
"mouseover",
function(){
1621 handle.style.cursor =
"ew-resize";
1624 element.addEventListener(
"mousemove",
function(e){
1626 bar.style.width = (mouseDragWidth + e.screenX - mouseDrag) +
"px";
1630 element.addEventListener(
"mouseup",
function(e){
1632 e.stopPropagation();
1633 e.stopImmediatePropagation();
1636 mouseDragWidth =
false;
1643 element.addEventListener(
"keydown",
function(e){
1646 bar.style.width = (bar.clientWidth + element.clientWidth/100) +
"px";
1650 bar.style.width = (bar.clientWidth - element.clientWidth/100) +
"px";
1664 element.addEventListener(
"blur",
function(){
1672 tickCross:
function(cell, onRendered, success, cancel, editorParams){
1673 var value = cell.getValue(),
1674 input = document.createElement(
"input"),
1675 tristate = editorParams.tristate,
1676 indetermValue = typeof editorParams.indeterminateValue ===
"undefined" ? null : editorParams.indeterminateValue,
1677 indetermState =
false;
1679 input.setAttribute(
"type",
"checkbox");
1680 input.style.marginTop =
"5px";
1681 input.style.boxSizing =
"border-box";
1683 if(editorParams.elementAttributes && typeof editorParams.elementAttributes ==
"object"){
1684 for (let key in editorParams.elementAttributes){
1685 if(key.charAt(0) ==
"+"){
1687 input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes[
"+" + key]);
1689 input.setAttribute(key, editorParams.elementAttributes[key]);
1694 input.value = value;
1696 if(tristate && (typeof value ===
"undefined" || value === indetermValue || value ===
"")){
1697 indetermState =
true;
1698 input.indeterminate =
true;
1701 if(this.table.browser !=
"firefox"){
1702 onRendered(
function(){
1707 input.checked = value ===
true || value ===
"true" || value ===
"True" || value === 1;
1709 function setValue(blur){
1712 if(input.checked && !indetermState){
1713 input.checked =
false;
1714 input.indeterminate =
true;
1715 indetermState =
true;
1716 return indetermValue;
1718 indetermState =
false;
1719 return input.checked;
1723 return indetermValue;
1725 return input.checked;
1729 return input.checked;
1734 input.addEventListener(
"change",
function(e){
1735 success(setValue());
1738 input.addEventListener(
"blur",
function(e){
1739 success(setValue(
true));
1743 input.addEventListener(
"keydown",
function(e){
1744 if(e.keyCode == 13){
1745 success(setValue());
1747 if(e.keyCode == 27){
1756 Tabulator.prototype.registerModule(
"edit", Edit);