Search code examples
jqueryhtmlcssjsontreetable

HTML jQuery treeTable auto refresh flickering


I'm trying to create a very simple HTML page where I want to display some data from a json file. I'm using jQuery treeTable, which is all up and running. However, JavaScript, html, css and all that stuff was pretty unknown to me until five days ago, so most of it is found doing research on Google and using w3school examples or brute forcing my code.

Before any start using massive amount of time on this please note that it is running as I want and thus do not really need to do more.

However there is a bit that's nagging me, and it's that when ever I auto refresh to pass (if there is any) new data into my table, it's flickering. I rebuilt the whole table and use persist to reload its current state.

I tried to use the method of drawing it in the background using the style display: none/inline and then flip it but somehow this didn't do anything to remove the flickering.

My html code is as follows:

<!DOCTYPE html>
<html>
  <head>
    <!-- 2 load the theme CSS file -->
    <script src="jquery/jquery-1.11.2.min.js"></script>
    <link href="jquery-treetable/css/jquery.treetable.css" rel="stylesheet" type="text/css" />
    <link href="jquery-treetable/css/jquery.treetable.theme.default.css" rel="stylesheet" />
    <script src="jquery-treetable/jquery.treetable.js"></script>    
    <script src="jquery-treetable/persist-min.js" type="text/javascript"></script>
    <script src="jquery-treetable/jquery.treetable-ajax-persist.js" type="text/javascript"></script>
    <meta http-equiv="refresh" content="5">
  </head>

  <body>
    <script type="text/javascript">
       <!-- // In case of no script support hide the javascript code from the browser 

       function isArray(myArray) {
         return myArray.constructor.toString().indexOf("Array") > -1;
       }

       function addNode(jsonData) {
         // Array handling here, no data need to be added
         var treeData = ''
         //console.log(jsonData)
         if ( isArray(jsonData) ) {
           if ( jsonData.length > 0 ) {
             $.each( jsonData, function( k, v ) {
               //console.log('key :' + k + ', value :' + v + ', length :' + v.length)
               treeData += addNode(v)
             });
           }
         }

         // Object handling here might contain data which needs to be presented  
         else {

           if ( jsonData.parentNodeId == "None" ) {
             treeData += '<tr data-tt-id="' + jsonData.nodeId + '">'
           } else {
             treeData += '<tr data-tt-id="' + jsonData.nodeId + '" data-tt-parent-id="' + jsonData.parentNodeId + '">'
           }

           switch(jsonData.nodeType) {
             case "fileLink":
               treeData += '<td></td>'
               treeData += '<td><span style="font-weight:bold"> log file: <a href="' + jsonData.data.comments + '">' + jsonData.text + '</a></span></td>'
               treeData += '<td></td>'
               treeData += '<td></td>'
               break
             default:
               if (parseInt(jsonData.data.status) > 25 ) {
                 treeData += '<td width="20px" align="center" class="status_'+ parseInt(jsonData.data.status) + '"></td>'
               } else {
                 treeData += '<td width="20px" align="center" class="status_default"></td>'
               }

               if ( jsonData.children.length > 0 ) {
                 treeData += '<td>' + jsonData.text + '(' + jsonData.children.length + ')</td>'
               } else {
                 treeData += '<td>' + jsonData.text + '</td>'
               }

               treeData += '<td>' + jsonData.data.type +'</td>'
               treeData += '<td>' + jsonData.data.comments +'</td>'
               treeData += '</tr>'
               if ( jsonData.nodeType == 'tst' ) {
                 treeData += addNode(jsonData.data.logFileNode)
               }

               treeData += addNode(jsonData.children)

           } // End switch(jsonData.nodeType)
         }
         return treeData
       }

       function buildTree(jsonData) {
         var baseTable = ''
         baseTable += '<caption>Test Suite test report</caption>'
           baseTable += '<thead>'
           baseTable += '<tr>'
           baseTable += '<th>status</th>'
           baseTable += '<th>Test tree</th>'
           baseTable += '<th>Type</th>'
         baseTable += '<th>comments</th>'
           baseTable += '</tr>'
           baseTable += '</thead>'
           baseTable += '<tbody>'
         baseTable += addNode(jsonData)
           baseTable += '</tbody>' 
           return baseTable
       }


       /* Ajax methode, more controle */
       $.ajax({
         url: 'testSuite.json',
         dataType: 'json',
         type: 'get',
         cache: false,
         success: function(data) {
           $.each( data, function( key, value ) {
             var treeData = buildTree(data)
             $("#reportDataTree").append(treeData)
             $("#reportDataTree").agikiTreeTable({expandable: true, column: 1, persist: true, persistStoreName: "treeTableData"});
          });
         }
       });

       // Highlight selected row
       $("#reportDataTree tbody").on("mousedown", "tr", function() {
         $(".selected").not(this).removeClass("selected");
         $(this).toggleClass("selected");
       });


       -->
    </script>


    <table id="reportDataTree">
    </table>

    <noscript>
      <h3>Requires JavaScript</h3>
    </noscript>  
  </body>
</html>

My code is pretty straight forward I think: I load the data from the json file, build my table by adding it all to a string and then .append the data to my table. After appending I load the treeTable feature with persist.

I could of course keep the treeTable information and only change what needs to be changed by comparing new vs. current; however this is too much work right now and would be something I'd do when I have time later.

