Search callback to add more rows to the search result

Search callback to add more rows to the search result

pelangipelangi Posts: 8Questions: 1Answers: 0

Hi all, I am looking at combining DataTables search with another (separate) search and hoping that before I call draw() I can insert more rows to the search results if necessary. Is it possible?

So for example I have a table with 1000 rows, and upon calling table.search('myquery') I know that I will get, for example, 16 rows and I will do another search (using another tool) and I get 4 relevant rows that are not already in the search result to add. So that when I call draw() I will end up with 20 rows.

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583
    Answer ✓

    Hi @pelangi ,

    You would need a custom search plugin to do that - Kevin's final comment on this thread gives a good demonstration on how to do that.

    Cheers,

    Colin

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Thanks @colin. I am assuming you are talking about $.fn.dataTable.ext.search.push. That gives me something to work with. I will post an update here when I could (not) get it working.

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    Hi @pelangi ,

    Yep, that's it.

    Cheers,

    Colin

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Hi @colin I can confirm that I can use it to achieve what I need to do. However it seems that the only way is for me to do totally custom search and I can't leverage the default DataTables search. By that I mean that I can let DataTables to do search first and then either add or remove rows from table.search('keyword').data().

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited September 2019

    So for example I have a table with 1000 rows, and upon calling table.search('myquery') I know that I will get, for example, 16 rows and I will do another search (using another tool) and I get 4 relevant rows that are not already in the search result to add. So that when I call draw() I will end up with 20 rows.

    The best thing to do is to build a simple test case showing your data and what you want to do.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    If you can't do that then please provide more details of what you are trying to do:

    When using table.search('myquery') you get 16 rows.

    Makes sense.

    I will do another search (using another tool) and I get 4 relevant rows that are not already in the search result to add.

    Where is this data? I assume its not in the Datatable and you want to use something like `-api rows.add() to add the data to the Datatable.

    So that when I call draw() I will end up with 20 rows.

    I suspect the problem is this doesn't happen because the rows you add are filtered due to the search term??

    If the above is basically correct then I would agree that you can't use the search() API. I would still look at using the search plugin. My suggestion would be to add a field to all you rows that is a flag indicating if its Datatables data or data added by the other search mechanism. This doesn't need to be a column but just part of each row. Depending on your requirements you may need to maintain this field to change the value or remove previously added rows.

    All you need to do is use draw() to execute the search plugin. You may need to provide your own search input and get the input value in your plugin function. In the function you will return true if the data in the row matches the search input or has the "added" flag set. Otherwise return false.

    This example might help:
    http://live.datatables.net/wenaxuti/1/edit

    Kevin

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Hi Kevin, thanks so much for your detailed explanation.

    If you can't do that then please provide more details of what you are trying to do:

    Sorry it is easier for me to explain it rather than to write the test case and I can't really use the real data for test case.

    So I have about 1,500 PDF documents that have been tagged in certain way (metadata) so that I can present that in DataTables with the following column, for example: Name, Category, Description, Link (URL).

    When I do search, I can use the built-in DataTables search functionality table.search(keyword) which will do search within the Name, Category and Description columns. However, obviously DataTables doesn't know anything about the content of the PDF and can't search within the PDF files. That's where I utilise our search application that search the content of PDF and then with all the results returned from that 'external' search I add that to the DataTables search results.

    Ideally what I would like to happen is I have table.search(keyword).data() array and then I merge it with the array I got from external search. By merge I meant that if the PDF is already in the DataTables search result, I will skip it, otherwise I will add it to the DataTables search result.

    Fortunately I have been able to do this using your example of search plugins. My last post was because I wonder if I can actually still using DataTables inbuilt search and then just do the merging instead of re-writing DataTables search.

    Thanks again.

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736

    I don't believe there is a way to merge your external search into the Datatables search.

    Without knowing the size of the PDF's this may not be feasible but one option may be to return the searchable content of the PDF in the table data. You don't have to display it but it could be there for Datatables to search. You could use orthogonal data and display the URL and have the PDF content in the filter type.

    Or you could have the PDF data in a hidden column which is searchable.

    Another, probably less elegant, solution would be to use server side processing and let the server script perform the data and PDF search and return the appropriate rows for the page.
    https://datatables.net/manual/server-side

    Kevin

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Yeah I have considered server-side but in my case unfortunately it will be slower.

    I have considered to load the PDF content as well (assuming I found a way for that) but the data will be too big.

    Now, I just realised that the search plugin will also kill column filtering by drop down. So in my table, I created a dynamic drop down list to on initComplete for users to filter by Category ... but apparently this functionality also uses search() so my search plugin needs to cater for that as well.

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited September 2019

    I have found, maybe incorrectly, that the search plugins execute after the builtin (search(), column().search() and global search input) have executed. If I want to do something that just uses the search plugin I simply use draw(). So the plugin will filter out any remaining rows after the Datatbles searches are run. Make sense.

    That's why I suggested using your own inputs and just draw(). Then you have more control over the result. But it sounds like you are getting it and on the right track.

    Kevin

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Hi Kevin, yeah I got it all working ... but I don't mind to pursue this discussion.

    I think I can confirm that the search plugin will be executed after search() and column().search(). This is exactly what I saw:

    Let's say I do column search (by way of drop down list) on second column and it will return 20 rows. If I just use table.draw() my search plugin will be iterated as many as total rows there are. But if I do table.column(1).search(keyword).draw() then my search plugin will be iterated only as many as the returned rows from the built-in search, in this case 20 times.

    Thank's for pointing that out ... it is useful to know.

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Uhm ... how do I access the search result from my search plugin when I call table.search(keyword).draw()? Doesn't call table.search(keyword).data() will do the search once again?

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited September 2019

    The search plugin will run once for each row being displayed and you have access to that row data via searchData. You can use console.log statement inside your plugin function to see this. Why would you need to get the search result data inside the plugin?

    To answer your question you would use the rows() API with the selector-modifier of search:'applied' to get the row data of the rows displayed, for example: table.rows( { search:'applied' } ).data();. Using table.search(keyword).data() would execute the search again and inside the plugin would probably cause an infinite loop. And the data() would probably return all the rows not the searched rows.

    Kevin

  • pelangipelangi Posts: 8Questions: 1Answers: 0

    Why would you need to get the search result data inside the plugin?

    Because my understanding so far if we do table.search(keyword).draw() instead of table.draw() then the search plugin will just process the search result returned by the built-in search. I would imagine that we will be able to remove some results by returning false in the search plugin but can't add more rows to the search result? Am I making sense?

    So this is back to my original idea and just for clarity with Colin's and your help I have been able to do what I need to do ... so this discussion just for my better understanding on the built-in search :smile:

    What I imagined I would do it was: do table.search(keyword) without drawing the table, grab the search results (let's call it searchData) and then iterate another array (which is the search result from external search), if an element is already in the searchData, skip to the next one, otherwise add it to searchData. Then call draw().

    I know that's probably not how DataTables works.

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736

    Doesn't call table.search(keyword).data() will do the search once again?

    My comment about asking why is this statement. Thought you wanted to do this inside the search plugin function.

    I know that's probably not how DataTables works.

    Yep, I don't think that would be possible with the way Datatables operates.

    Glad you are able to do what you need.

    Kevin

This discussion has been closed.