Reputation: 9863
So I think this might be a bug in the data tables lib. I was able to reproduce this using just their example code in jsfiddle.
Steps to recreate:
NOTE: The Data table still remains filtered but the search fields are now all empty.
Has anyone else seen this or see something I'm doing wrong here?
This is the javascript
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/jquery.dataTables.js" type="text/javascript"></script>
<script src='https://code.jquery.com/jquery-1.12.4.js'></script>
<script src='https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js' type="text/javascript"></script>
<script src='https://cdn.datatables.net/select/1.2.5/js/dataTables.select.min.js' type="text/javascript"></script>
<script src='https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js' type="text/javascript"></script>
<script src='https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js' type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
const table = $('#example').DataTable({
stateSave: true
});
// Setup - add a text input to each footer cell
$('#example tfoot th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
} );
</script>
Most of the code was taken from this link https://datatables.net/examples/api/multi_filter.html
The expected functionality is that the data table should save state between loads and the search boxes should reload the filtered text when the page reloads.
Upvotes: 5
Views: 7198
Reputation: 11
The above mentioned answers didn't work. So I am posting the solution that works.
initComplete: function () {
this.api()
.columns()
.every(function () {
let column = this;
let title = column.footer().textContent;
// Create input element
let input = document.createElement('input');
input.placeholder = title;
input.value = column.search();
input.style.width = '100%';
column.footer().replaceChildren(input);
// Event listener for user input
input.addEventListener('keyup', () => {
if (column.search() !== this.value) {
column.search(input.value).draw();
}
});
});
},
input.value = column.search(); should be used at the time of input field creation. This will populate the correct value from the saved state.
Upvotes: 0
Reputation: 9863
So using a combination of my code and the answer above I came up with this solution
$(document).ready(function() {
const table = $('#example').DataTable({
stateSave: true
});
// Setup - add a text input to each footer cell
$('#example tfoot th').each( function (index,value) {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" value="'+table.column(index).search()+'"/>' );
} );
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
});
});
The main piece of code here that is the fix is
$(this).html( '<input type="text" placeholder="Search '+title+'" value="'+table.column(index).search()+'"/>' );
By first getting the index value pair while iterating over the columns
$('#example tfoot th').each( function (index,value)
Then, stealing from the answer above, injecting the search value from the column by index
$(this).html( '<input type="text" placeholder="Search '+title+'" value="'+table.column(index).search()+'"/>' );
Upvotes: 1
Reputation: 1542
It's because you've got stateSave
enabled. This performs the column searches as they were, which are internal to DataTables, but because your input elements are external and DataTables isn't aware of them, you have to populate those yourself. Take a look at this example, it does it in the initComplete
:
// Restore state saved values
var state = this.state.loaded();
if (state) {
var val = state.columns[this.index()];
input.val(val.search.search);
}
Upvotes: 6