Am trying to generate multiple line charts at one go using the code below. However, it isn't working. What would be the best way to generate graphs using a for/while or any other looping mechanism? I have many charts to generate.
var db_query = Array();
db_query[1] = <?php echo json_encode($db_query_1) ?>;
db_query[2] = <?php echo json_encode($db_query_2) ?>;
var chartConfig1 = clone(chartConfigLineOne);
var chartConfig2 = clone(chartConfigLineOne);
for(var i=1, len=2; i <= len; i++) {
/* chart initialization */
var chart_num = "chart" + i.toString();
var plot_num = "plot" + i.toString();
var chartConfig_num = "chartConfig" + i.toString();
/*alert(chart_num);
alert(plot_num);
alert(chartConfig_num);*/
chart_num = AmCharts.makeChart(plot_num, chartConfig_num);
$.ajax({
type: 'POST',
url: "query_db.php",
data: {'db_que': db_query[i]},
dataType: 'json',
context: document.body,
global: false,
async: true,
success: function(data) {
//alert(data);
chart_num.dataProvider = data;
chart_num.validateNow();
}
});
}
UPDATED CODE
<script type="text/javascript">
var chartNameList = ['chart1','chart2'];
var divId = ['plot1','plot2'];
var configList = ['chartConfig1','chartConfig2'];
var dbQuery = [];
var chartConfig1 = clone(chartConfigLineOne);
var chartConfig2 = clone(chartConfigLineOne);
dbQuery[0] = <?php echo json_encode($db_query_1) ?>;
dbQuery[1] = <?php echo json_encode($db_query_2) ?>;
/* chart initialization */
for(var i =0; i < 2; i += 1) {
//window["chart"+i] = createChartObj(divId[i],configList[i]);
execDbQuery(divId[i],configList[i],dbQuery[i],chartNameList[i]);
}
</script>
/**
* Execute of DB query
*/
function execDbQuery(divId, configObj, dbQuery, chartObj) {
chartObj = AmCharts.makeChart(divId, configObj);
$.ajax({
type: 'POST',
url: "query_db.php",
data: {'db_que': dbQuery},
dataType: 'json',
context: document.body,
global: false,
async: true,
success: function(data) {
//alert(data);
chartObj.dataProvider = data;
chartObj.validateNow();
}
});
}
As many comments correctly pointed out, you should probably start with rethinking your approach to data loading. Passing SQL queries in from client-side is asking for trouble. Will you be able to properly sanitize your queries to guard against malicious code? You can't be sure.
It's far more reasonable to move your DB access layer to PHP. You can pass in parameters needed for PHP script running on server to identify what needs to be loaded from DB and construct and execute actual SQL queries.
I.e.: query_db.php?chart_id=5
It would be up for PHP script to determine what to do. Given that you're currently using PHP to format those SQL queries, I can hardly image it can be a problem.
This brings us to another issue. Your current setup will run multiple AJAX requests simultaneously. While it's probably OK in the example you posted which has two charts, it can bog down the performance if you you have, say, 30 charts you need to load data for.
The solution would be to daisy-chain the loading. Do not start loading of another chart, until the previous one finishes loading. I.e.:
var charts = [ {
"name": "chart1",
"div": "plot1",
"config": clone( chartConfigLineOne ),
"query": <? php echo json_encode( $db_query_1 ) ?>
}, {
"name": "chart2",
"div": "plot2",
"config": clone( chartConfigLineOne ),
"query": <? php echo json_encode( $db_query_2 ) ?>
} ];
// do whatever modifications to each chart's config you need here
// ...
// function that creates the chart
function processNextChart() {
if ( charts.length ) {
var chart = charts.shift();
$.ajax( {
type: 'POST',
url: "query_db.php",
data: {
'db_que': chart.query
},
dataType: 'json',
context: document.body,
global: false,
async: true,
success: function( data ) {
chart.config.dataProvider = data;
chartObj = AmCharts.makeChart( chart.div, chart.config );
setTimeout( processNextChart, 100 );
}
} );
}
}
// process first chart
processNextChart();
Please note how I simplified your whole chart array with a single array that holds all applicable data.
Please note, that the above code is not live-tested and is meant as a guiding point for your own implementation.
Do not make ajax calls inside the for loop. It's a burden on server. The less calls you make, the more responsive is your ui. So, the better way to implement what you want is to get all data for all graphs in one ajax call and on success to iterate through the data building your graphs with AmCharts.makeChart.
Related
In my cakephp application I am trying to create a commenting functionality. So I use an ajax request to get the comments and then clone an html template and append it to the page:
//load comments
$(document).ready(function(){
$.ajax({
type: 'POST',
url: '/app/tasks/getComments',
datatype: 'json',
beforeSend: function (xhr) { // Add this line
xhr.setRequestHeader('X-CSRF-Token', $('[name="_csrfToken"]').val());
},
data: {
task_id : "<?php echo $task->id; ?>"
},
success: function( data )
{
for (var i=0; i < data.length; i++)
{
//Clone the template
var item = $(template).clone();
document.cookie = 'photos['+i+']='+data[i].user.photo;
document.cookie = 'names['+i+']='+data[i].user.username;
//Find the element
$(item).find('#comment_photo').html('<?php if(isset($_COOKIE["photos[$num]"])) {echo $this->Html->image($_COOKIE["photos[$num]"], ["class" => "avatar avatar-online", "alt" => $currentUser->username]); } ?>');
$(item).find('#comment_username').html('<?php if(isset($_COOKIE["names[$num]"])) { echo $_COOKIE["names[$num]"]; }?>');
$(item).find('#comment_time').html(moment(data[i].created_date, 'DD-MM-YYYY hh:mm:ss').format('MMMM Do YYYY, h:mm:ss a'));
$(item).find('#comment_text').html(data[i].comment);
$(item).find('#comment_id').html(data[i].id);
//Append to the source
$('#target').append(item);
}
}
});
});
In order to access the returned results in php I store them in cookie arrays (photos[], names[]). How I can set and update the value of $num in order to iterate the arrays in every html code append? Is it possible to achieve what I want with this approach? Or I need a complete new one?
The solution was much simpler than I actually thought... I did it with JQuery like this:
.......
$(item).find('#comment_photo').prepend("<img src='/app/img/' class='avatar avatar-online'/>");
$(item).find('.avatar.avatar-online').prop('src', '/app/img/'+data[i].user.photo);
......
I am building my best attempt at a twitter clone and have run into a bit of a problem. I want to be able to click on a post and, without a page refresh, display that post in the overlay of the page (as you would on a twitter feed to look at replies, etc.).
In script.js, I check for a click and try to change the url.
$('body').on("click", ".chirp", function(){
var uid = $_GET['id'];
var pid = $(this).attr("id");
var pidSplit = pid.split("chirp");
var messageID = pidSplit[1];
var obj = {foo: "status"};
$('.chirpOverlay').addClass("active");
window.history.pushState(obj, "Status", "profile.php?id="+uid+"&status="+pid);
});
The javascript works as intended...but as I will soon find out, the victory is short-lived.
In profile.php, I attempt to GET the status id from the URL parameter.
<?php
$status_id = $_GET['status'];
$sql = $db->query("SELECT * FROM chirps WHERE id='$status_id'");
if (mysqli_num_rows($sql) > 0) {
$c = $sql->fetch_object();
}
?>
This doesn't work because, as I've learned, using 'window.history.pushState' only changes the url- but doesn't load the page. Thus the $_GET statement fails. I need a way to get the id of the post I click on into profile.php without a page refresh. Even if it means taking a different approach (instead of using a URL parameter).
PS: I tried to do an XMLHttpRequest as well- to no avail. :(
Thanks in advance!
$('body').on("click", ".chirp", function(){
var uid = $_GET['id'];
var pid = $(this).attr("id");
var pidSplit = pid.split("chirp");
var messageID = pidSplit[1];
var obj = {foo: "status"};
$('.chirpOverlay').addClass("active");
$.ajax({
url: "profile.php?id="+uid+"&status="+pid,
type: "GET",
data: obj,
dataType: "html",
success: function(data){
console.log(data);
}
});
});
You need to just get something up and going that works and then you can add more to it as you figure things out. This should give you a good starting place.
Here are your two files. Make sure they are both in the same directory.
You will need to make sure you have a jquery version loaded. Put this on whatever page you are calling the script.js from.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
script.js
$(document).ready(function(){
$('body').click(function(){
var id; //define your id.
var pid; //define your pid.
var datastring = 'id=' + uid + '&status=' + pid;
console.log(datastring);
$.ajax({
url: 'profile.php',
type: 'POST',
cache: false,
data: datastring,
dataType: 'json',
success: function(data){
console.log('Made it to the success function: ' + data);
if (data) {
//It works, do something.
console.log(data);
} else{
//It does not work, do something.
console.log('Your ajax failed to get the info from your php page. Keep troubleshooting');
}
}
});
});
});
profile.php
<?php
/*
$status_id = $_POST['status']; //This needs to be sanitized and validated.
$sql = $db->query("SELECT * FROM chirps WHERE id='$status_id'"); //This is unsafe sql practice.
if (mysqli_num_rows($sql) > 0) {
$c = $sql->fetch_object();
}
echo json_encode($c); //This is what gets sent back to script.js
*/
echo 'You made it to your php page.';
?>
A few things:
You can not call any php variable from within your js. var uid = $_GET['id']; does not work.
Any value that you pass to the php page needs to be validated to make sure it is a legitimate value.
Your SQL query is prone to sql injections. Please read up on how to parameterize your queries. Good Mysqli Practices
I have finally found a AJAX-based solution to my problem.
I created a new php file called "chirp_open_ref.php" and added this ajax to script.js:
var datastring = 'status=' + messageID;
$.ajax({
url: "chirp_open_ref.php",
type: "POST",
data: datastring,
cache: false,
dataType: "text",
success: function(data){
$('.chirp-container').html(data);
}
});
Inside of 'chirp_open_ref.php':
<?php
require 'core.inc.php';
if (isset($_POST['status']) && isset($_SESSION['user_id'])){
$chirp_id = $_POST['status'];
$c = "";
$sql = $db->query("SELECT * FROM chirps WHERE id='$chirp_id'");
if (mysqli_num_rows($sql) > 0){
$c = $sql->fetch_object();
}
include'chirp.inc.php';
}
?>
'chirp.inc.php' is simply a template for the layout/structure of each post.
This works like a charm, but I am always open to any criticism of how I am performing this. Thanks for all the help guys!
The code I have is at http://www.lesha.wemakesites.ru/
What it does is givng out reversed string and counting times the servise was used.
What I wanna do is that once the page is opened and somebody runs the code on any other device I can see the total number changed without reloading the page.
To do so I'm using 2 ajax-requests of following view:
var ajax_result = $.ajax({
url: 'count.php',
method: 'post',
success: function () {}
})
var ajax_write = $.ajax({
url: 'count.txt',
success: function (data) {
document.getElementById("total_global").style.display = ("none");
document.getElementById("global").style.display = ("inline");
document.getElementById("global").style.color = ("red");
document.getElementById("global").innerHTML = data;
}
In count.php I have:
<?php
$file = 'count.txt';
$file_open = file_get_contents($file);
$file_open = (int)$file_open;
$file_open = $file_open + 1;
file_put_contents($file, $file_open);
echo($file_open);
?>
and after I dynamically show the result with js.
Nevertheless I don't see changes when I run it from my phone until I reload the page at my PC.
I need some help. I am trying to send multiply array of width and length to php, straight forward. I don't want to save it to any HTML field, however it's not working. I am getting the width and length from html text are and convert it to a number and then add it to an array in javascript.
Here is the code for that
var widthL = [];
var lengthL = [];
var widths = document.wall.width.value;
var lengths = document.wall.length.value;
var wNumber = Number(widths);
var lNumber = Number(lengths);
widthL.push(JSON.stringify(wNumber));
lengthL.push(JSON.stringify(lNumber));
This is the Ajax code I am using to send it to PHP
$.ajax( {
type: "POST",
url: "./Summary.php",
data: {"widths": widthL, "lengths" : lengthL},
cache: false,
success: function (response) {
console.log("This is the width", widthL, " This is the length", lengthL);
}
});
In PHP I am using this code to receive it. But I am not getting things back.
<?php
$lengths = json_decode($_POST['lengths']);
$widths = json_decode($_POST['widths']);
echo 'This is the width: '.$widtsL;
echo 'This is the length: '.$lengths;
?>
I was hopping that someone could help me out here.
First you should specify the content type in the ajax POST:
$.ajax( {
type: "POST",
url: "./Summary.php",
contentType: "application/json; charset=UTF-8", // Add content type
data: {"widths": widthL, "lengths" : lengthL},
cache: false,
success: function (response) {
console.log("This is the width", widthL, " This is the length", lengthL);
}
});
then in PHP:
$request_body = file_get_contents('php://input'); //This reads the raw POST data
$json = json_decode($request_body); // Then parse it to JSON
$lengths = $json->lengths;
$widths = $json->widths;
please add a POST parameter name as dataType,type it value JSON,
the Ajax data param value use key=value&key=value format
then in php file enter debug code
I am working on an e-commerce project for practice and right now I am building product filters. So I have three files
catalogue.php
It basically shows all the products.
product filters on left and displays products on right. When user checks a box then AJAX call is made.
productsfilter.js
It contains Javascript and AJAX calls.
var themearray = new Array();
$('input[name="tcheck"]:checked').each(function(){
themearray.push($(this).val());
});
if(themearray=='') $('.spanbrandcls').css('visibility','hidden');
var theme_checklist = "&tcheck="+themearray;
var main_string = theme_checklist;
main_string = main_string.substring(1, main_string.length)
$.ajax({
type: "POST",
url: "mod/product_filter.php",
data: main_string,
cache: false,
success: function(html){
replyVal = JSON.parse(myAjax.responseText);
alert(replyVal);
}
});
product_filter.php
It is the PHP script called by the AJAX call.
$tcheck = $objForm->getPost('tcheck');
if(!empty($tcheck)) {
if(strstr($tcheck,',')) {
$data1 = explode(',',$tcheck);
$tarray = array();
foreach($data1 as $t) {
$tarray[] = "adv.attribute_deterministic_id = $t";
}
$WHERE[] = '('.implode(' OR ',$tarray).')';
} else {
$WHERE[] = '(adv.attribute_deterministic_id = '.$tcheck.')';
}
}
$w = implode(' AND ',$WHERE);
if(!empty($w))
{
$w = 'WHERE '.$w;
}
$results = $objCatalogue->getResults($w);
echo json_encode($results);
So product_filter.php returns an array of product_ids retrieved from the database and gives it back to AJAX. Now the problem is: that array of product ids I got from AJAX call, how do I use it in catalogue.php?
As I got {["product_id" : "1"]} from product_filter.php, I want to use this id in catalogue.php and find the related attributes and display the product details.
How can I pass this array to my catalogue.php page so that it can use this array and call further PHP functions on it?
If the question is unclear then kindly say so, and I will try to explain it as clearly as I can. Help would be much appreciated.
It seems you want to get data from one php and send it to a different php page then have the ajax callback process the results from that second page.
You have at least 2 options
Option 1 (the way I would do it)
In product_filter.php, near the top, do this
include('catalogue.php');
still in product_filter.php somewhere have your function
function getFilterStuff($someDataFromAjax){
// ... do some stuff here to filter or whatever
$productData = getCatalogueStuff($results);
echo json_encode($productData);
exit;
}
In catalogue.php somewhere have that function
function getCatalogueStuff($resultsFromFilter){
// ... get product data here
return $productData;
}
Then in your Ajax do this:
$.ajax({
type: "POST",
dataType: "json", // add this
url: "mod/filter_products.php",
data: main_string,
cache: false,
success: function (response) {
replyVal = response;
alert(replyVal);
}
});
Option 2
Nested ajax calls like this:
$.ajax({
type: "POST",
dataType: "json", // add this
url: "mod/filter_products.php",
data: main_string,
cache: false,
success: function (filterResponse) {
$.ajax({
type: "POST",
dataType: "json", // add this
url: "catalogue.php",
data: filterResponse,
cache: false,
success: function (catalogueResponse) {
alert(catalogueResponse);
}
});
}
});