Tabulator calculating a total price - tabulator

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

Related

Tabulator - Styling empty cells

I'm trying to style only tabulator empty cells.
I tried with a custom formatter but it seems to be called only on cells with data.
Any suggestion on how to proceed?
Seems to process fields without data just fine ...
https://jsfiddle.net/udpr2680/
new Tabulator("#tabulator", {
data:[{id:4957},{id:39857,price:100}],
columns: [
{ title: "number", field: "id"},
{ title: "price", field: "price",formatter: function(c,fP,onR) { let p = c.getData().price; if (p === undefined) return "undefined"; return p; } },
],
});

Formatting date for Tabulator cell to dd/mm/yy

I am using Tabulator for an external JSON source.
The source gives the DOB in this format: 2020-04-16T00:00:00.000+0000
which I want to convert to dd/mm/yy
I have included the moment library.
I am using this code:
{title:"Date of Birth", field:"birthDate", sorter:"date", width:200, sorterParams:{format:"DD/MM/YY"}},
But no change is displayed - i just get the original format.
I have also tried this, but it also did not work.
{title:"Date of Birth", field:"birthDate", sorter:"date", width:200, formatter:dateFormatter},
//custom date formatter
var dateFormatter = function(cell, formatterParams){
var value = cell.getValue();
if(value){
value = moment(value , "YYYY/MM/DD").format("MM/DD/YYYY");
}
return value;
}
Thanks for your suggestions.
You need the datetime formatter:
http://tabulator.info/docs/4.7/format#format-builtin
For your custom formatter you are missing the onRendered argument.
The following 2 formats landed up working for me. Kudos to #adrian-klaver for the pointer to option #2
Option 1:
{title:"Date of Birth", field:"dob", width:150, formatter:function(cell, formatterParams, onRendered){
var value = cell.getValue();
value = moment(value).format("DD/MM/YYYY");
return value;
}},
Option 2:
{title:"Date of Birth", field:"dob", width:150, formatter:"datetime", formatterParams:{
inputFormat:"YYYY-MM-DD HH:ii",
outputFormat:"DD/MM/YY",
invalidPlaceholder:"(invalid date)",
timezone:"America/Los_Angeles",
}
},

Tabulator total Rows count (Column Calculations) gets exported as well

I am using this approach to show the total rows in a table:
var tabulator_table = new Tabulator("#example", {
columns: [
{ title: "name", field: "name", bottomCalc: "count", headerFilter: "input" },
{ title: "Type", field: "Type", bottomCalc: "count", headerFilter: "input" },
],
dataFiltered: function (filters, rows) {
var el = document.getElementById("search_count");
el.innerHTML = rows.length;
},
dataLoad: function (data) {
var el = document.getElementById("total_count");
el.innerHTML = data.length;
},
});
var total_count = $(".tabulator-footer").find('.tabulator-cell:first-child()').text();
$("#total_count").text(total_count);
$(".tabulator-footer").append("<span class='search_count' id='search_count'></span> Of<span class='search_result'>Total Productions: <span class='total_count'></span></span>")
var totalsearch = $("#total_count").text();
var resultsearch = $("#search_count").text();
$(".total_count").text(totalsearch)
$(".search_count").text(totalsearch);
//This CSS will hide the footer:
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
This works good but there is one issue: when i hit export to excel, it exports the calculation row as well such as:
Name Type
john human
1 1
How do I stop the count row (1 1) from being exported or is there other approach to show total rows.
This is the export function:
document.getElementById("myButtons").addEventListener("click", function () {
tabulator_table.download("xlsx", "name.xlsx", { sheetName: "Info" });
});
I think all you need is the downloadConfig option in your table options. http://tabulator.info/docs/4.6/download#advanced-config
So, just add downloadConfig: {columnCalcs: false} to your table options.
Here is a working example.
https://jsfiddle.net/nrayburn/0hn6v48r/11/

Uncaught TypeError: Cannot read property getColSpanningList

