[SearchPanes, Select]: Custom search pane for selected rows

[SearchPanes, Select]: Custom search pane for selected rows

pgerundtpgerundt Posts: 90Questions: 13Answers: 2

Goal:
Create a custom search pane for filtering all (un)selected rows.

Test case:
http://live.datatables.net/rolakana/1/edit?js,console,output

Steps to reproduce:
Select the first row

Notes:
- We are using var rowIds = [] to store the ids of all selected rows (to prevent infinite loops due to search pane options being (un)selected when using cascadePanes: true
- We listen to the events select.dt and deselect.dt to add/remove the row id and to rebuild the search pane.
- During rebuild, the function for the search pane options is called 4 times (with correct information about the selected state)
- But after the rebuild, the function is called again two times and the selected state information is missing

So after selecting the first row, the console output is:

"SELECT EVENT: REBUILD PANE 0"
"ROW 0 IS SELECTED"
"ROW 0 IS SELECTED"
"ROW 0 IS SELECTED"
"ROW 0 IS SELECTED"
"SELECT EVENT: REBUILD DONE"
"ROW 0 IS NOT SELECTED"
"ROW 0 IS NOT SELECTED"

I think it`s a bug that the information about the row being selected is missing.

This question has accepted answers - jump to:

Answers

  • pgerundtpgerundt Posts: 90Questions: 13Answers: 2
    Answer ✓
  • pgerundtpgerundt Posts: 90Questions: 13Answers: 2

    Hi @allan and @colin,

    I was working again on that topic and suddenly a general question came up:
    Is SearchPanes capable of custom search panes
    (such as https://datatables.net/extensions/searchpanes/examples/customFiltering/customPane.html)
    when running in serverSide: true mode?

    Even if the options[x].value function works and shows the filter options with count and total,
    will selecting a filter option make SearchPanes filter the rows returned by the Ajax call (data) ?

    My guess is "no", because the returned searchPanes.options would also have to be altered (count and total).

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Answer ✓

    Hi Pascal,

    You are absolutely correct. A custom pane would require hooks for logic and conditions on the server-side which I'm afraid the libraries do not provide at this time.

    Allan

  • pgerundtpgerundt Posts: 90Questions: 13Answers: 2

    Hi @allan,

    thanks for the quick answer.

    For everyone struggeling to build a filter for selected rows in serverSide: true mode, here is a working solution:

    1) Add an <input id="selectedIds" type="hidden" value="[ids from database as JSON array]"> to your website storing the ids of the selected rows
    2) init DataTables with selected ids added to the data option:

    ajax: {
      url: '[your serverside url]',
      data: function(data) {
        data = jQuery.extend(data, {selectedIds: JSON.parse(jQuery('input#selectedIds').val())})
      }
    }
    

    3) modify your serverside script to use the request variable selectedIds for filtering returned rows and search panes options
    4) add an select/deselect event handler to add/remove ids from the hidden input:

    tableElement.on('select.dt deselect.dt', function(event, dt, type, indexes) {
      var DataTableApi = tableElement.dataTable().api();
      var data = DataTableApi.row(indexes).data();
      var ids = JSON.parse(jQuery('input#selectedIds').val());
      if(data) {
        switch(event.type) {
          case 'select':
            if(ids.indexOf(data['DT_RowId']) === -1) {
              ids.push(data['DT_RowId']);
              jQuery('input#selectedIds').val(JSON.stringify(ids));
              DataTableApi.ajax.reload();
            }
            break;
          case 'deselect':
            if(ids.indexOf(data['DT_RowId']) !== -1) {
              ids.splice(ids.indexOf(data['DT_RowId']), 1);
              jQuery('input#selectedIds').val(JSON.stringify(ids));
              DataTableApi.ajax.reload();
            }
            break;
        }
      }
      event.stopPropagation();
    });
    

    5) add an draw event handler to prevent selected rows to be unselected after using the search panes filter:

    tableElement.on('draw.dt', function(event) {
      var DataTableApi = tableElement.dataTable().api();
      var ids = JSON.parse(jQuery('input#selectedIds').val());
      DataTableApi.rows().every(function() {
        var data = this.data();
        if(data) {
          if(jQuery.inArray(data['id'], ids) > -1) {
            this.select();
          }
        }
      });
      event.stopPropagation();
    });
    

    Hope that helps!
    Pascal

Sign In or Register to comment.