I have a fairly simple table, and am currently using a bottom calculator formatter:
export let myTable = new Tabulator("#my-table", {
columns:[
{title:"ID", field:"id", headerSort:false, visible:false, responsive:2},
{formatter:"rowSelection", titleFormatter:"rowSelection", align:"center", bottomCalc:"sum", hozAlign:"center", headerSort:false, cellClick:function(e, cell){
cell.getRow().toggleSelect();
}},
{title:"Name", field:"address", width:300, bottomCalc:"count"},
{title:"My Data", field:"mydata", bottomCalc:avNoOutsiders},
],
});
export let avNoOutsiders = function(values, data, calcParams){
// filter outliers
let myArray = filterOutliers(values);
// filter any null or falsy values
let av = average(myArray);
return av
}
The code isn't super important, but what I'd like to be able to do is allow the user to de-select a row to exclude the value from this calculation.
The problem is, I don't understand how to access the isSelected()
function here, I think it's just the row()
I can access it. I can access the values
(all the column values) but there's no selection data there, I can access the data
- the whole table, but there's no way of determining which row it is, or whether it is selected or not.
My current direction of thinking is either
bottomCalcParams
. I don't understand how I would do this. This function returns a getRow() is not a function
error:function cellIsSelected(cell){
selected = cell.getRow().isSelected()
return {isSelected:selected};
}
or
var selectedRows = table.getSelectedRows()
causes a circular error if I try to put that into a column calc function. I can reference the table inside the table.Any ideas how I can access the row selection data to make a column calculation?
There might be an easier way, but one way to achive that would be to create a hidden placeholder column which can be updated to true/false upon row selection/deselection. Then you can use the values of this hidden column in your bottomCalc
function to exclude rows that are not selected. Here is an example where selecting a row will re-trigger bottom calculation and average the age of all selections:
const dataSet1 = [
{ id: 1, name: 'Billy Bob', age: '21', gender: 'male' },
{ id: 2, name: 'Mary May', age: '5', gender: 'female' },
{ id: 3, name: 'Christine Lobowski', age: '42', gender: 'female' },
{ id: 4, name: 'Brendon Philips', age: '80', gender: 'male' },
]
const calcAvg = (values, data, calcParams) => {
let selected = data.filter((row) => row.isSelected)
values = selected.map((i) => i.age)
let avg = values.reduce((a, b) => Number(a) + Number(b), 0) / values.length
return avg ? avg : ''
}
const table = new Tabulator('#table', {
data: dataSet1,
columns: [
{
formatter: 'rowSelection',
titleFormatter: 'rowSelection',
cellClick: (e, cell) => {
cell.getRow().toggleSelect()
}
},
{ title: 'Name', field: 'name' },
{ title: 'Age', field: 'age', bottomCalc: calcAvg },
{ title: 'Gender', field: 'gender' },
{ title: '', field: 'isSelected', visible: false } // Selection placeholder column
]
})
const selection = (row) => {
row.update({ isSelected: row.isSelected() })
table.recalc()
}
table.on('rowSelected', selection)
table.on('rowDeselected', selection)
<html>
<head>
<link href="https://unpkg.com/[email protected]/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/[email protected]/dist/js/tabulator.min.js"></script>
</head>
<body>
<div id="table"></div>
</body>
<html>