Search code examples
tabulator

Why is my tabulator custom header filter changing on keyup?


To reproduce:

  1. Run the Code Snippet (recommend Full Page mode)
  2. Hold Ctrl or Shift while clicking to select multiple 'species' in the table column header
  3. Note that while the key is held down, the table data is filtered according to selected 'species'
  4. Release the key, observe changes in filtered table data

I think this is probably related to https://github.com/olifolkerd/tabulator/issues/975 and that I need to do something to override default tabulator keypress events.

JSFiddle: https://jsfiddle.net/jjech/3th28pv0/229/

const speciesTypes = [ 'Human', 'Android', 'Betazoid', 'Klingon', 'Ferengi', 'Tamarian' ];

function multiSelectHeaderFilter(cell) {

	var values = speciesTypes;

	const filterFunc = (rowData) => {
  	return values.includes(rowData['species']);
	}

  const getSelectedValues = (multiSelect) => {
    var result = [];
    var options = multiSelect && multiSelect.options;
    var opt;

    for (var i=0, iLen=options.length; i<iLen; i++) {
      opt = options[i];

      if (opt.selected) {
        result.push(opt.value || opt.text);
      }
    }
    return result;
  }

	const onChange = () => {
  	var editor = document.getElementById('speciesSelector');
    values = getSelectedValues(editor);
    console.log("values: "+values);
    cell.getColumn().getTable().removeFilter(filterFunc);
    cell.getColumn().getTable().addFilter(filterFunc);
  }

	var select = document.createElement("select");
  select.multiple = "multiple";
	select.id = 'speciesSelector';
  select.style = 'width: 100%';
  speciesTypes.forEach(species => { 
  	select.innerHTML += "<option id='"+species+"' value='"+species+"' selected='selected'>"+species+"</option>";
  });
  cell.getColumn().getTable().addFilter(filterFunc);
  select.addEventListener('change',onChange);
  return select;
}

var table = new Tabulator("#tabulator", {
	layout:"fitColumns",
	data:[ {name:'Geordi La Forge',species:'Human'}, {name:'Dathon', species:'Tamarian'}, {name:'Jean-Luc Picard', species:'Human'}, {name:'Worf, son of Mogh', species:'Klingon'}, {name:'Tasha Yarr', species:'Human'}, {name:'Data', species:'Android'}, {name:'Wesley Crusher', species:'Human'}, {name:'Jalad', species:'Tamarian'}, {name:'Lwaxana Troi', species:'Betazoid'}, {name:'Temba', species:'Tamarian'}, {name:'T\'Kuvma', species:'Klingon'}, {name:'Lore', species:'Android'}, {name:'Noonian Soongh', species:'Human'}, {name:'Darmok', species:'Tamarian'}, {name:'Reittan Grax', species:'Betazoid'}, {name:'Quark', species:'Ferengi'} ],
	headerSort:true,
	columns:[ {title:'Name',field:'name',sorter:'string'},{title:'Species',field:'species',sorter:'string',headerFilter:multiSelectHeaderFilter }, ],
});

//document.multiselect('#speciesSelector');
<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>
<link href="https://cdn.jsdelivr.net/gh/mneofit/multiselect/styles/multiselect.css" rel="stylesheet">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/mneofit/multiselect/multiselect.min.js"></script>
<script></script>
<style>
.tabulator .tabulator-header,
.tabulator .tabulator-header .tabulator-col
{
  overflow: unset;
}
</style>
</head>
<body>
<div id="tabulator"></div>
</body>
</html>


Solution

  • Fixed by adding headerFilterLiveFilter:false to the column definition.

    columns:[ {title:'Name',field:'name',sorter:'string'},{title:'Species',field:'species',sorter:'string',headerFilter:multiSelectHeaderFilter,headerFilterLiveFilter:false }, ],
    

    https://jsfiddle.net/jjech/3th28pv0/237/