Generating a table with javascript/json. No pagination and data resets when ordering or filtering.

Generating a table with javascript/json. No pagination and data resets when ordering or filtering.

eduardopatoeduardopato Posts: 6Questions: 2Answers: 0

Link to test case: https://aux5e.github.io/lista-de-magias.html
Debugger code (debug.datatables.net): unilaj
Error: When I updated DataTables, it started giving a "Uncaught TypeError: Cannot read properties of undefined (reading 'appendChild')" error. But the problem is still the same.
Description of problem: I build a site early this year using php and now I'm trying to migrate everything to Javascript (kind of a learning exercise)... I'm trying to create a table in a loop, like I did in php and rendering it at the the body of the table. But the table render all rows (361) without pagination, and every time I try to order clicking in any header or search anything all data is just gone. Any idea of what I'm doing that's breaking everything?

Initializing

$(document).ready(function () {
            $(document).ready(function () {
                $("#table-lista-de-magias").DataTable({
                    responsive: true,
                    language: {
                        url: "/data/dataTables.ptbr.json",
                    },
                    pageLength: 25,
                    paging: true,
                    scroller: true
                });
            });
        });

Html

<table id="table-lista-de-magias" class="display table table-bordered table-striped"
            style="font-size: 0.9em; margin-bottom: 35px">
            <thead>
                <tr>
                    <th scope="col" class="align-middle">Círculo</th>
                    <th scope="col" class="align-middle" style="max-width: 200px;">Nome</th>
                    <th scope="col" class="align-middle">Em Inglês</th>
                    <th scope="col" class="align-middle">Duração</th>
                    <th scope="col" class="align-middle">Alcance</th>
                    <th scope="col" class="align-middle" style="max-width: 60px;">Fonte</th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>

Javascript

<script>
        function loadIntoTable(url, table) {
            const tableBody = table.querySelector("tbody");
            
            $.getJSON(url, function (magias) {
                const magiasValues = Object.keys(magias.data);
                const siteUrl = 'https://aux5e.github.io';
                const magiasArray = Object.values(magias.data);
                const magiasLenght = Object.keys(magias.data).length;

                // Limpa o corpo da tabela
                // tableBody.innerHTML = "";

                // Popular o corpo da tabela
                var r = new Array(), j = -1;
                for (var row = 0; row < magiasLenght; row++) {
                    r[++j] = '<tr onclick=';
                    r[++j] = 'window.location="';
                    r[++j] = siteUrl;
                    r[++j] = '/magias.html?nome=';
                    r[++j] = magiasValues[row];
                    r[++j] = '"><th scope="row" class="text-center align-middle magiaCirculoCol">';
                    if (magiasArray[row].circulo == 0) {
                        r[++j] = '<span style="visibility:hidden;">0</span>Truque<span style="visibility:hidden;">0</span>';
                    }
                    else if (magiasArray[row].circulo > 0) {
                        r[++j] = magiasArray[row].circulo;
                        r[++j] = 'º';
                    }
                    r[++j] = '</th>';
                    r[++j] = '<td><div class="magiaNomeRow1">';
                    r[++j] = magiasArray[row].nome;
                    if (magiasArray[row].concentracao == true) {
                        r[++j] = '<span class="concentSpan"></span>';
                    }
                    r[++j] = '</div><div class="magiaNomeRow2">';
                    r[++j] = magiasArray[row].escola + ' • ' + magiasArray[row].componentes;
                    r[++j] = '</div></td>';
                    r[++j] = '<td class="align-middle magiaInglesCol">';
                    r[++j] = magiasArray[row].nome_ingles;
                    r[++j] = '</td><td class="align-middle magiaOutrasCol">';
                    r[++j] = magiasArray[row].duracao;
                    r[++j] = '</td><td class="align-middle magiaOutrasCol">'
                    r[++j] = magiasArray[row].alcance;
                    r[++j] = '</td><td class="text-center align-middle magiaOutrasCol">'
                    r[++j] = magiasArray[row].fonte;
                    r[++j] = '</td></tr>';
                }
                $(tableBody).html(r.join(''));
            });
        }

        loadIntoTable("/data/magias.json", document.getElementById("table-lista-de-magias"));
    </script>

Answers

  • colincolin Posts: 15,146Questions: 1Answers: 2,586

    I'm guessing it's a timing issue. I suspect you're creating the HTML for the table after you've initialised the DataTable - that means DataTables doesn't know anything about the data so each draw would just clear it down.

    I'd say confirm that loadIntoTable() is called before the table is initialised.

    Colin

  • eduardopatoeduardopato Posts: 6Questions: 2Answers: 0

    Thanks for answering! I was really creating the HTML after initializing DataTable. But now I moved DataTable() to the footer after loadIntoTable() but it still with the same problems :neutral:

  • colincolin Posts: 15,146Questions: 1Answers: 2,586

    Try moving the loadIntoTable() into the ready() function. If that doesn't help, we'd need to see it - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • eduardopatoeduardopato Posts: 6Questions: 2Answers: 0

    Hi, colin! Tried it inside both ready() functions and nothing (https://aux5e.github.io/lista-de-magias.html). I replicated my code in the live.database code (http://live.datatables.net/zabuvoyo/1/edit?html,js,output) and the issue is there.

  • eduardopatoeduardopato Posts: 6Questions: 2Answers: 0

    @colin I asked a friend and we found the problem! it seems $.getJSON is a asynchronous function (I had no idea) and was loading after DataTables. With a few async await the table is working flawless :smiley:

    Thank you very much for helping!

  • colincolin Posts: 15,146Questions: 1Answers: 2,586

    Perfect, glad all sorted, and thanks for the explanation - I'm sure that'll be helpful for others,

    Colin

Sign In or Register to comment.