Search code examples
javascriptjquery-select2tabulator

How can you get Tabulator to use Select2 header filter?


Following the example here, we've been trying for over a week to get Tabulator working with a Select2 header filter. There is a JS Fiddle here with all the pieces. It seems like the Tabulator filter (which are really just editors) onRendered() function is not even getting called because the console log we have inside it never gets logged.

The select element itself shows up in the header filter, but never gets the Select2 object applied (probably because the onRendered seems to not even be called). If we put the Select2 object outside the onRendered function, it get applied, but then the filter does not get applied after selection is made. There are no console or other errors and we've followed the Tabulator 'example' to the letter, so we are not sure what to try next.

Does anyone know how to get a basic Select2 header filter functioning with Tabulator?

var tableData = [{
    id: "1",
    topic: "1.1"
  },
  {
    id: "2",
    topic: "2.2"
  },
];

var select2Editor = function(cell, onRendered, success, cancel, editorParams) {
  var editor = document.createElement("select");
  var selData = [{
    id: '1.1',
    text: "One"
  }, {
    id: "2.2",
    text: "Two"
  }, {
    id: "3.3",
    text: "Three"
  }, ];

  onRendered(function() {
    // TODO: map tracks to id and text
    console.log('rendered');

    $(editor).select2({
      data: selData,
      minimumResultsForSearch: Infinity,
      width: '100%',
      minimumInputLength: 0,
      //allowClear: true,
    });
    
    $(editor).on('change', function(e) {
      success($(editor).val());
    });


    $(editor).on('blur', function(e) {
      cancel();
    });

  });


  return editor
};


var columns = [{
  title: "ID",
  field: "id"
}, {
  title: "Topic",
  field: "topic",
  headerFilter: select2Editor,
}, ];


var table = new Tabulator("#table", {
  placeholder: "No Data Found.",
  layout: "fitData",
  data: tableData,
  columns: columns,
});

Solution

  • I'm new to both Tabulator and select2 and I think this is possibly a bad way to do it but it seems like it miiight work.

    If you want to use select2 with text input elements, it looks like you need to use the full package.

    https://jsfiddle.net/dku41pjy/

    var tableData = [{
        id: "1",
        topic: "1.1"
      },
      {
        id: "2",
        topic: "2.2"
      },
    ];
    
    var columns = [{
      title: "ID",
      field: "id"
    }, {
      title: "Topic",
      field: "topic",
      headerFilter: 'select2Editor'
    }, ];
    
    var awaiting_render = [];
    
    function do_render({ editor, cell, success, cancel, editorParams }) {
      console.log('possibly dodgy onrender');
        var selData = [{
        id: '',
        text: "-- All Topics --"
      }, {
        id: '1.1',
        text: "One"
      }, {
        id: "2.2",
        text: "Two"
      }, {
        id: "3.3",
        text: "Three"
      }, ];
      
      $(editor).select2({
        data: selData,
        //allowClear: true,
      });
    
      $(editor).on('change', function(e) {
        console.log('chaaaange')
        success($(editor).val());
      });
    
    
      $(editor).on('blur', function(e) {
        cancel();
      });
          
    }
    function render_awaiting() {
        var to_render = awaiting_render.shift();
      do_render(to_render);
      if(awaiting_render.length > 0)
        render_awaiting();
    }
    
    Tabulator.prototype.extendModule("edit", "editors", {
        select2Editor:function(cell, onRendered, success, cancel, editorParams) {
          console.log(cell);
          var editor = document.createElement("input");
          editor.type = 'text';
          awaiting_render.push({ editor, cell, success, cancel, editorParams });
    
          return editor
        },
    });
    
    var table = new Tabulator("#table", {
      placeholder: "No Data Found.",
      layout: "fitData",
      data: tableData,
      columns: columns,
      tableBuilt:function(){
        render_awaiting();
      },
    });
    

    Edit: my suspicion is that onRendered only gets fired when these edit elements are used in cells to sope with the transition between showing just data and showing an editable field.