So I'm asking is there a simple way I could improve my code, have I missed some clever functionality, etc.


Solution

  • I found a solution to my problem. Now my table is updating without flickering. I tried to redo the display: none/table thing and got it working. I remove the html page refresh and added a interval timer for the JavaScript which will load my getJsonData function. It will only refresh the table if the file is modified.

    <!DOCTYPE html>
    <html>
      <head>
        <!-- 2 load the theme CSS file -->
        <script src="jquery/jquery-1.11.2.min.js"></script>
        <link href="jquery-treetable/css/jquery.treetable.css" rel="stylesheet" type="text/css" />
        <link href="jquery-treetable/css/jquery.treetable.theme.default.css" rel="stylesheet" />
        <script src="jquery-treetable/jquery.treetable.js"></script>    
        <script src="jquery-treetable/persist-min.js" type="text/javascript"></script>
        <script src="jquery-treetable/jquery.treetable-ajax-persist.js" type="text/javascript"></script>
      </head>
    
      <body onload="getJsonData()">
        <div class="show"></div>
         <div class="hide"></div>
      </body>
    
      <script type="text/javascript">
         <!-- // In case of no script support hide the javascript code from the browser 
         setInterval(function () {getJsonData()}, 5000);
    
         function isArray(myArray) {
           return myArray.constructor.toString().indexOf("Array") > -1;
         }
    
         function addNode(jsonData) {
           // Array handling here, no data need to be added
           var treeData = ''
           //console.log(jsonData)
           if ( isArray(jsonData) ) {
             if ( jsonData.length > 0 ) {
               $.each( jsonData, function( k, v ) {
                 //console.log('key :' + k + ', value :' + v + ', length :' + v.length)
                 treeData += addNode(v)
               });
             }
           }
    
           // Object handling here might contain data which needs to be presented  
           else {
    
             if ( jsonData.parentNodeId == "None" ) {
               treeData += '<tr data-tt-id="' + jsonData.nodeId + '">'
             } else {
               treeData += '<tr data-tt-id="' + jsonData.nodeId + '" data-tt-parent-id="' + jsonData.parentNodeId + '">'
             }
    
             switch(jsonData.nodeType) {
               case "fileLink":
                 treeData += '<td></td>'
                 treeData += '<td><span style="font-weight:bold"> log file: <a href="file:///' + jsonData.data.comments + '">' + jsonData.text + '</a></span></td>'
                 treeData += '<td></td>'
                 treeData += '<td></td>'
                 break
               default:
                 if (parseInt(jsonData.data.status) > 25 ) {
                   treeData += '<td width="20px" align="center" class="status_'+ parseInt(jsonData.data.status) + '"></td>'
                 } else {
                   treeData += '<td width="20px" align="center" class="status_default"></td>'
                 }
    
                 if ( jsonData.children.length > 0 ) {
                   treeData += '<td>' + jsonData.text + '(' + jsonData.children.length + ')</td>'
                 } else {
                   treeData += '<td>' + jsonData.text + '</td>'
                 }
    
                 treeData += '<td>' + jsonData.data.type +'</td>'
                 treeData += '<td>' + jsonData.data.comments +'</td>'
                 treeData += '</tr>'
                 if ( jsonData.nodeType == 'tst' ) {
                   treeData += addNode(jsonData.data.logFileNode)
                 }
    
                 treeData += addNode(jsonData.children)
    
             } // End switch(jsonData.nodeType)
           }
           return treeData
         }
    
         function buildTree(jsonData) {
           var table = document.createElement("table")
           table.setAttribute("class", "hide");
           $(table).appendTo("div.hide");
           $(document.createElement("caption")).appendTo("table.hide");
           $("table.hide caption").append('Test Suite test report')
    
           $(document.createElement("thead")).appendTo("table.hide");
           var header = ''
             header += '<tr>'
             header += '<th>status</th>'
             header += '<th>Test tree</th>'
             header += '<th>Type</th>'
           header += '<th>comments</th>'
             header += '</tr>'
    
           $("table.hide thead").append(header)
    
           $(document.createElement("tbody")).appendTo("table.hide");
           $("table.hide tbody").append(addNode(jsonData)) 
         }
    
    
         /* Ajax methode, more controle */
         function getJsonData() {
           $.ajax({
             url: 'testSuite.json',
             dataType: 'json',
             type: 'get',
             cache: false,
             ifModified: true,
             success: function(data, status) {
               if (status == 'success') {
                 $.each( data, function( key, value ) {
                   var treeData = buildTree(data)
                   $(".hide, .show").toggleClass("hide show");
                   $('table.hide').treetable('destroy');
                   $('div.hide').empty();
                   $("table.show").agikiTreeTable({expandable: true, column: 1, persist: true, persistStoreName: "treeTableData"});
                 });
               }
             },
             error: function(xhr){
                $("div.show").empty();
                $("div.show").append(xhr.responseText);
             }
           });
         }       
         // Highlight selected row
         //$("div.show, div.hide").on("mousedown", "tr", function() {
         //  $(".selected").not(this).removeClass("selected");
         //  $(this).toggleClass("selected");
         //});
    
         -->
      </script>   
      <noscript>
        <h3>Requires JavaScript</h3>
      </noscript>  
    
    </html>
    

    The highlight feature at the end of the script have been commented out due to that it didn't save its state between updates and cause the selected line to disappear when ever the table was updated.