Search code examples
javascripttabulator

Detect row selection change from inside a cell component


I'm using Tabulator for some data needs in my application and have created a few custom cell.s

I currently have a custom cell with an "Edit" button that toggles the row selection and its editibility. There is also a button external from the grid to allow for selecting all rows (as shown in the screenshot)

enter image description here

What I would like to do is have the button change from "Edit" to "Cancel" when the row is highlighted (either by clicking the "Edit" button or when all rows are selected programmatically).

From with in the cell I can get the current row selection by doing cell.getRow().isSelected() but I don't see a way to detecting when a particular row selection has changed.

One solution I have in mind is to use CSS to hide/show the "Edit" or "Cancel" button since Tabulator will add the class tabulator-selected to anything that is highlighted. But this seems more like a hack.

Thanks in advance for the thoughts, opinions and comments!


In case it's relevant, I'm using Tabulator wrapped in a Vue component. The custom cell is just vanilla JS at the moment.


Solution

  • I figured out what appears to be a suitable way of detecting row-selection change from with in a cell. It uses the MutationObserver API and checks the row-element for the tabulator-selected CSS class.

    (I also opened a feature request on GitHub, so maybe in the future there will be a different way to handle this)

    /**
     * A custom formatter/cell to enable the selection of an individual row
     *
     * @param {Object} cell Tabulator Cell object
     * @returns {HTMLElement}
     */
    export default function(cell) {
      const checkbox = document.createElement('input')
      checkbox.type = 'checkbox'
      checkbox.onchange = function() {
        cell.getRow().toggleSelect()
      }
    
      // Callback function to execute when mutations are observed
      function mutationCallback(mutationsList) {
        for (let mutation of mutationsList) {
          // if you are using something other than a checkbox, you would perform the element changes in there
          checkbox.checked = mutation.target.classList.contains('tabulator-selected')
        }
      }
    
      // Create an observer to only watch for attribute changes (like CSS classes) and activate it
      const rowEl = cell.getRow().getElement()
      // list of all available config options: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit
      const config = { attributes: true, attributeFilter: ['class'] }
      const observer = new MutationObserver(mutationCallback)
      observer.observe(rowEl, config)
    
      return checkbox
    }