Coldfusion refresh a field in a table output automatically - coldfusion

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?

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.

Related

Django with Vue, detect form validation error

I have a Django ModelForm which is displayed in the template by using using crispy forms. After the user fills out the fields and presses a Submit button, an email is sent at the backend using Django's core send_email.
The problem is that the call to send_email is synchronous, so the user has to wait for the next page to load (success/failure page) but in this time the user might press the Submit button again and this generates multiple POSTs, making multiple emails.
I want to use Vue.js to make the button inactive once the user presses it but only if it passes Django's form validation. Is there a way to detect this?
Add to your button :disabled="!readyToSend" where readyToSend can be returned by your data function or a computed propoerty.
Before submitting the form set this variable to false, afater receiving data from your API, reset it to true.
In the following example I've choosen to make readyToSend a computed proporty where it will return true if the form is valid and if the process is not waiting for the API response.
The complete Code Pen example is here
html file :
<html>
<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>example</title>
</head>
<body>
<div id="app">
<h2>{{ message }}</h2>
<form #submit.prevent>
<input type="text" v-model="dataToSend" placeholder="Something to send">
<button type="button" :disabled="!readyToSend" #click="send">Send</button>
</form>
</div>
</body>
</html>
javascript:
var vm = new Vue({
el: '#app',
data: function(){
return {
message: "please enter your message and click on send.",
dataToSend: "",
sentAndWaiting: false,
}
},
methods:{
send: async function(){
this.sentAndWaiting = true;
// Send Data Here
this.message = "sending....";
try{
let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
let jsonResponse = await response.json();
}
catch(e){
this.message = e.message;
}
// reponse received ... do Something with it
this.reponseReceived();
},
reponseReceived: function(){
this.sentAndWaiting = false;
this.message = "Ok. Got The response.";
}
},
computed:{
readyToSend: function(){
return this.dataToSend.length > 0 && !this.sentAndWaiting;
}
},
});
in my browser I had to test this by going to the developper tools and limit my internet connexion to the GPRS and disabling cache:
Screenshot DevTools

Create a map of Canada and USA with Datamaps in a single page

