Application is using:
- DataTables 1.10.18
- jquery 3.2.1
- PHP back-end
- lodash 4.17.4
The application contains a web page which consists of multiple DataTables. Each of these uses serverSide: true
(server-side mode) to obtain the data via an ajax endpoint which returns JSON data.
The tables are initialised as follows:
On page load several
<table>
's are rendered. I'm using a jquery.each()
to initialise the DataTable for each one:$.each($('table'), function () { $(this).DataTable({ processing: true, serverSide: true, searching: false, ajax: { data: { table_id: $(this).attr('id') }, url: '/get-data.json', }, ... });
Each
<table>
has an ID. This is passed via ajax in thedata:
attribute. The endpoint/get-data.json
returns data based on the table ID. In other words it knows "which table" the data should be obtained for based on this ID.
I want to be able to do searching on tables, but it must be done server-side. For this reason my initialisation code in (1) sets searching: false
because this effectively disables the client-side search facility that DataTables provides (which we can't use in this instance as searching must be done server-side).
The problem I'm facing is how to create search inputs for each table, make an ajax call and update the appropriate table. I want the search to work in realtime after >=3 characters have been entered. Critical to this question is that 1 search input is responsible for searching 1 DataTable - it's not a search feature where the input can update "any/every table on the page" which is a commonly described pattern in other questions. 1 input : searching 1 table in this case.
My plan has been as follows - each table referenced in point (2) has an ID. I need to create unique inputs. So if I have tables with ID's #table1
, #table2
, #table3
I can easily create:
<input type="text" name="table1_search" id="table1_search">
<input type="text" name="table2_search" id="table2_search">
<input type="text" name="table3_search" id="table3_search">
I then detect if any changes have occurred on inputs:
$('input[type="text"]').bind("keyup change input",
function (e) {
// Ignore tab key for keyup event otherwise it'll fire an ajax request that does nothing useful.
if (e.which !== 9) {
processSearch.call(this);
} else {
e.preventDefault();
}
});
var prev_value = {};
function processSearch() {
var obj = $(this),
search_id = obj.attr('id'), // ID of input
search_value = obj.val(); // Value of input
// There's been no change to the field, ignore.
if (prev_value[search_id] === search_value) {
return;
}
prev_value[search_id] = search_value;
/* Wait until at least 3 characters have been entered, or user has cleared the input */
if (search_value.length >= 3 || (!search_value)) {
debouncedDraw({search_id: search_id, search_value: search_value});
}
}
The above code does what I need in terms of waiting for >=3 characters to be entered. I'm then executing a function called debouncedDraw
which passes an object containing search_id
and search_value
. These refer to the input ID and value respectively, e.g. if I type "foo" into #table1_search
then the object is:
{search_id: 'table1_search', search_value: 'foo'}
The debouncedDraw
function looks like this. This is using lodash to limit the rate at which the function can fire. The point here is to stop it making needless ajax requests based on a question I asked a few years ago here: DataTables - kill ajax requests when a new one has started:
var debouncedDraw = _.debounce(function (opts) {
console.log(opts);
}, 500);
At the moment this will just console.log
the object given above.
I'm unsure of the best way to proceed at this point. I need to re-run /get-data.json
via ajax and then update the appropriate table.
I could access the request data and split the search_id
based on the underscore to work out which table ID the data is for (e.g. table1_search
targets #table1
). I then need to write this data back to the appropriate table (#table1
in this case).
I can't help but think I'm going about this in a convoluted way and wondered if DataTables itself has any better ways of supporting this? It seems quite a basic requirement (multiple searchable tables in serverSide
mode). But I can't find any posts which refer how to do this specifically.