问题
I have a datatable with footer filtering. Each column has 1 value which works perfect with the default way of handling the footer filtering:
//Add footer filtering
this.api().columns([2, 6, 7, 8, 9, 10]).every(function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function (d, j) {
console.log(d);
if (d) {
var val = $('<div/>').html(d).text();
select.append('<option value="' + val + '">' + val + '</option>')
}
});
});
Now the exception (column 6); there is one column which is filled in with 3 possibilities:
1) empty
2) array with one value
3) array with multiple values
Atm when selecting an option in the dropdown the filtering will not find any results i think because it searches on text and the data there is send as an array (see below). The html in de datatable itself is inserted as followed:
<span class="badge badge-pill badge-primary">suborg test met lange titel</span>
I've searched far and wide but I cannot seem to find a correct approach for my solution. The result should be that the footer filter dropdown will contain a row for each seperate tag and that it actually filters. So the ideal outcome would be:
(note that this is edited directly in the HTMl as ex)
In the code snippet above there is a console log which shows how the data is passed for that column:
I've figured to create a specific footer filtering for that column but i'm really stuck on how to handle the array data:
this.api().columns(6).every( function () {}
Who can provide me the golden tip i'm missing?
Thanks in advance
EDIT
I've been able to loop through the data and get better options in the dropdown:
This by using the following code:
column.data().unique().sort().each(function (d, j) {
if (d) {
$.each(d, function (index, value) {
var val = $('<div/>').html(value).text();
select.append('<option value="' + val + '">' + val + '</option>');
});
}
});
However the filtering doesn't match any results in the datatable.. Still very stuck on this.
回答1:
can you remove these search extra values and check
column.search(val ? '^' + val + '$' : '', true, false).draw();
to
column.search(val).draw();
you can also search each column through--
//indexcolumn--where we need the filter (column index )
initComplete: function()
{
this.api().columns(indexcolumn).every(function()
{
var column = this;
$('input', this.header()).on('keyup', function() {
if (column.search() !== this.value) {
column
.search(this.value)
.draw();
}
});
});
}
for more information-- https://jsfiddle.net/vigneshwarannevilish/gx5vh9jm/73/
回答2:
Here is a stand-alone solution, using a slightly different approach.
You can load the following text into a file and open it in a browser. It contains two filters:
- a text input filter on column 1
- a drop-down (select) filter on column 2
The filters work in combination with each other (which I assume you would want, if you have multiple column filters of different types). The drop-down is ordered and de-duped, and is based on the tags in the table's column, when the table is first rendered.
There's a global search field, but that can be switched off if you don't need it.
An example screenshot:
The HTML page:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Animals</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<style>
.boxed {
border: 1px solid grey;
padding: 2px;
margin: 0 2px;
}
</style>
</head>
<body>
<div style="margin: 20px;">
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr><th>Animal</th><th>Color</th></tr>
</thead>
<tbody>
<tr><td>antelopes</td><td><span class="boxed">blue</span><span class="boxed">green</span></td></tr>
<tr><td>elephants</td><td><span class="boxed">red</span><span class="boxed">yellow</span></td></tr>
<tr><td>hounds</td><td><span class="boxed">blue</span><span class="boxed">green</span></td></tr>
<tr><td>kittens</td><td></td></tr>
<tr><td>lions</td><td><span class="boxed">blue</span></td></tr>
<tr><td>ravens</td><td><span class="boxed">black</span></td></tr>
<tr><td>whales</td><td><span class="boxed">red</span><span class="boxed">green</span></td></tr>
<tr><td>zebras</td><td><span class="boxed">blue</span></td></tr>
</tbody>
<tfoot>
<tr><th>Animal</th><th>Color</th></tr>
</tfoot>
</table>
</div>
<script type="text/javascript">
$(document).ready(function() {
// DataTable
var table = $('#example').DataTable();
// Setup - add a text input to first footer cell
$('#example tfoot th').slice(0, 1).each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
// Setup - add a select list to second footer cell
$('#example tfoot th').slice(1, 2).each( function () {
var html = buildDropdown();
$(this).html( html );
} );
$('#colorSelect').change(function() {
table.draw();
});
// Apply the input field search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that.search( this.value ).draw();
}
} );
} );
function buildDropdown() {
var selectHtml;
var items = [];
table.columns([1]).data().each(function (d, j) {
$( "span.boxed" ).each(function( index ) {
var newItem = $( this ).text();
if (items.indexOf(newItem) === -1) {
items.push(newItem);
}
});
});
items.sort();
//console.log(items);
selectHtml = '<select id="colorSelect"><option value=""></option>';
items.forEach(function(item) {
selectHtml = selectHtml + '<option value="' + item + '">' + item + '</option>';
});
selectHtml = selectHtml + '</select>';
return selectHtml;
}
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var selectedValue = $('#colorSelect').val();
if (data[1].includes(selectedValue)) {
//console.log("match!");
return true;
} else {
return false;
}
}
);
} );
</script>
</body>
来源:https://stackoverflow.com/questions/60523467/datatables-handle-array-data-in-the-footer-filtering