jQuery Data Table Retain Filter and Search parameters

Viewed 963

I am working with datatable and want to retain dropdown filters and search parameters on page reload as seen in the screenshot below. However, I want the parameters to clear up if a window is closed or a user logs out of the application.

Here I have used "stateSave": true but it retains only for search input and that too is not consistent as sometimes even when a user logs back in, it shows old search keyword instead of resetting.

I am using the below code to preserve values but since Country and State dropdowns are not in datatable scope their values are not retained

// Restore state
var state = table.state.loaded();
if ( state ) {
    table.columns().eq( 0 ).each( function ( colIdx ) {
        var colSearch = state.columns['colIdx'].search;
        if ( colSearch.search ) {
            $('input', $('.filters th')[colIdx]).val( colSearch.search );
        }
    });
    table.draw();
}
2 Answers

Request: I want the parameters to clear up if a window is closed or a user logs out of the application.

By default, DataTables saves its state for 2 hours after the last change. It uses the browser's Local Storage for this. It sounds as if you want to use the browser's Session Storage instead.

To do this, you can explicitly set a negative value for the timeout period:

"stateDuration": -1

You can see more details here.

I am not sure how this relates to your application's specific logout process (if the process involves redirecting to a different page - and if that is sufficient to clear the Session Storage). The notes below may be relevant for this.


Issue: Country and State dropdowns are not in datatable scope their values are not retained

For this case - and maybe also for the logout scenario above - you would have to write your own JavaScript to handle saving and retrieving your country and state values.

With apologies if I am telling you what you already know - but there is a straightforward JavaScript API to handle this:

https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

You would need to decide on a naming strategy for your storage key, and a structure for the data you wish to store.

For your Country and State fields, you can use an onchange or onselect event to trigger updates to your storage (I assume you already have something implemented for these).

For initially loading these values when your table is first displayed, I expect you can add this to your existing "state restore" code.


It's always helpful to see what is happening behind the scenes. You can access Local and Session storage via your browser's dev tools (F12, usually). You can also see how DataTables stores its data, this way.


UPDATE

Based on comments from the original poster: I like the alternative (and probably much better!) approach of integrating external values into the DataTables saved data set.

When I use the approach mentioned in the comments below, I do not have a problem with saving and retrieving this data.

In case it helps, here is a full stand-alone example (except it does not have any "logout" functionality):

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

</head>

<body>

<div style="margin: 20px;">

    <select name="country" id="drop_down_country">
      <option value="Argentina">Argentina</option>
      <option value="Belgium">Belgium</option>
      <option value="Canada">Canada</option>
    </select>

    <br><br>

    <table id="example" class="display dataTable cell-border" style="width:100%">
    </table>

</div>

<script>

var dataSet = [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "office": "Tokyo"
    },
    {
      "id": "2",
      "name": "Garrett Winters",
      "position": "Accountant",
      "office": "London"
    },
    {
      "id": "3",
      "name": "Ashton Cox",
      "position": "Junior Technical Author",
      "office": "New York"
    }
];
 
$(document).ready(function() {

$( "#drop_down_country" ).change(function() {
  table.state.save();
});

var table = $('#example').DataTable( {
  data: dataSet,
  stateSave: true,
  stateSaveParams: function( settings, data ) { 
    data.searchCountry = $('#drop_down_country').val();
  }, 
  stateLoadParams: function( settings, data ) { 
    $('#drop_down_country').val(data.searchCountry); 
  },
  columns: [
    { title: "ID", data: "id" },
    { title: "Name", data: "name" },
    { title: "Office", data: "office" },
    { title: "Position", data: "position" }
  ]

} ); 


} );

</script>

</body>
</html>

In this example, I only have one drop-down (country), with a related event listener:

$( "#drop_down_country" ).change(function() {
  table.state.save();
});

Apart from that, I use the same stateSaveParams and stateLoadParams approach mentioned in the comments.

When I make changes to the country drop-down, I can see the changes being reflected in the local storage data.

When I close the browser tab, and then re-open it, my saved state is restored (including the selected country). The same happens if I navigate to another URL and then return to the original URL.

After exploring few options to resolve this issue, below code has been helpful to achieve what is required.

"stateSave": true

This will store state information such as pagination position, display length, filtering and sorting.

stateSaveParams: function( settings, data ){
    data.searchCountry = $('#drop_down_country').val()
    data.searchState = $('#drop_down_state').val()
},

stateLoadParams: function( settings, data ){
    $('#drop_down_country').val(data.searchCountry)
    $('#drop_down_state').val(data.searchState)
}

For logout, clear out the saved state

$('#reset_filter').click(function() {
        var testTable = $('#test-table').DataTable();
        testTable.state.clear();//Clear State
        testTable.destroy();//Destroy
        location.reload();
    });

It has been observed that the stateSaveParams and stateSave basically remembers the url and works with it to retains the applied filters

Use Case - User has typed in order #12345 in search input and the url is store.com/orders/index Now if user go to any other page and come back to same url it would retain the search parameters but if you try changing the url to say store.com/orders/ it will not retain the params.

After executing multiple test cases, it has been concluded that the stateSave API works when user applies the filters and url remains same

Related