I am using Datamaps to create a map of Canada and USA. I saw the tutorial and/or examples in its website and I saw a "USA map only" example. And I did that:
<script>
var addUSA = new Datamap({
scope: 'usa',
element: document.getElementById('usa-map'),
geographyConfig: {
highlightOnHover: false,
borderColor: '#006298',
borderWidth: 0.8,
popupTemplate: function(geography, data) {
return "<div class='hoverinfo'><strong>" + data.info + "</strong></div>";
}
},
dataUrl: 'data.json',
dataType: 'json',
data: {},
fills: {
defaultFill: '#FFFFFF'
}
});
addUSA.labels();
</script>
So I assume that you can also create a "Canada map only". But the problem is, I don't know how to combine two countries.
I aim for labels, the hover-info and json that's why I'm using Datamaps.
So I've found this URL entitled Custom Map Data in Datamaps by Mark DiMarco and I used and tried copying what he had done. On that link, he created a map of Afghanistan which was not included in his main examples on Datamaps website. But instead of one country, we will combine two countries custom map using Datamaps. This is an experiment I've made but I hope this will be the answer to your problem
First, he created a custom topo json for Afghanistan. He published a tutorial on how to create custom map data but I think I don't have an access 'cause I'm getting 404 or he took it down. Going back, the code he used for that custom topo json can also be found in his other works located at "More Versions" link in Datamaps website. You just need to look for the country/ies you need to make a custom topo json. On your end, look for datamaps.afg.js and datamaps.usa.js; and get the json.
I only have 1 reputation and I am limit with two URLs. Just visit this GitHub site where I put those two custom topo json for Canada and USA.
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Canada and USA</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://rawgithub.com/markmarkoh/datamaps/master/dist/datamaps.none.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<!-- CANADA -->
<h1>CANADA</h1>
<div id="canada"></div>
<!-- USA -->
<h1>USA</h1>
<div id="usa"></div>
</body>
</html>
CSS
#canada {
border: 1px solid #000000;
height: 450px;
width: 400px;
}
#usa {
border: 2px solid #EDA552;
height: 400px;
width: 500px;
}
JQUERY
$(function() {
var canadaMap = new Datamap({
element: document.getElementById('canada'),
geographyConfig: {
dataUrl: 'canada.topo.json'
},
scope: 'canada',
fills: {
defaultFill: '#bada55'
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([-95, 71])
.scale(200)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});
var USAmap = new Datamap({
element: document.getElementById('usa'),
geographyConfig: {
dataUrl: 'usa.topo.json'
},
scope: 'usa',
fills: {
defaultFill: '#bada55'
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([-120, 54])
.scale(250)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});
});
Working code here => JS FIDDLE

Django Using Query and to_json to plot Google Graphs

I want to plot a Google Graph to visualize the results of a query.
Can anyone please help me ? I have included my code below. Thanks
models.py
class InventoriesApplication(models.Model):
ROADMAPS = (
('R', 'Retire'),
('SU', 'Sustain'),
('ST', 'Strategic')
)
app_name = models.CharField(max_length=45)
roadmap = models.CharField(max_length=2, choices=ROADMAPS, null = True)
views.py
import json
I used the following code to serialize my query:
def render_chart(request):
total= InventoriesApplication.objects.values("roadmap").annotate(total=Count('id'))
return HttpResponse(json.dumps(list(total), cls=DjangoJSONEncoder),content_type='charts.html')
and now I have the following array:
charts.html
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create the data table.
var data = google.visualization.arrayToDataTable({{ total }});
// Set chart options
var options = {'title':'Roadmaps'};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
...

Google Column Chart blank page

I am working on this project which I need to make a Google Chart (column chart) to make the data in my database visualize. I checked the IP and the database (the data comes from a database), everything works fine. But when I try to see the output on my computer, the page is blank. I thought the problem comes from google.load, and I made it like this below. I still get blank page. Please help me get this through. Thanks!
//
google.load('visualization', '1.0', {packages:['corechart'], callback: drawChart});
//
Here is the whole page.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><html>
<head>
<title>R1 Google Chart</title>
<!-- Load jQuery -->
<script language="javascript" type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js">
</script>
<!--Load the Ajax API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the column chart package.
// Set a callback to run when the Google Visualization API is loaded.
google.load('visualization', '1.0', {packages:['corechart'], callback: drawChart});
function drawChart() {
var jsonData = $.ajax({
url: "chart.php",
dataType: "json",
async: false
}).responseText;
var obj = jQuery.parseJSON(jsonData);
var data = google.visualization.arrayToDataTable(obj);
var options = {
title: 'Solar Panel Data',
width: 800,
height: 600,
hAxis: {title: 'time', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--this is the div that will hold the column chart-->
<div id="chart_div" style="width: 900px; height: 500px;">
</div>
</body>
</html>
PHP page
<?php
$con=mysql_connect("131.xxx.xxx.xx","xx","xxxx") or die("Failed to connect with database!!!!");
mysql_select_db("r1array", $con);
/** This example will display a column chart. If you need other charts such as a Bar chart, you will need to modify the code a little
to make it work with bar chart and other charts **/
$sth = mysql_query("SELECT UNIX_TIMESTAMP(TimeStamp), Pac FROM SolarData");
/*
---------------------------
example data: Table (Chart)
--------------------------
TimeStamp Pac
2013-08-16 06:45:01 0
2013-08-16 06:50:01 0
2013-08-16 06:55:01 12
2013-08-16 07:00:00 39
2013-08-16 07:05:01 64
2013-08-16 07:10:00 84
*/
$rows = array();
//flag is not needed
$flag = true;
$table = array();
$table['cols'] = array(
// Labels for your chart, these represent the column titles
array('label' => 'TimeStamp', 'type' => 'TIMESTAMP DEFAULT NOW()'),
array('label' => 'Pac', 'type' => 'INT')
);
$rows = array();
while($r = mysql_fetch_assoc($sth)) {
$temp = array();
//
$temp[] = array('v' => (string) $r['TimeStamp']);
// Values of each slice
$temp[] = array('v' => (int) $r['Pac']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
echo $jsonTable;
mysql_close($db);
?>
It seems that prepare data in wrong way in your php file. With your html file and following php file which fake your data I got column chart.
<?php
/*
---------------------------
example data: Table (Chart)
--------------------------
TimeStamp Pac
2013-08-16 06:45:01 0
2013-08-16 06:50:01 0
2013-08-16 06:55:01 12
2013-08-16 07:00:00 39
2013-08-16 07:05:01 64
2013-08-16 07:10:00 84
*/
$table = array();
$table[0] = array('TimeStamp', 'Pac');
$table[1] = array('2013-08-16 06:45:01', 0);
$table[2] = array('2013-08-16 06:50:01', 0);
$table[3] = array('2013-08-16 06:55:01', 12);
$table[4] = array('2013-08-16 07:00:00', 39);
$table[5] = array('2013-08-16 07:05:01', 64);
$table[6] = array('2013-08-16 07:10:00', 84);
$jsonTable = json_encode($table);
echo $jsonTable;
?>
There is comment in your php file This example will display a pie chart.... Which chart do you want to create?
Off the bat, I can see a problem here:
$table['cols'] = array(
// Labels for your chart, these represent the column titles
array('label' => 'TimeStamp', 'type' => 'TIMESTAMP DEFAULT NOW()'),
array('label' => 'Pac', 'type' => 'INT')
);
as 'TIMESTAMP DEFAULT NOW()' and 'INT' are not valid data types for a DataTable. If you want to create Date objects from your timestamps, you need to use the 'date' or 'datetime' data type, and format your timestamps as strings with the format 'Date(year, month, day, hour, minute, second, millisecond)', where month is zero-indexed (so January is 0 not 1). The 'INT' type should be 'number'.
Update your code with these fixes. If your chart still doesn't work, view chart.php in a browser - you should see a JSON string output of your data (if not, there is a problem in your PHP that you will have to debug) - and update your post with this JSON string.

Adding legend to Google chart

I am trying to add the column headings to the legend in this line graph, they should be the first row within the data table. The graph works fine if I remove the headings, however when I try load it with the headings I am getting nothing. Below is the output of the code that creates the input table it looks correct based on the google api example. Thanks
['Date','Species A', 'Species B'],['2013-08-27',3,1], ['2013-09-17',4,1], ['2013-08-23',1,1], ['2013-08-10',2,8]
The relevant bits of code
$result = mysqli_query($con,"SELECT * FROM Species");
while($row1 = mysqli_fetch_array($result))
{
$data1[]= "['" . $row1['Date'] . "'," . $row1['SpeciesA'] . "," . $row1['SpeciesB'] . "]";
}
$headings = "['Date','Species A', 'Species B'],";
$headingdata = $headings . implode(",\n",$data1);
echo $headingdata;
?>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart()
{
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'Species A');
data.addColumn('number', 'Species B');
data.addRows([
<?php echo $headingdata;?>
]);
If you are creating the DataTable like that, you don't want to include the $headings data in the data you are passing to the DataTable's #addRows method. Those should only be included if you are using the arrayToDataTable constructor.
Most of the charts will include the column labels as the series labels in the legend by default.
If you use the solution I posted in your other question, you shouldn't have any problems with this.