Pagination broken after jquery onchange kicks in

Pagination broken after jquery onchange kicks in

ibrahim2002ibrahim2002 Posts: 2Questions: 1Answers: 0

I am creating a mini version of IMDB for a uni assignment and need to utilise all 3 of JSON (default), XML and a custom text format. I have a dropdown in the top right as pictured below.

Whenever that value changes I have a jquery function(?) that writes the new value to local storage and re-triggers the ajax get request so the data can be loaded with the chosen format. I have written it to local storage because I thought it would be nice to keep the selected format if the user was to refresh the page rather than reset to the default. However, once a format has been changed once for a session the pagination is broken. It displays all of the results, the pagination number buttons do not work and changing the shown entries value or searching results in nothing being shown at all. When I create a new session via the incognito tab all is well until I change the format as I've mentioned.

I have included all of my JS below.

function loadNav() {
    $(document).ready(function() {
        $("#nav").load("navbar.html", function() {
            if ($('#formats').length && localStorage.getItem("formats")) {
                $('#formats').val(localStorage.getItem("formats")).change();
            }
        });
    });
}

function getFilms() {
    $(document).ready(function() {
        var format = $("#formats").val();
        var url = new URL("http://localhost:8080/FilmRestful/api");
        
        var searchTitle = $("#searchTitle").val();      
        var searchYear = $("#searchYear").val();        
        var searchDirector = $("#searchDirector").val();        
        var searchStars = $("#searchStars").val();      
        var searchReview = $("#searchReview").val();
        
        addQueryParam("title", searchTitle, url);
        addQueryParam("year", searchYear, url);
        addQueryParam("director", searchDirector, url);
        addQueryParam("stars", searchStars, url);
        addQueryParam("review", searchReview, url);
        
        $.get(url.toString(), function(data) {
            if (format == "xml") {
                displayXMLResults(data);
            } else if (format == "text") {
                displayTextResults(data); 
            } else {
                displayJSONResults(data); //selected format must be JSON (default)
            }
            
            $("#filmTable").DataTable();
        }, format);
    });
}

function displayXMLResults(results) {
    $("#filmTable tbody").empty();
    
    $(results).find('film').each(function() {
        $('<tr>').append(
            $('<td>').text($(this).find('title').text()),
            $('<td>').text($(this).find('year').text()),
            $('<td>').text($(this).find('director').text()),
            $('<td>').text($(this).find('stars').text()),
            $('<td>').text($(this).find('review').text()),
            $('</tr>')).appendTo('#filmTable tbody');
    });
}

function displayTextResults(results) {
    var films = results.split("@@@");
    
    $("#filmTable tbody").empty();
    
    $(films).each(function(index, film) {
        var filmData = film.split("|");
        $('<tr>').append(
            $('<td>').text(filmData[1]),
            $('<td>').text(filmData[2]),
            $('<td>').text(filmData[3]),
            $('<td>').text(filmData[4]),
            $('<td>').text(filmData[5]),
            $('</tr>')).appendTo('#filmTable tbody');
    });
}

function displayJSONResults(results) {
    $("#filmTable tbody").empty();
    
    $(results).each(function(index, film) {
        $('<tr>').append(
            $('<td>').text(film.title),
            $('<td>').text(film.year),
            $('<td>').text(film.director),
            $('<td>').text(film.stars),
            $('<td>').text(film.review),
            $('</tr>')).appendTo('#filmTable tbody');
    });
}

function addQueryParam(param, value, url) {
    if (value !== undefined) {
        url.searchParams.append(param, value);
    }
}

$("#formats").on('change', function() {    
    localStorage.setItem("formats", $(this).val());
    getFilms();
});

If I'm missing anything in this question please let me know and I'll try to add it as soon as possible. thanks

This question has an accepted answers - jump to answer

Answers

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

    Have a look at this FAQ which effectively addresses this issue.

    In short, you are changing the HTML, but not telling DataTables about that change.

    You have two options:

    1. Use clear() to empty the table and then rows.add() to add the new data, or
    2. Destroy the old table, and then create the new HTML and then initialise a new DataTable.

    For example, the displayTextResults function might be:

    function displayTextResults(results) {
      var table = $('#filmTable').DataTable();
    
      table.clear();
      table.rows.add(results).add();
      table.draw();
    }
    

    For the XML and JSON functions, create an array of arrays (the inner arrays being the row data, since that is how you have the DataTable configured).

    Allan

  • ibrahim2002ibrahim2002 Posts: 2Questions: 1Answers: 0

    Cheers Allan, shortly after posting this I found a solution via Stack Overflow where I clear and destroy the table before reinstating it which has done the trick!

Sign In or Register to comment.