I've been going through Tabulator and so far think it's great in functionality and what it can achieve. However, I have been stuck for half a day trying to get some seemingly basic functionality working. It is to allow the user to input numerical values in a quantity field, and then it will calculate a total in a new column based on quantity * price.
I have looked and tried everything I can find online but it still does not work as intended. I feel it's mostly to my understanding of how mutators work. I did get one to work in a different page which statically calculated the values based on a stock value * price.
Here is what I have so far:
var totalEditor = function(cell, onRendered, success, cancel){
//cell - the cell component for the editable cell
//onRendered - function to call when the editor has been rendered
//success - function to call to pass the successfuly updated value to Tabulator
//cancel - function to call to abort the edit and return to a normal cell
var price = cell.getData().price;
var cellValue = cell.getValue(),
input = document.createElement("input");
input.setAttribute("type", "number");
input.value = cellValue;
onRendered(function()
{
input.focus();
input.style.height = "100%";
});
function onChange()
{
if(input.value >= 0)
{
success(cell.getRow().getData().quantity = input.value);
success(cell.getRow().getData().total = input.value * price);//Thought this would work
}
else
{
cancel();
}
}
//submit new value on blur or change
input.addEventListener("blur", onChange);
//submit new value on enter
input.addEventListener("keydown", function(e){
if(e.keyCode == 13){
onChange();
}
if(e.keyCode == 27){
cancel();
}
});
return input;
};
//custom mutator for static total calculation
var totalMutator = function(value, data, type, params, mutatorParams){
var qty = data.quantity;
var price = data.price;
return (Math.abs(qty) * Math.abs(price));
}
var table = new Tabulator("#example-table", {
//data:array2,
layout:"fitColumns",
placeholder:"No Data Set",
reactiveData: true,
columnCalcs:"both",
initialSort:[
{column:"name", dir:"asc"}, //sort by this first
],
columns:[
{title:"SKU", field:"sku", sorter:"string", width:100},
{title:"Name", field:"name", sorter:"string",headerFilter:"input"},
{title:"Price", field:"price", formatter: "money", formatterParams: { decimal: ".", thousand: ",", symbol: "$", precision: false,}, sorter:"number", width:100, align:"center"},
{title:"Quantity", width:100, field:"quantity", align:"center", editor:totalEditor, editorParams:{min:0,max:1000,step:1,}},
{title: "Total", width:100, field:"total", sorter:"number", align: "center", formatter: "money",formatterParams: { decimal: ".", thousand: ",", symbol: "$"}},
],
});
I also note that the input then does not not allow you to increment via the up and down arrows of the input box being number type.
Managed to get it working via updating the cell value through a cell edited function on the quantity cell. I also think that due to the total cell not being part of the data (a new cell created for the table) I needed to access it via getCell("total) rather than getData().total
var table = new Tabulator("#example-table", {
layout:"fitColumns",
placeholder:"No Data Set",
reactiveData: true,
columnCalcs:"both",
dataEdited:function(data){
},
initialSort:[{column:"name", dir:"asc"},],
columns:[
{title:"SKU", field:"sku", sorter:"string", width:100},
{title:"Name", field:"name", sorter:"string",headerFilter:"input"},
{title:"Price", field:"price", formatter: "money", formatterParams: { decimal: ".", thousand: ",", symbol: "$", precision: false,}, sorter:"number", width:100, align:"center"},
{title:"Quantity", width:100, field:"quantity", align:"center", editor: true,
cellEdited: function(cell) {
cell.getRow().getCell("total").setValue(cell.getRow().getData().price * cell.getValue());
}},
{title: "Total", width:100, field:"total", sorter:"number", align: "center", formatter: "money",formatterParams: { decimal: ".", thousand: ",", symbol: "$"}},
],
});