Is it possible to add a dropdown to switch between column calculations?

42 Views Asked by At

I'm starting with the Tabulator in my project, I know that possible to define the bottomCalcParams to sum, avg, max, etc... but I need to add a dropdown in the column calculation at the bottom, to switch between the available options (Sum, Average, Min, Max and Count);

Is there any way to do this with Tabulator? How would you recommend implementing this feature?

Something like this: Dropdown to select the option

Tabulator Version: 5.6.1

Best regards

My first thought is to use the HTML Format to customize the bottomCalc.

1

There are 1 best solutions below

0
Timur On BEST ANSWER

One way would be to use bottomCalcFormatter to add a dropdown to the calculations with an event listener, which would update the calculation column definition on value change. Here is an example:

const tableData = [
  { id: 1, fullName: 'Oli Bob', age: '12', color: 'red' },
  { id: 2, fullName: 'Mary May', age: '1', color: 'blue' },
  { id: 3, fullName: 'Christine Lobowski', age: '42', color: 'green' },
  { id: 4, fullName: 'John Smith', age: '30', color: 'red' },
  { id: 5, fullName: 'Tim Burton', age: '51', color: 'blue' }
]

const table = new Tabulator('#table', {
  data: tableData,
  layout: 'fitDataFill',
  columns: [
    { title: 'Name', field: 'fullName' },
    {
      title: 'Age',
      field: 'age',
      bottomCalc: 'avg',
      bottomCalcFormatter: (cell, formatterParams, onRendered) => {
        const div = document.createElement('div')  // Wrapper div for the dropdown
        const select = document.createElement('select')  // Dropdown element

        //  Add options to dropdown
        select.innerHTML = `
          <option value="sum">Sum</option>
          <option value="avg">Average</option>
          <option value="count">Count</option>
          <option value="min">Min</option>
          <option value="max">Max</option>
        `
        
        // Add event listener to dropdown to update column definition on change
        select.addEventListener('change', () => {
          cell.getTable().updateColumnDefinition('age', { bottomCalc: select.value })
        })

        // Append dropdown to wrapper div
        div.appendChild(select)

        onRendered(() => {
          // Once rendered, prepend dropdown to calculaation result cell
          cell.getElement().prepend(div)

          // Set the value of the dropdown to current column definition value
          select.value = cell
            .getTable()
            .getColumnDefinitions()
            .filter((d) => d.field === 'age')[0].bottomCalc
        })

        // Return the calculation value
        return `<div>${cell.getValue()}</div>`
      }
    },
    { title: 'Color', field: 'color' }
  ]
})
<!DOCTYPE html>
<html lang="en">

<head>
  <link href="https://unpkg.com/[email protected]/dist/css/tabulator.min.css" rel="stylesheet" />
  <script src="https://unpkg.com/[email protected]/dist/js/tabulator.min.js"></script>
</head>

<body>
  <div id="table"></div>
</body>

</html>