0

I have a table that outputs a bunch of records and has a status field that shows if the record has processed or not. I would like to auto refresh that one when the DB value changes from 0 to 1. I would rather not refresh the whole table or page, but just that one field.

Any thoughts on how to accomplish this?

spacerobot
  • 265
  • 1
  • 5
  • 23

1 Answers1

0

I'm sharing a working example solution that makes repeated AJAX jQuery calls to a simple CFML template. That CFML template returns a JSON object with data that is used to update the html table with jQuery. Here are the steps:

1. Step: Create a cfml file myTable.cfm that outputs a table with a cfml query data and binding each <tr> dom element with an identifier attribute to use as an dom element selector (e.g. <tr id=""dataID_#fruitsQuery.id#"">). This way you can manipulate/change the tables dom elements easier by accessing each table row and its children <td> with Javascript or Jquery. Please note my comments in the code:

myTable.cfm:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>myTable</title>
<!-- embed Bulma -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css">

</head>
<body>
<cfscript>
        // create a query and populate with random data
        fruitsQuery = queryNew( 
            "id, fruit , price" , "numeric, varchar , numeric" , 
            {
                id:     [1,2,3,4,5], 
                fruit:  [ "Bananas" , "Kiwis", "Apples", "Oranges", "Peaches" ], 
                price: [ 1.99 , 0.99 , 2.99, 3.99, 6.99 ] 
            }
        );
        
        
        /**
         * Ouptut the query data to a html table with bounded reference of the dom element to an ID
         */ 

        // output table head
        writeOutput("<table class=""table""><tr><thead><th>id</th><th>fruit</th><th>price</th></thead></tr><tbody>");
        
        
        // output rows with data
        cfloop( query="fruitsQuery" ){
            
            // open table row and set an identifier with the data id for easier dom selection 
            writeOutput( "<tr id=""dataID_#fruitsQuery.id#"">"  );
            
            writeOutput( "<td class=""id"">#encodeForHTML( id )#</td>"  );
            writeOutput( "<td class=""fruit"">#encodeForHTML( fruit )#</td>"  );
            writeOutput( "<td class=""price"" >#encodeForHTML( price )#</td>"  );

            
              writeOutput( "</tr>"  );  // close table row

        };
        
        writeOutput("</tbody></table>"); // close table
</cfscript>



<!-- embedded jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<script>
// set a variable with function expressions
myTableLibary={

  checkForUpdates: function(){

    console.log('call invoked');

    myTableLibary.myAjax( 'getLastUpdate.cfm' )
      .done( function( result ) {
          
          // set/reset all css for all table tds to default 
          $('td').css({'background-color':'','color':''})
          
          // use the identifier ID as a selector and populate its child
          // td.price with the data. Then set its css.
          $('tr#dataID_'+ result.id + ' td.price' )
              .css({'background-color':'blue','color':'white',})
              .html( result.price );

          // set css for td.fruit of the affected row
          $('tr#dataID_'+ result.id + ' td.fruit' )
          .css({'background-color':'yellow'})

      })
      .fail( function( e ) { 
          console.dir( e.responseText );
          alert('Ops! Something went wrong!');
      });
  },

  // function that returns an ajax object with Jquery (using deferred objects)
  myAjax: function( url ) {

    return $.ajax({
        url: url,
        type: 'GET',
        processData: false,
        contentType: false,
        success: function( contentdata ){
            return contentdata;
        },
        error: function( e  ){
            console.dir( e );
        }
        
    });
  }
}

// onload: call the checkForUpdate function (ajax) every 2 seconds
window.setInterval(function(){
  myTableLibary.checkForUpdates();
  }, 2000 ); 

</script>

</body>
</html>

2. Step: Create a cfml template named getLastUpdate.cfm to return the data as JSON. This set of data is returned to the calling template as the JSON object named result (see it in the myTable.cfm), which is further used to populate the table price cell. Here is the code:

getLastUpdate.cfm

<cfscript>
    // create the random data. I use bracket notation to make sure case is preserved in any CF engine version.
    result={};
    result["id"]=RandRange( 1, 5 );
    result["price"]=RandRange( 1, 22 ) & "." & randRange (0, 99) ;
    randomID=RandRange(0, 10 );
    
    // reset the stream, add content type and output the data as JSON
    cfcontent( reset = "true" );
    cfheader( name="content-type", value="application/json");
    writeoutput( serializeJSON( result ) );
</cfscript>

Step 3: Open the browser and call the myTable.cfm running witin your preferred cfml engine.

To see the action in your browsers background, watch the network tab in your preferred browsers dev tool and see all the available tabs with all informations.

AndreasRu
  • 1,053
  • 8
  • 14