I am working with ag-Grid and Node.js to do some updates in the database. I am doing a calculation on 5 fields. I am using the onCellValueChanged event in order to do calculations for field2, field3, field4, field5 based of the change in field1. I can see the change when there is a mouse click event. However, the problem arises when I hit the TAB key on the keyboard. It gives me this error:
ag-grid-community.min.noStyle.js:110 Uncaught TypeError: Cannot read property 'getColSpanningList' of undefined
at t.getLastCellOfColSpan (ag-grid-community.min.noStyle.js:110)
at t.findNextCellToFocusOn (ag-grid-community.min.noStyle.js:110)
at t.moveToNextEditingCell (ag-grid-community.min.noStyle.js:110)
at t.moveToCellAfter (ag-grid-community.min.noStyle.js:110)
at t.onTabKeyDown (ag-grid-community.min.noStyle.js:110)
at t.onTabKeyDown (ag-grid-community.min.noStyle.js:242)
at t.onKeyDown (ag-grid-community.min.noStyle.js:242)
at t.processKeyboardEvent (ag-grid-community.min.noStyle.js:530)
This is my ejs template:
selection.ejs
var tableCols = <%- JSON.stringify(tables) %>;
var rowData = tableCols;
var columnDefs = [
{headerName: "Field1", field: "field1", editable: true},
{headerName: "Field2", field: "field2"},
{headerName: "Field3", field: "field3"},
{headerName: "Field4", field: "field4"},
{headerName: "Field5", field: "field5"},
{headerName: "Total", field: "total"}
];
var gridOptions = {
columnDefs: columnDefs,
rowData: rowData,
onCellValueChanged: function(params){
var d = params.data.field1;
var id = params.data.Unique_ID;
params.field2 = (.25 * params.data.field1).toFixed(2);
var q = params.data.field2;
params.data.field3 = (0 * params.data.field1).toFixed(2);
var b = params.data.field3;
params.data.field4 = (.175 * params.data.field1).toFixed(2);
var p = params.data.field4;
params.data.field5 = (.20 * params.data.field1).toFixed(2);
var a = params.data.field5;
params.data.total = (parseFloat(params.data.field1) + parseFloat(params.field2 ) + parseFloat(params.data.field3) + parseFloat(params.data.field4) + parseFloat(params.data.field5)).toFixed(0);
var t = params.data.total;
this.api.refreshCells();
},
onCellEditingStarted: function(event){
console.log("started");
},
// this is where the error happens, then logs "cellEditingStopped"
onCellEditingStopped: function(event) {
console.log('cellEditingStopped');
}
};
I don't understand how can pressing the TAB key cause the error, but not on MOUSE click. Any help would be appreciated. Thank you.
I can reproduce this issue. When you tab to the next column with editable: false, it will give the error. If you comment the option editable: false, tab will work without the problem.
I guess you may need to implement your own tabToNextCell: https://www.ag-grid.com/javascript-grid-keyboard-navigation/#tabtonextcell
I am figuring out how to skip the editable: false cell.

Autocomplete using values from AJAX

I have a table using tabulator.
Everything works great, but I am trying to get autocomplete working with Ajax
What I am trying is:
var customerNumbers = [];
var table = new Tabulator("#edi-table",
ajaxURL: baseUrl + '/PaginatedEndPoint',
pagination: "remote",
paginationSize: 30,
paginationSizeSelector: [30, 60, 100, 200],
ajaxSorting: true,
ajaxFiltering: true,
selectable: true,
cellEdited: function (cell) {
cell.getElement().style.backgroundColor = "#32CD32";
},
dataLoading: function () {
customerNumbers = ["11", "12", "13"];
},
columns: [
{
title: "CustomerNumber", field: "CustomerNumber", headerFilter: "input", editor: "autocomplete", editorParams: {
searchFunc: function (term, values) {
var matches = [];
values.forEach(function (item) {
if (item.value === term) {
matches.push(item);
}
});
console.log(matches);
return matches;
},
listItemFormatter: function (value, title) {
return "Mr " + title;
},
values: customerNumbers
}
}
]
However, this does not show any predictions value predictions for me, it seems that autocomplete is built before "dataLoading" or any other Callback (I have tried many) is called.
I have tried to make an auxilary array in the style of values like {Title: "Mr + title", value: "title"} and then assign it in the searchFunc, and it didn't work despite being returned in matches.
Is it even possible to dynamically create autofill?
It seems like the current autocomplete functionality does not allow for the editorParams to take a function as an argument to set the dropdown values. You can set it with an object of key/values if you can send that via AJAX, but as far as dynamically setting, altering, or searching the data, it seems like that's impossible to do at the moment.
The other option would be use the editor:"select", which can take a function to set its editorParams. It's not the best solution, but it's the one I had to go with at the moment.
There is an open issue on the Tabulator docs, but so far no response from the developers.
I wish I had a better answer for you!

Resources