UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

1,575 lines (1,234 loc) 38.8 kB
var Edit = function(table){ this.table = table; //hold Tabulator object this.currentCell = false; //hold currently editing cell this.mouseClick = false; //hold mousedown state to prevent click binding being overriden by editor opening this.recursionBlock = false; //prevent focus recursion this.invalidEdit = false; }; //initialize column editor Edit.prototype.initializeColumn = function(column){ var self = this, config = { editor:false, blocked:false, check:column.definition.editable, params:column.definition.editorParams || {} }; //set column editor switch(typeof column.definition.editor){ case "string": if(column.definition.editor === "tick"){ column.definition.editor = "tickCross"; console.warn("DEPRECATION WANRING - the tick editor has been depricated, please use the tickCross editor"); } if(self.editors[column.definition.editor]){ config.editor = self.editors[column.definition.editor]; }else{ console.warn("Editor Error - No such editor found: ", column.definition.editor); } break; case "function": config.editor = column.definition.editor; break; case "boolean": if(column.definition.editor === true){ if(typeof column.definition.formatter !== "function"){ if(column.definition.formatter === "tick"){ column.definition.formatter = "tickCross"; console.warn("DEPRECATION WANRING - the tick editor has been depricated, please use the tickCross editor"); } if(self.editors[column.definition.formatter]){ config.editor = self.editors[column.definition.formatter]; }else{ config.editor = self.editors["input"]; } }else{ console.warn("Editor Error - Cannot auto lookup editor for a custom formatter: ", column.definition.formatter); } } break; } if(config.editor){ column.modules.edit = config; } }; Edit.prototype.getCurrentCell = function(){ return this.currentCell ? this.currentCell.getComponent() : false; }; Edit.prototype.clearEditor = function(){ var cell = this.currentCell, cellEl; this.invalidEdit = false; if(cell){ this.currentCell = false; cellEl = cell.getElement(); cellEl.classList.remove("tabulator-validation-fail"); cellEl.classList.remove("tabulator-editing"); while(cellEl.firstChild) cellEl.removeChild(cellEl.firstChild); cell.row.getElement().classList.remove("tabulator-row-editing"); } }; Edit.prototype.cancelEdit = function(){ if(this.currentCell){ var cell = this.currentCell; var component = this.currentCell.getComponent(); this.clearEditor(); cell.setValueActual(cell.getValue()); if(cell.column.cellEvents.cellEditCancelled){ cell.column.cellEvents.cellEditCancelled.call(this.table, component); } this.table.options.cellEditCancelled.call(this.table, component); } }; //return a formatted value for a cell Edit.prototype.bindEditor = function(cell){ var self = this, element = cell.getElement(); element.setAttribute("tabindex", 0); element.addEventListener("click", function(e){ if(!element.classList.contains("tabulator-editing")){ element.focus(); } }); element.addEventListener("mousedown", function(e){ self.mouseClick = true; }); element.addEventListener("focus", function(e){ if(!self.recursionBlock){ self.edit(cell, e, false); } }); }; Edit.prototype.focusCellNoEvent = function(cell){ this.recursionBlock = true; if(this.table.browser !== "ie"){ cell.getElement().focus(); } this.recursionBlock = false; }; Edit.prototype.editCell = function(cell, forceEdit){ this.focusCellNoEvent(cell); this.edit(cell, false, forceEdit); }; Edit.prototype.edit = function(cell, e, forceEdit){ var self = this, allowEdit = true, rendered = function(){}, element = cell.getElement(), cellEditor, component, params; //prevent editing if another cell is refusing to leave focus (eg. validation fail) if(this.currentCell){ if(!this.invalidEdit){ this.cancelEdit(); } return; } //handle successfull value change function success(value){ if(self.currentCell === cell){ var valid = true; if(cell.column.modules.validate && self.table.modExists("validate")){ valid = self.table.modules.validate.validate(cell.column.modules.validate, cell.getComponent(), value); } if(valid === true){ self.clearEditor(); cell.setValue(value, true); if(self.table.options.dataTree && self.table.modExists("dataTree")){ self.table.modules.dataTree.checkForRestyle(cell); } }else{ self.invalidEdit = true; element.classList.add("tabulator-validation-fail"); self.focusCellNoEvent(cell); rendered(); self.table.options.validationFailed.call(self.table, cell.getComponent(), value, valid); } }else{ // console.warn("Edit Success Error - cannot call success on a cell that is no longer being edited"); } } //handle aborted edit function cancel(){ if(self.currentCell === cell){ self.cancelEdit(); if(self.table.options.dataTree && self.table.modExists("dataTree")){ self.table.modules.dataTree.checkForRestyle(cell); } }else{ // console.warn("Edit Success Error - cannot call cancel on a cell that is no longer being edited"); } } function onRendered(callback){ rendered = callback; } if(!cell.column.modules.edit.blocked){ if(e){ e.stopPropagation(); } switch(typeof cell.column.modules.edit.check){ case "function": allowEdit = cell.column.modules.edit.check(cell.getComponent()); break; case "boolean": allowEdit = cell.column.modules.edit.check; break; } if(allowEdit || forceEdit){ self.cancelEdit(); self.currentCell = cell; component = cell.getComponent(); if(this.mouseClick){ this.mouseClick = false; if(cell.column.cellEvents.cellClick){ cell.column.cellEvents.cellClick.call(this.table, e, component); } } if(cell.column.cellEvents.cellEditing){ cell.column.cellEvents.cellEditing.call(this.table, component); } self.table.options.cellEditing.call(this.table, component); params = typeof cell.column.modules.edit.params === "function" ? cell.column.modules.edit.params(component) : cell.column.modules.edit.params; cellEditor = cell.column.modules.edit.editor.call(self, component, onRendered, success, cancel, params); //if editor returned, add to DOM, if false, abort edit if(cellEditor !== false){ if(cellEditor instanceof Node){ element.classList.add("tabulator-editing"); cell.row.getElement().classList.add("tabulator-row-editing"); while(element.firstChild) element.removeChild(element.firstChild); element.appendChild(cellEditor); //trigger onRendered Callback rendered(); //prevent editing from triggering rowClick event var children = element.children; for (var i = 0; i < children.length; i++) { children[i].addEventListener("click", function(e){ e.stopPropagation(); }); } }else{ console.warn("Edit Error - Editor should return an instance of Node, the editor returned:", cellEditor); element.blur(); return false; } }else{ element.blur(); return false; } return true; }else{ this.mouseClick = false; element.blur(); return false; } }else{ this.mouseClick = false; element.blur(); return false; } }; //default data editors Edit.prototype.editors = { //input element input:function(cell, onRendered, success, cancel, editorParams){ //create and style input var cellValue = cell.getValue(), input = document.createElement("input"); input.setAttribute("type", editorParams.search ? "search" : "text"); input.style.padding = "4px"; input.style.width = "100%"; input.style.boxSizing = "border-box"; input.value = typeof cellValue !== "undefined" ? cellValue : ""; onRendered(function(){ input.focus(); input.style.height = "100%"; }); function onChange(e){ if(((cellValue === null || typeof cellValue === "undefined") && input.value !== "") || input.value != cellValue){ success(input.value); }else{ cancel(); } } //submit new value on blur or change input.addEventListener("change", onChange); input.addEventListener("blur", onChange); //submit new value on enter input.addEventListener("keydown", function(e){ switch(e.keyCode){ case 13: success(input.value); break; case 27: cancel(); break; } }); return input; }, //resizable text area element textarea:function(cell, onRendered, success, cancel, editorParams){ var self = this, cellValue = cell.getValue(), value = String(cellValue !== null && typeof cellValue !== "undefined" ? cellValue : ""), count = (value.match(/(?:\r\n|\r|\n)/g) || []).length + 1, input = document.createElement("textarea"), scrollHeight = 0; //create and style input input.style.display = "block"; input.style.padding = "2px"; input.style.height = "100%"; input.style.width = "100%"; input.style.boxSizing = "border-box"; input.style.whiteSpace = "pre-wrap"; input.style.resize = "none"; input.value = value; onRendered(function(){ input.focus(); input.style.height = "100%"; }); function onChange(e){ if(((cellValue === null || typeof cellValue === "undefined") && input.value !== "") || input.value != cellValue){ success(input.value); setTimeout(function(){ cell.getRow().normalizeHeight(); },300) }else{ cancel(); } } //submit new value on blur or change input.addEventListener("change", onChange); input.addEventListener("blur", onChange); input.addEventListener("keyup", function(){ input.style.height = ""; var heightNow = input.scrollHeight; input.style.height = heightNow + "px"; if(heightNow != scrollHeight){ scrollHeight = heightNow; cell.getRow().normalizeHeight(); } }); input.addEventListener("keydown", function(e){ if(e.keyCode == 27){ cancel(); } }); return input; }, //input element with type of number number:function(cell, onRendered, success, cancel, editorParams){ var cellValue = cell.getValue(), input = document.createElement("input"); input.setAttribute("type", "number"); if(typeof editorParams.max != "undefined"){ input.setAttribute("max", editorParams.max); } if(typeof editorParams.min != "undefined"){ input.setAttribute("min", editorParams.min); } if(typeof editorParams.step != "undefined"){ input.setAttribute("step", editorParams.step); } //create and style input input.style.padding = "4px"; input.style.width = "100%"; input.style.boxSizing = "border-box"; input.value = cellValue; var blurFunc = function(e){ onChange(); } onRendered(function () { //submit new value on blur input.removeEventListener("blur", blurFunc); input.focus(); input.style.height = "100%"; //submit new value on blur input.addEventListener("blur", blurFunc); }); function onChange(){ var value = input.value; if(!isNaN(value) && value !==""){ value = Number(value); } if(value != cellValue){ success(value); }else{ cancel(); } } //submit new value on enter input.addEventListener("keydown", function(e){ switch(e.keyCode){ case 13: case 9: onChange(); break; case 27: cancel(); break; } }); return input; }, //input element with type of number range:function(cell, onRendered, success, cancel, editorParams){ var cellValue = cell.getValue(), input = document.createElement("input"); input.setAttribute("type", "range"); if (typeof editorParams.max != "undefined") { input.setAttribute("max", editorParams.max); } if (typeof editorParams.min != "undefined") { input.setAttribute("min", editorParams.min); } if (typeof editorParams.step != "undefined") { input.setAttribute("step", editorParams.step); } //create and style input input.style.padding = "4px"; input.style.width = "100%"; input.style.boxSizing = "border-box"; input.value = cellValue; onRendered(function () { input.focus(); input.style.height = "100%"; }); function onChange(){ var value = input.value; if(!isNaN(value) && value !==""){ value = Number(value); } if(value != cellValue){ success(value); }else{ cancel(); } } //submit new value on blur input.addEventListener("blur", function(e){ onChange(); }); //submit new value on enter input.addEventListener("keydown", function(e){ switch(e.keyCode){ case 13: case 9: onChange(); break; case 27: cancel(); break; } }); return input; }, //select select:function(cell, onRendered, success, cancel, editorParams){ var self = this, cellEl = cell.getElement(), initialValue = cell.getValue(), input = document.createElement("input"), listEl = document.createElement("div"), dataItems = [], displayItems = [], currentItem = {}, blurable = true; this.table.rowManager.element.addEventListener("scroll", cancelItem); if(Array.isArray(editorParams) || (!Array.isArray(editorParams) && typeof editorParams === "object" && !editorParams.values)){ 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"); editorParams = {values:editorParams}; } function getUniqueColumnValues(){ var output = {}, column = cell.getColumn()._getSelf(), data = self.table.getData(); data.forEach(function(row){ var val = column.getFieldValue(row); if(val !== null && typeof val !== "undefined" && val !== ""){ output[val] = true; } }); if(editorParams.sortValuesList){ if(editorParams.sortValuesList == "asc"){ output = Object.keys(output).sort(); }else{ output = Object.keys(output).sort().reverse(); } }else{ output = Object.keys(output); } return output; } function parseItems(inputValues, curentValue){ var dataList = []; var displayList = []; function processComplexListItem(item){ var item = { label:editorParams.listItemFormatter ? editorParams.listItemFormatter(item.value, item.label) : item.label, value:item.value, element:false, }; if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){ setCurrentItem(item); } dataList.push(item); displayList.push(item); return item; } if(typeof inputValues == "function"){ inputValues = inputValues(cell); } if(Array.isArray(inputValues)){ inputValues.forEach(function(value){ var item; if(typeof value === "object"){ if(value.options){ item = { label:value.label, group:true, element:false, }; displayList.push(item); value.options.forEach(function(item){ processComplexListItem(item); }); }else{ processComplexListItem(value); } }else{ item = { label:editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value, value:value, element:false, }; if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){ setCurrentItem(item); } dataList.push(item); displayList.push(item); } }); }else{ for(var key in inputValues){ var item = { label:editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key], value:key, element:false, }; if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){ setCurrentItem(item); } dataList.push(item); displayList.push(item); } } dataItems = dataList; displayItems = displayList; fillList(); } function fillList(){ while(listEl.firstChild) listEl.removeChild(listEl.firstChild); displayItems.forEach(function(item){ var el = item.element; if(!el){ if(item.group){ el = document.createElement("div"); el.classList.add("tabulator-edit-select-list-group"); el.tabIndex = 0; el.innerHTML = item.label === "" ? "&nbsp;" : item.label; }else{ el = document.createElement("div"); el.classList.add("tabulator-edit-select-list-item"); el.tabIndex = 0; el.innerHTML = item.label === "" ? "&nbsp;" : item.label; el.addEventListener("click", function(){ setCurrentItem(item); chooseItem(); }); if(item === currentItem){ el.classList.add("active"); } } el.addEventListener("mousedown", function(){ blurable = false; setTimeout(function(){ blurable = true; }, 10); }); item.element = el; } listEl.appendChild(el); }); } function setCurrentItem(item){ if(currentItem && currentItem.element){ currentItem.element.classList.remove("active"); } currentItem = item; input.value = item.label === "&nbsp;" ? "" : item.label; if(item.element){ item.element.classList.add("active"); } } function chooseItem(){ hideList(); if(initialValue !== currentItem.value){ initialValue = currentItem.value; success(currentItem.value); }else{ cancel(); } } function cancelItem(){ hideList(); cancel(); } function showList(){ if(!listEl.parentNode){ if(editorParams.values === true){ parseItems(getUniqueColumnValues(), initialValue); }else{ parseItems(editorParams.values || [], initialValue); } var offset = Tabulator.prototype.helpers.elOffset(cellEl); listEl.style.minWidth = cellEl.offsetWidth + "px"; listEl.style.top = (offset.top + cellEl.offsetHeight) + "px"; listEl.style.left = offset.left + "px"; document.body.appendChild(listEl); } } function hideList(){ if(listEl.parentNode){ listEl.parentNode.removeChild(listEl); } removeScrollListener(); } function removeScrollListener() { self.table.rowManager.element.removeEventListener("scroll", cancelItem); } //style input input.setAttribute("type", "text"); input.style.padding = "4px"; input.style.width = "100%"; input.style.boxSizing = "border-box"; input.style.cursor = "default"; input.readOnly = (this.currentCell != false); input.value = typeof initialValue !== "undefined" || initialValue === null ? initialValue : ""; if(editorParams.values === true){ parseItems(getUniqueColumnValues(), initialValue); }else{ parseItems(editorParams.values || [], initialValue); } //allow key based navigation input.addEventListener("keydown", function(e){ var index; switch(e.keyCode){ case 38: //up arrow e.stopImmediatePropagation(); e.stopPropagation(); e.preventDefault(); index = dataItems.indexOf(currentItem); if(index > 0){ setCurrentItem(dataItems[index - 1]); } break; case 40: //down arrow e.stopImmediatePropagation(); e.stopPropagation(); e.preventDefault(); index = dataItems.indexOf(currentItem); if(index < dataItems.length - 1){ if(index == -1){ setCurrentItem(dataItems[0]); }else{ setCurrentItem(dataItems[index + 1]); } } break; case 37: //left arrow case 39: //right arrow e.stopImmediatePropagation(); e.stopPropagation(); e.preventDefault(); break; case 13: //enter chooseItem(); break; case 27: //escape cancelItem(); break; } }); input.addEventListener("blur", function(e){ if(blurable){ cancelItem(); } }); input.addEventListener("focus", function(e){ showList(); }); //style list element listEl = document.createElement("div"); listEl.classList.add("tabulator-edit-select-list"); onRendered(function(){ input.style.height = "100%"; input.focus(); }); return input; }, //autocomplete autocomplete:function(cell, onRendered, success, cancel, editorParams){ var self = this, cellEl = cell.getElement(), initialValue = cell.getValue(), input = document.createElement("input"), listEl = document.createElement("div"), allItems = [], displayItems = [], values = [], currentItem = {}, blurable = true; this.table.rowManager.element.addEventListener("scroll", cancelItem); function getUniqueColumnValues(){ var output = {}, column = cell.getColumn()._getSelf(), data = self.table.getData(); data.forEach(function(row){ var val = column.getFieldValue(row); if(val !== null && typeof val !== "undefined" && val !== ""){ output[val] = true; } }); if(editorParams.sortValuesList){ if(editorParams.sortValuesList == "asc"){ output = Object.keys(output).sort(); }else{ output = Object.keys(output).sort().reverse(); } }else{ output = Object.keys(output); } return output; } function parseItems(inputValues, curentValue){ var itemList = []; if(Array.isArray(inputValues)){ inputValues.forEach(function(value){ var item = { title:editorParams.listItemFormatter ? editorParams.listItemFormatter(value, value) : value, value:value, element:false, }; if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){ setCurrentItem(item); } itemList.push(item); }); }else{ for(var key in inputValues){ var item = { title:editorParams.listItemFormatter ? editorParams.listItemFormatter(key, inputValues[key]) : inputValues[key], value:key, element:false, }; if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){ setCurrentItem(item); } itemList.push(item); } } if(editorParams.searchFunc){ itemList.forEach(function(item){ item.search = { title:item.title, value:item.value, }; }); } allItems = itemList; } function filterList(term, intialLoad){ var matches = [], searchObjs = [], searchResults = []; if(editorParams.searchFunc){ allItems.forEach(function(item){ searchObjs.push(item.search); }); searchResults = editorParams.searchFunc(term, searchObjs); searchResults.forEach(function(result){ var match = allItems.find(function(item){ return item.search === result; }); if(match){ matches.push(match); } }); }else{ if(term === ""){ if(editorParams.showListOnEmpty){ allItems.forEach(function(item){ matches.push(item); }); } }else{ allItems.forEach(function(item){ if(item.value !== null || typeof item.value !== "undefined"){ if(String(item.value).toLowerCase().indexOf(String(term).toLowerCase()) > -1 || String(item.title).toLowerCase().indexOf(String(term).toLowerCase()) > -1){ matches.push(item); } } }); } } displayItems = matches; fillList(intialLoad); } function fillList(intialLoad){ var current = false; while(listEl.firstChild) listEl.removeChild(listEl.firstChild); displayItems.forEach(function(item){ var el = item.element; if(!el){ el = document.createElement("div"); el.classList.add("tabulator-edit-select-list-item"); el.tabIndex = 0; el.innerHTML = item.title; el.addEventListener("click", function(){ setCurrentItem(item); chooseItem(); }); el.addEventListener("mousedown", function(){ blurable = false; setTimeout(function(){ blurable = true; }, 10); }); item.element = el; if(intialLoad && item.value == initialValue){ input.value = item.title; item.element.classList.add("active"); current = true; } if(item === currentItem){ item.element.classList.add("active"); current = true; } } listEl.appendChild(el); }); if(!current){ setCurrentItem(false); } } function setCurrentItem(item, showInputValue){ if(currentItem && currentItem.element){ currentItem.element.classList.remove("active"); } currentItem = item; if(item && item.element){ item.element.classList.add("active"); } } function chooseItem(){ hideList(); if(currentItem){ if(initialValue !== currentItem.value){ initialValue = currentItem.value; input.value = currentItem.title; success(currentItem.value); }else{ cancel(); } }else{ if(editorParams.freetext){ initialValue = input.value; success(input.value); }else{ if(editorParams.allowEmpty && input.value === ""){ initialValue = input.value; success(input.value); }else{ cancel(); } } } } function cancelItem(){ hideList(); cancel(); } function showList(){ if(!listEl.parentNode){ while(listEl.firstChild) listEl.removeChild(listEl.firstChild); if(editorParams.values === true){ values = getUniqueColumnValues(); }else{ values = editorParams.values || []; } parseItems(values, initialValue); var offset = Tabulator.prototype.helpers.elOffset(cellEl); listEl.style.minWidth = cellEl.offsetWidth + "px"; listEl.style.top = (offset.top + cellEl.offsetHeight) + "px"; listEl.style.left = offset.left + "px"; document.body.appendChild(listEl); } } function hideList(){ if(listEl.parentNode){ listEl.parentNode.removeChild(listEl); } removeScrollListener(); } function removeScrollListener() { self.table.rowManager.element.removeEventListener("scroll", cancelItem); } //style input input.setAttribute("type", "search"); input.style.padding = "4px"; input.style.width = "100%"; input.style.boxSizing = "border-box"; //allow key based navigation input.addEventListener("keydown", function(e){ var index; switch(e.keyCode){ case 38: //up arrow e.stopImmediatePropagation(); e.stopPropagation(); e.preventDefault(); index = displayItems.indexOf(currentItem); if(index > 0){ setCurrentItem(displayItems[index - 1]); }else{ setCurrentItem(false); } break; case 40: //down arrow e.stopImmediatePropagation(); e.stopPropagation(); e.preventDefault(); index = displayItems.indexOf(currentItem); if(index < displayItems.length - 1){ if(index == -1){ setCurrentItem(displayItems[0]); }else{ setCurrentItem(displayItems[index + 1]); } } break; case 37: //left arrow case 39: //right arrow e.stopImmediatePropagation(); e.stopPropagation(); e.preventDefault(); break; case 13: //enter chooseItem(); break; case 27: //escape cancelItem(); break; case 36: //home case 35: //end //prevent table navigation while using input element e.stopImmediatePropagation(); break; } }); input.addEventListener("keyup", function(e){ switch(e.keyCode){ case 38: //up arrow case 37: //left arrow case 39: //up arrow case 40: //right arrow case 13: //enter case 27: //escape break; default: filterList(input.value); } }); input.addEventListener("search", function(e){ filterList(input.value); }); input.addEventListener("blur", function(e){ if(blurable){ chooseItem(); } }); input.addEventListener("focus", function(e){ var value = typeof initialValue !== "undefined" || initialValue === null ? initialValue : ""; showList(); input.value = value; filterList(value, true); }); //style list element listEl = document.createElement("div"); listEl.classList.add("tabulator-edit-select-list"); onRendered(function(){ input.style.height = "100%"; input.focus(); }); return input; }, //start rating star:function(cell, onRendered, success, cancel, editorParams){ var self = this, element = cell.getElement(), value = cell.getValue(), maxStars = element.getElementsByTagName("svg").length || 5, size = element.getElementsByTagName("svg")[0] ? element.getElementsByTagName("svg")[0].getAttribute("width") : 14, stars = [], starsHolder = document.createElement("div"), star = document.createElementNS('http://www.w3.org/2000/svg', "svg"); //change star type function starChange(val){ stars.forEach(function(star, i){ if(i < val){ if(self.table.browser == "ie"){ star.setAttribute("class", "tabulator-star-active"); }else{ star.classList.replace("tabulator-star-inactive", "tabulator-star-active"); } 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 "/>'; }else{ if(self.table.browser == "ie"){ star.setAttribute("class", "tabulator-star-inactive"); }else{ star.classList.replace("tabulator-star-active", "tabulator-star-inactive"); } 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 "/>'; } }); } //build stars function buildStar(i){ var starHolder = document.createElement("span"); var nextStar = star.cloneNode(true); stars.push(nextStar); starHolder.addEventListener("mouseenter", function(e){ e.stopPropagation(); e.stopImmediatePropagation(); starChange(i); }); starHolder.addEventListener("mousemove", function(e){ e.stopPropagation(); e.stopImmediatePropagation(); }); starHolder.addEventListener("click", function(e){ e.stopPropagation(); e.stopImmediatePropagation(); success(i); }); starHolder.appendChild(nextStar); starsHolder.appendChild(starHolder); } //handle keyboard navigation value change function changeValue(val){ value = val; starChange(val); } //style cell element.style.whiteSpace = "nowrap"; element.style.overflow = "hidden"; element.style.textOverflow = "ellipsis"; //style holding element starsHolder.style.verticalAlign = "middle"; starsHolder.style.display = "inline-block"; starsHolder.style.padding = "4px"; //style star star.setAttribute("width", size); star.setAttribute("height", size); star.setAttribute("viewBox", "0 0 512 512"); star.setAttribute("xml:space", "preserve"); star.style.padding = "0 1px"; //create correct number of stars for(var i=1;i<= maxStars;i++){ buildStar(i); } //ensure value does not exceed number of stars value = Math.min(parseInt(value), maxStars); // set initial styling of stars starChange(value); starsHolder.addEventListener("mousemove", function(e){ starChange(0); }); starsHolder.addEventListener("click", function(e){ success(0); }); element.addEventListener("blur", function(e){ cancel(); }); //allow key based navigation element.addEventListener("keydown", function(e){ switch(e.keyCode){ case 39: //right arrow changeValue(value + 1); break; case 37: //left arrow changeValue(value - 1); break; case 13: //enter success(value); break; case 27: //escape cancel(); break; } }); return starsHolder; }, //draggable progress bar progress:function(cell, onRendered, success, cancel, editorParams){ var element = cell.getElement(), max = typeof editorParams.max === "undefined" ? ( element.getElementsByTagName("div")[0].getAttribute("max") || 100) : editorParams.max, min = typeof editorParams.min === "undefined" ? ( element.getElementsByTagName("div")[0].getAttribute("min") || 0) : editorParams.min, percent = (max - min) / 100, value = cell.getValue() || 0, handle = document.createElement("div"), bar = document.createElement("div"), mouseDrag, mouseDragWidth; //set new value function updateValue(){ var calcVal = (percent * Math.round(bar.offsetWidth / (element.clientWidth/100))) + min; success(calcVal); element.setAttribute("aria-valuenow", calcVal); element.setAttribute("aria-label", value); } //style handle handle.style.position = "absolute"; handle.style.right = "0"; handle.style.top = "0"; handle.style.bottom = "0"; handle.style.width = "5px"; handle.classList.add("tabulator-progress-handle"); //style bar bar.style.display = "inline-block"; bar.style.position = "relative"; // bar.style.top = "8px"; // bar.style.bottom = "8px"; // bar.style.left = "4px"; // bar.style.marginRight = "4px"; bar.style.height = "100%"; bar.style.backgroundColor = "#488CE9"; bar.style.maxWidth = "100%"; bar.style.minWidth = "0%"; //style cell element.style.padding = "4px 4px"; //make sure value is in range value = Math.min(parseFloat(value), max); value = Math.max(parseFloat(value), min); //workout percentage value = Math.round((value - min) / percent); // bar.style.right = value + "%"; bar.style.width = value + "%"; element.setAttribute("aria-valuemin", min); element.setAttribute("aria-valuemax", max); bar.appendChild(handle); handle.addEventListener("mousedown", function(e){ mouseDrag = e.screenX; mouseDragWidth = bar.offsetWidth; }); handle.addEventListener("mouseover", function(){ handle.style.cursor = "ew-resize"; }); element.addEventListener("mousemove", function(e){ if(mouseDrag){ bar.style.width = (mouseDragWidth + e.screenX - mouseDrag) + "px"; } }); element.addEventListener("mouseup", function(e){ if(mouseDrag){ e.stopPropagation(); e.stopImmediatePropagation(); mouseDrag = false; mouseDragWidth = false; updateValue(); } }); //allow key based navigation element.addEventListener("keydown", function(e){ switch(e.keyCode){ case 39: //right arrow bar.style.width = (bar.clientWidth + element.clientWidth/100) + "px"; break; case 37: //left arrow bar.style.width = (bar.clientWidth - element.clientWidth/100) + "px"; break; case 13: //enter updateValue(); break; case 27: //escape cancel(); break; } }); element.addEventListener("blur", function(){ cancel(); }); return bar; }, //checkbox tickCross:function(cell, onRendered, success, cancel, editorParams){ var value = cell.getValue(), input = document.createElement("input"), tristate = editorParams.tristate, indetermValue = typeof editorParams.indeterminateValue === "undefined" ? null : editorParams.indeterminateValue, indetermState = false; input.setAttribute("type", "checkbox"); input.style.marginTop = "5px"; input.style.boxSizing = "border-box"; input.value = value; if(tristate && (typeof value === "undefined" || value === indetermValue || value === "")){ indetermState = true; input.indeterminate = true; } if(this.table.browser != "firefox"){ //prevent blur issue on mac firefox onRendered(function(){ input.focus(); }); } input.checked = value === true || value === "true" || value === "True" || value === 1; function setValue(blur){ if(tristate){ if(!blur){ if(input.checked && !indetermState){ input.checked = false; input.indeterminate = true; indetermState = true; return indetermValue; }else{ indetermState = false; return input.checked; } }else{ if(indetermState){ return indetermValue; }else{ return input.checked; } } }else{ return input.checked; } } //submit new value on blur input.addEventListener("change", function(e){ success(setValue()); }); input.addEventListener("blur", function(e){ success(setValue(true)); }); //submit new value on enter input.addEventListener("keydown", function(e){ if(e.keyCode == 13){ success(setValue()); } if(e.keyCode == 27){ cancel(); } }); return input; }, }; Tabulator.prototype.registerModule("edit", Edit);