tabulator-tables
Version:
Interactive table generation JavaScript library
589 lines (455 loc) • 13.4 kB
JavaScript
import Helpers from '../../../../core/tools/Helpers.js';
//dropdown select editor
export default function(cell, onRendered, success, cancel, editorParams){
var self = this,
cellEl = cell.getElement(),
initialValue = cell.getValue(),
vertNav = editorParams.verticalNavigation || "editor",
initialDisplayValue = typeof initialValue !== "undefined" || initialValue === null ? (Array.isArray(initialValue) ? initialValue : [initialValue]) : (typeof editorParams.defaultValue !== "undefined" ? editorParams.defaultValue : []),
input = document.createElement("input"),
listEl = document.createElement("div"),
multiselect = editorParams.multiselect,
dataItems = [],
currentItem = {},
displayItems = [],
currentItems = [],
blurable = true,
blockListShow = false,
searchWord = "",
searchWordTimeout = null;
if(Array.isArray(editorParams) || (!Array.isArray(editorParams) && typeof editorParams === "object" && !editorParams.values)){
console.warn("DEPRECATION WARNING - 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(field){
var output = {},
data = self.table.getData(),
column;
if(field){
column = self.table.columnManager.getColumnByField(field);
}else{
column = cell.getColumn()._getSelf();
}
if(column){
data.forEach(function(row){
var val = column.getFieldValue(row);
if(val !== null && typeof val !== "undefined" && val !== ""){
output[val] = true;
}
});
}else{
console.warn("unable to find matching column to create select lookup list:", field);
}
return Object.keys(output);
}
function parseItems(inputValues, curentValues){
var dataList = [];
var displayList = [];
function processComplexListItem(item){
var item = {
label:item.label,
value:item.value,
itemParams:item.itemParams,
elementAttributes: item.elementAttributes,
element:false,
};
// if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
// setCurrentItem(item);
// }
if(curentValues.indexOf(item.value) > -1){
setItem(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,
itemParams:value.itemParams,
elementAttributes:value.elementAttributes,
element:false,
};
displayList.push(item);
value.options.forEach(function(item){
processComplexListItem(item);
});
}else{
processComplexListItem(value);
}
}else{
item = {
label:value,
value:value,
element:false,
};
// if(item.value === curentValue || (!isNaN(parseFloat(item.value)) && !isNaN(parseFloat(item.value)) && parseFloat(item.value) === parseFloat(curentValue))){
// setCurrentItem(item);
// }
if(curentValues.indexOf(item.value) > -1){
setItem(item);
}
dataList.push(item);
displayList.push(item);
}
});
}else{
for(var key in inputValues){
var item = {
label: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);
// }
if(curentValues.indexOf(item.value) > -1){
setItem(item);
}
dataList.push(item);
displayList.push(item);
}
}
if(editorParams.sortValuesList){
dataList.sort((a, b) => {
return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0);
});
displayList.sort((a, b) => {
return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0);
});
if(editorParams.sortValuesList !== "asc"){
dataList.reverse();
displayList.reverse();
}
}
dataItems = dataList;
displayItems = displayList;
fillList();
}
function fillList(){
while(listEl.firstChild) listEl.removeChild(listEl.firstChild);
displayItems.forEach(function(item){
var el = item.element;
if(!el){
el = document.createElement("div");
item.label = editorParams.listItemFormatter ? editorParams.listItemFormatter(item.value, item.label, cell, el, item.itemParams) : item.label;
if(item.group){
el.classList.add("tabulator-edit-select-list-group");
el.tabIndex = 0;
el.innerHTML = item.label === "" ? " " : item.label;
}else{
el.classList.add("tabulator-edit-select-list-item");
el.tabIndex = 0;
el.innerHTML = item.label === "" ? " " : item.label;
el.addEventListener("click", function(){
blockListShow = true;
setTimeout(() => {
blockListShow = false;
}, 10);
// setCurrentItem(item);
// chooseItem();
if(multiselect){
toggleItem(item);
input.focus();
}else{
chooseItem(item);
}
});
// if(item === currentItem){
// el.classList.add("active");
// }
if(currentItems.indexOf(item) > -1){
el.classList.add("active");
}
}
if(item.elementAttributes && typeof item.elementAttributes == "object"){
for (let key in item.elementAttributes){
if(key.charAt(0) == "+"){
key = key.slice(1);
el.setAttribute(key, input.getAttribute(key) + item.elementAttributes["+" + key]);
}else{
el.setAttribute(key, item.elementAttributes[key]);
}
}
}
el.addEventListener("mousedown", function(){
blurable = false;
setTimeout(function(){
blurable = true;
}, 10);
});
item.element = el;
}
listEl.appendChild(el);
});
}
function setCurrentItem(item, active){
if(!multiselect && currentItem && currentItem.element){
currentItem.element.classList.remove("active");
}
if(currentItem && currentItem.element){
currentItem.element.classList.remove("focused");
}
currentItem = item;
if(item.element){
item.element.classList.add("focused");
if(active){
item.element.classList.add("active");
}
}
if(item && item.element && item.element.scrollIntoView){
item.element.scrollIntoView({behavior: 'smooth', block: 'nearest', inline: 'start'});
}
}
// function chooseItem(){
// hideList();
// if(initialValue !== currentItem.value){
// initialValue = currentItem.value;
// success(currentItem.value);
// }else{
// cancel();
// }
// }
function setItem(item) {
var index = currentItems.indexOf(item);
if(index == -1){
currentItems.push(item);
setCurrentItem(item, true);
}
fillInput();
}
function unsetItem(index) {
var item = currentItems[index];
if(index > -1){
currentItems.splice(index, 1);
if(item.element){
item.element.classList.remove("active");
}
}
}
function toggleItem(item) {
if(!item){
item = currentItem;
}
var index = currentItems.indexOf(item);
if(index > -1){
unsetItem(index);
}else{
if(multiselect !== true && currentItems.length >= multiselect){
unsetItem(0);
}
setItem(item);
}
fillInput();
}
function chooseItem(item){
hideList();
if(!item){
item = currentItem;
}
if(item){
input.value = item.label;
success(item.value);
}
initialDisplayValue = [item.value];
}
function chooseItems(silent){
if(!silent){
hideList();
}
var output = [];
currentItems.forEach((item) => {
output.push(item.value);
});
initialDisplayValue = output;
success(output);
}
function fillInput(){
var output = [];
currentItems.forEach((item) => {
output.push(item.label);
});
input.value = output.join(", ");
if(self.currentCell === false){
chooseItems(true);
}
}
function unsetItems() {
var len = currentItems.length;
for(let i = 0; i < len; i++){
unsetItem(0);
}
}
function cancelItem(){
hideList();
cancel();
}
function showList(){
currentItems = [];
if(!listEl.parentNode){
if(editorParams.values === true){
parseItems(getUniqueColumnValues(), initialDisplayValue);
}else if(typeof editorParams.values === "string"){
parseItems(getUniqueColumnValues(editorParams.values), initialDisplayValue);
}else{
parseItems(editorParams.values || [], initialDisplayValue);
}
var offset = Helpers.elOffset(cellEl);
listEl.style.minWidth = cellEl.offsetWidth + "px";
listEl.style.top = (offset.top + cellEl.offsetHeight) + "px";
listEl.style.left = offset.left + "px";
listEl.addEventListener("mousedown", function(e){
blurable = false;
setTimeout(function(){
blurable = true;
}, 10);
});
document.body.appendChild(listEl);
}
}
function hideList(){
if(listEl.parentNode){
listEl.parentNode.removeChild(listEl);
}
removeScrollListener();
}
function removeScrollListener() {
self.table.rowManager.element.removeEventListener("scroll", cancelItem);
}
function scrollTovalue(char){
clearTimeout(searchWordTimeout);
var character = String.fromCharCode(event.keyCode).toLowerCase();
searchWord += character.toLowerCase();
var match = dataItems.find((item) => {
return typeof item.label !== "undefined" && item.label.toLowerCase().startsWith(searchWord);
});
if(match){
setCurrentItem(match, !multiselect);
}
searchWordTimeout = setTimeout(() => {
searchWord = "";
}, 800)
}
//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);
if(editorParams.elementAttributes && typeof editorParams.elementAttributes == "object"){
for (let key in editorParams.elementAttributes){
if(key.charAt(0) == "+"){
key = key.slice(1);
input.setAttribute(key, input.getAttribute(key) + editorParams.elementAttributes["+" + key]);
}else{
input.setAttribute(key, editorParams.elementAttributes[key]);
}
}
}
input.value = typeof initialValue !== "undefined" || initialValue === null ? initialValue : "";
// if(editorParams.values === true){
// parseItems(getUniqueColumnValues(), initialValue);
// }else if(typeof editorParams.values === "string"){
// parseItems(getUniqueColumnValues(editorParams.values), initialValue);
// }else{
// parseItems(editorParams.values || [], initialValue);
// }
input.addEventListener("search", function(e){
if(!input.value){
unsetItems();
chooseItems();
}
});
//allow key based navigation
input.addEventListener("keydown", function(e){
var index;
switch(e.keyCode){
case 38: //up arrow
index = dataItems.indexOf(currentItem);
if(vertNav == "editor" || (vertNav == "hybrid" && index)){
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
if(index > 0){
setCurrentItem(dataItems[index - 1], !multiselect);
}
}
break;
case 40: //down arrow
index = dataItems.indexOf(currentItem);
if(vertNav == "editor" || (vertNav == "hybrid" && index < dataItems.length - 1)){
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
if(index < dataItems.length - 1){
if(index == -1){
setCurrentItem(dataItems[0], !multiselect);
}else{
setCurrentItem(dataItems[index + 1], !multiselect);
}
}
}
break;
case 37: //left arrow
case 39: //right arrow
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
break;
case 13: //enter
// chooseItem();
if(multiselect){
toggleItem();
}else{
chooseItem();
}
break;
case 27: //escape
cancelItem();
break;
case 9: //tab
break;
default:
if(self.currentCell === false){
e.preventDefault();
}
if(e.keyCode >= 38 && e.keyCode <= 90){
scrollTovalue(e.keyCode);
}
}
});
input.addEventListener("blur", function(e){
if(blurable){
if(multiselect){
chooseItems();
}else{
cancelItem();
}
}
});
input.addEventListener("focus", function(e){
if(!blockListShow){
showList();
}
});
//style list element
listEl = document.createElement("div");
listEl.classList.add("tabulator-edit-select-list");
onRendered(function(){
input.style.height = "100%";
input.focus({preventScroll: true});
});
setTimeout(() => {
this.table.rowManager.element.addEventListener("scroll", cancelItem);
}, 10);
return input;
};