ext.search.push not working with serverSide
ext.search.push not working with serverSide
Yesterday I noticed that filtering with ext.search.push does not work with serverSide data tables. I knew that the usual search doesn't work with serverSide tables because the search is performed on the server and not on the client. So any transformation of data base values on the server side creates a problem. Got used to that.
But I don't think it would be required for serverSide data tables that ext.search.push on the client side is turned off as well.
Can you turn it on for this please.
I mean it is optional anyway, so why turn it off for serverSide? Anyone who thinks this will impair performance doesn't have to use it.
Here is my use case:
I use the more or less same data table once with serverSide and once without serverSide for different purposes. ServerSide is needed to perform a full-text search on large documents that the user can upload and which are OCR-transformed with Tesseract if they aren't machine readable and then parsed to allow full-text search in all of the uploaded documents.
In both cases I have a custom button (not a data tables custom button) for the user to set whether she wants to see expired contracts or not and how long they may have been expired. The filtering is done with ext.search.push like this:
$.fn.dataTable.ext.search.push(
function (settings, data, dataIndex, row, counter) {
if (typeof row.ctr !== 'undefined') {
if (row.ctr.expired > '0') {
return filterShowNMonths(row.ctr.end_date);
}
}
return true;
}
);
With the help of the debugger I found out that this logic isn't executed for serverSide data tables. Would be great if this could change.
This is my work around for serverSide:
ajax: {
url: 'actions.php?action=tblCtrManagement',
type: 'POST',
data: function ( d ) {
if ( serverSide ) {
d.startDateExpired = nMonthsAgo( $('#monthsSelect').val() );
}
}
},
->where( function ( $q ) {
if ( isset($_POST['startDateExpired']) ) {
$q ->where( function ( $r ) {
$r ->where( 'ctr.expired', 0 )
->or_where( function ( $s ) {
$s ->where( 'ctr.expired', 1 )
->where( 'ctr.end_date', $_POST['startDateExpired'] . ' 00:00:00', '>=');
} );
} );
}
} )
This question has an accepted answers - jump to answer
Answers
The search plugin ($.fn.dataTable.ext.search.push) is an extension of search which is why it doesn't run when SSP is enabled. And even if it did it would only work against the rows displayed in the client. It wouldn't help with filtering the server data. Seems like what you are doing is a good way to handle the server side filtering.
Kevin
Hi Kevin,
"And even if it did it would only work against the rows displayed in the client." That would be good enough and I don't expect more!
Roland
As designed the search plugin won't run when using SSP. @allan can comment on the feasibility of enabling search plugins in SSP mode. Maybe he has other ideas for you.
One option might be to programmatically add a hidden class to the rows currently displayed in the client. Datatables will still think they are being displayed but they won't be visible. I had a recent discussion in this thread about not using a hidden class. However, I did provide an example in my second post to show the Datatables behavior with hidden rows. Might give you some ideas.
Kevin
Yes, adding a hidden class may be an option, Kevin. But my target was to have a joint solution for serverSide and clientSide based on ext.search.push. I think that should be feasible. It would be up to @allan. But if it is not possible I'll keep what I have now for serverSide.
Hi,
As Kevin says, this is currently working as expected and it's intentional that it is this way. Your server-side processing "workaround" is the correct way to handle this with server-side processing enabled.
Kevin noted that if client-side filtering were to work when SSP is enabled, the client-side would only be able to filter the rows shown on the client-side. Say for example you were showing 10 rows out of a date set of 1 million. You apply a filter which results in just 5 rows from the data set matching, but none of them are already shown on the client-side. The client-side would show no records, even although we know there are 5 matching. Equally, if you apply a search condition which means there is one matching in the current display, and another 100 in the data set, only that one would be shown.
While that might be acceptable in the use case you have, I don't think that will be acceptable in most cases, and for that reason I don't plan to enable this I'm afraid.
The key thing with server-side processing enabled is to consider DataTables a simple display and event handler. The data processing must be handled by the server or a proxy.
Allan