Enabling History API with datatables

datatables, html5-history, javascript, jquery

Solution

you have only 2 options here:

- move pushState code out of drawCallback. There must be some other code that causes the datatables to draw when user enters something. put your pushState code there. This is the ideal solution

add a hack like this

$(document).ready(function () {
    var prevSearch;
    var saveState = true;
    var table = $('#releases').dataTable({
        "bJQueryUI":true,
        "sPaginationType":"full_numbers",
        "iDisplayLength":50,
        "oSearch":{"sSearch":'#{params[:query]}'},
        "fnDrawCallback":function (oSettings) {
            var curSearch = oSettings.oPreviousSearch.sSearch;
            if (!prevSearch) {
                prevSearch = curSearch;
            } else if (curSearch != prevSearch) {
                console.log("changed to: " + curSearch);
                if (saveState) {
                    history.pushState({query:curSearch}, "title", "releases?query=" + curSearch);
                }
                prevSearch = curSearch;
            }
        }
    });
    window.addEventListener("popstate", function (e) {
        if (e.state) {
            saveState = false;
            table.fnFilter(e.state.query);
            saveState = true;
        }
    });
});

Problem

I have a `dataTable` object on a page representing a list of releases I need to keep track of with the url `/releases` I want to add the following functionality - if `/releases?query=<query>`, the `dataTable` will initialized with the provided query - The `query` parameter is updated if the user changes the search term - The back and forward buttons in the browser go the appropriate query So far I am able to do the first 2, but when I listen for the `popstate` event, redrawing the table triggers a `pushState` which I can't figure out how to prevent. Here's my code so far: ``` $(document).ready(function(){ var prevSearch; var table = $('#releases').dataTable({ "bJQueryUI" : true, "sPaginationType" : "full_numbers", "iDisplayLength" : 50, "oSearch": {"sSearch": '#{params[:query]}'}, "fnDrawCallback": function(oSettings) { var curSearch = oSettings.oPreviousSearch.sSearch; if (!prevSearch) { prevSearch = curSearch; } else if (curSearch != prevSearch) { console.log("changed to: " + curSearch); history.pushState({query: curSearch}, "title", "releases?query=" + curSearch); prevSearch = curSearch; } } }); window.addEventListener("popstate", function(e) { if (e.state) { table.fnFilter(e.state.query); } }); }); ``` Note, I am using a `rails` backend and this is inlined javascript being served in the page.

Original source