I have a DataTables instance that appends a select in the header of a table. Here is a codepen showing it.
Here is the relevant part of code that adds the select to the header
initComplete: function () {
count = 0;
this.api().columns().every(function () {
var title = this.header();
//replace spaces with dashes
title = $(title).html().replace(/[\W]/g, '-');
var column = this;
var select = $('<br><select id="' title '" ></select>')
.appendTo($(column.header()))
.on('change', function () {
//Get the "text" property from each selected data
//regex escape the value and store in array
var data = $.map($(this).select2('data'), function (value, key) {
return value.text ? '^' $.fn.dataTable.util.escapeRegex(value.text) '$' : null;
});
//if no data selected use ""
if (data.length === 0) {
data = [""];
}
//join array into string with regex or (|)
var val = data.join('|');
//search for the option(s) selected
column
.search(val ? val : '', true, false)
.draw();
});
//unique, tipo group by
//sorte deixa em ordem abcd
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' d '">' d '</option>');
});
//use column title as selector and placeholder
$('#' title).select2({
multiple: true,
closeOnSelect: false,
placeholder: "Select a " title
});
//initially clear select otherwise first option is selected
$('.select2').val(null).trigger('change');
});
}
However I noticed that one downside of putting it in the header, is that when I click into the select, DataTables thinks I am sorting by that column. Is there a way to not sort the column if I am clicking inside the select (which has ID equal to the column name)
CodePudding user response:
There are two ways you can do it.
First is to disable sorting on click altogether. Just put this in your table options:
ordering: false,
The other option is to have two rows in the header. The first row should be th
with your column header, the second should be your dropdown filters inside a td
cell. This is because DataTables reserves a space inside th
cells for the sorting arrows even when they are not there.
<thead>
<tr>
<th>Demanda</th>
<th>Título</th>
<th>Solicitante</th>
<th>Data Inclusao</th>
<th>Área</th>
<th>SP</th>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
You would need to change your appendTo()
to something like this:
.appendTo($(`#example thead tr:eq(1) td`).eq(this.index()))
Then in your table options you can set
orderCellsTop: true,
this will allow sorting when you click the top header row and filtering from the dropdowns in the second header row.