I am currently working with Tabulator.js and trying to create a column that has a multi-select feature with a search option. I've attempted to implement this using the Select2 library, but I'm running into some issues.
Here is the code I've been using:
const tabledata = [
{
id: 1,
name: "Oli Bob",
select2: ['two', 'three']
},
{
id: 2,
name: "Mary May",
select2: ['two']
},
{
id: 3,
name: "Christine Lobowski",
select2: ['two']
},
{
id: 4,
name: "Brendon Philips",
select2: ['two']
},
{
id: 5,
name: "Margret Marmajuke",
},
];
const list = [
{
id: 'one',
text: 'one'
},
{
id: 'two',
text: 'two'
},
{
id: 'three',
text: 'three'
}
];
const select2Editor = function (cell, onRendered, success, cancel, editorParams) {
const editor = document.createElement("select");
onRendered(function () {
const select_2 = $(editor);
select_2.select2({
data: list,
width: '100%',
multiple: true,
minimumInputLength: 0,
})
if (typeof cell.getValue() == 'object') {
const selectedValuesIds = cell.getValue().map(val => list.find(x => x.text == val).id)
select_2.val(selectedValuesIds).trigger('change')
}
select_2.on('select2:select select2:unselect', () => {
const data = select_2.select2('data')
const cellValue = data.map(el => el.text)
success(cellValue)
});
// $(editor).on('blur', () => cancel)
editor.focus()
});
return editor;
};
const table = new Tabulator("#table", {
// debugEventsExternal: true,
// debugEventsInternal: true,
height: "500px",
data: tabledata,
rowHeight: 32,
columns: [
{
title: "Name",
field: "name",
width: 150
},
{
title: "Select2",
field: "select2",
width: 300,
editor: select2Editor,
},
],
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<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>
<div id="table"></div>
With this code, I've encountered the following problems:
To open the list, I first have to click on the cell to get the editor to appear, and then click again for the list to appear. This feels cumbersome and unintuitive.
If I click on other non-editable cells with the list open, the focus doesn't go away. I tried adding "$(editor).on('blur', () => cancel)", but then the list doesn't open at all because when the list opens, the focus shifts to the select2 element and the editor closes.
I'm wondering if there's a simpler way to implement this feature, perhaps without using additional libraries, or is there something I'm missing in my current approach using Select2? Any help or guidance would be greatly appreciated. Thank you!
For the first case, you can use the open method.
For the second case, you can use the select2:close event.