Dynamically creating the table from ajax data - with reload

Dynamically creating the table from ajax data - with reload

Dan CarrollDan Carroll Posts: 12Questions: 3Answers: 0
edited November 2018 in Free community support

First let me say that Datatables remains one of the most amazing pieces of software I've ever used. I come back to it time and time again for each new data representing project.

That said, I am not sure how the next one might work...

I'd like to create a data table using an array of objects as the source.
But I'd like to know if it's possible to have the column numbers (and headings) be determined by the ajax data..

Consider a gymnastics comp. Looking at a competitors score sheet you might see for a routing the following scores:

Apparatus    Judge 1    Judge 2     Judge 3
Beam            7          6           7
Parallel Bars   6          6           5
Vault           8          7           7

I'd like to be able to set up an ajax reload using setInterval but I'm not sure what happens when the number of judges goes from 3 to 4... Is it possible to therefore scrap and recreate the whole table just via the AJax objects?

Replies

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Hi @Dan Carroll,

    Thank you for the kind words!

    As you say, with DataTables, the table width is defined at initialisation, so I think there's two ways you could go.

    1. Ajax outside of DataTables

    It might be easier to just have the Ajax loop running outside of DataTables, destroy any old tables and create anew in the success callback, reinitialising DataTables each time.

    1. Ajax within DataTables

    The only way I can see this working is to have the maximum number of columns in the table at initialisation, then in xhr rename columns and make columns visible based on the server response (ajax.json()).

    Hope that helps,

    Cheers,

    Colin

  • Dan CarrollDan Carroll Posts: 12Questions: 3Answers: 0
    edited November 2018

    Thanks Colin,... I've found a way that I think is suitable.
    The idea is that the webpage (php) checks the JSON data first for how many columns it needs and creates them.

    Then, the datatables on.error and on.processing events are used to check if the reloaded AJAX data is different to the dt table definition. If it is, window.location.reload() is called and the whole web page is reloaded.

    Probably on.xhr is a better place to test the data rather than both processing and error events, I have not checked that yet.

    For now, it just works with Ajax Array of Arrays, but if I moved the DT definition to the php code I could also define the columns on the fly as well so I could use Ajax Array of Objects.

    Anyway, for anyone wanting to see it. Here's the php code:

    <!DOCTYPE html>
    <html>
        <head>
            <link href="//datatables.net/download/build/nightly/jquery.dataTables.css" rel="stylesheet" type="text/css" />
            <link rel="stylesheet" href="a.css">
            <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
            <script src="//datatables.net/download/build/nightly/jquery.dataTables.js"></script>
            <script charset="utf-8" src="a.js"></script>
            <meta charset=utf-8 />
            <title>Test</title>
        </head>
        <body>
            <button id="reload">Reload</button>
            <div class="container">
                <table id="example" class="display" width="100%">
                <thead>
                    <tr>
                        <th>Apparatus</th>
                        <?php
                        // Ok, lets get the JSON object that DT will call later and have a look,..
    
                        include_once("data.php");
                        $scores = json_decode($json);
                        $cols = 0;
                        foreach($scores->data as $score) {
                            if ($cols < count($score)) {
                                $cols = count($score);
                            }
                        }
                        for ($i = 1 ; $i < $cols ; $i++ ) {
                            echo "<th>Judge " . $i . "</th>\n";
                        }
                    ?>
                    </tr>
                </thead>
                </table>
            </div>
        </body>
    </html>
    

    And here is the DT:

    $(document).ready( function () {
      $.fn.dataTable.ext.errMode = 'none';
    
      var table = $('#example').DataTable( {
        ajax: 'jsondata.php',
        processing: false
      } );
    
      function checkColumns (dtArr, jsData) {
          var maxCol = 0;
          jsData.forEach(function(element) {
                if (maxCol < element.length) {
                    console.log(element.length);
                    maxCol = element.length;
                }
          });
          if (maxCol != dtArr.length) {
              window.location.reload();
          }
      }
    
      $('#example').on( 'processing.dt', function ( e, settings, processing ) {
          checkColumns(settings.aoColumns, settings.json.data);
      } );
    
      $('#example').on( 'error.dt', function ( e, settings, techNote, message ) {
          checkColumns(settings.aoColumns, settings.json.data);
      } );
    
      $('#reload').click( function () {
        table.ajax.reload();
      } );
    } );
    
This discussion has been closed.