tabulatormutators

Tabulator calculating a total price


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.


Solution

  • 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: "$"}},       
    ],  
    });