Success handling behavior in Ext.Ajax.request - php

I am working on extjs 4 project. In this project I have to communicate back and fourth between js and php files. So to call php from js, I am using Ext.Ajax.request.
var dirs = [];
Ext.Ajax.request(
{
url: 'text.php',
method: 'GET',
success: function(response)
{
dirs = JSON.parse(response.responseText);
},
failure: function(response)
{
alert('server-side failure with status code ' + response.status);
}
});
// Creating dropdown list menu
document.write("<select class='select'>");
for (var i = 0; i < dirs.length; i++)
{
document.write("<option>" + dirs[i] + "</option>");
}
document.write("</select>");
php code is the following:
<?php
$filepath = "scenarios";
$dirs = array();
$files = array();
$scenes = array_diff(scandir($filepath), array('..', '.'));
for ($i = 2; $i < count($scenes)+2; $i++)
{
if (strpos($scenes[$i], '.'))
{
array_push($files, $scenes[$i]);
}
else
{
array_push($dirs, $scenes[$i]);
}
}
if (count($dirs) > 0)
{
echo json_encode($dirs);
}
else
{
echo json_encode("You do nat have any projects. Please create new project.");
}
?>
Now the problem appears in the part where I want to generate list menu from the resulting dirs object. In the firebug DOM dirs = ["google","yahoo"], but in the loop, dirs.length returns 0???
Also when I put alert(dirs.length) before the for loop, it shows 0, then correctly generates the list menu...weird????

The request call is asynchronous which means, that after calling Ext.Ajax.Request, the next instruction is your loop. But you haven't received the data from the server yet. You need to put the loop in the success callback to make sure that you'll execute it after getting the data from the server.
var dirs = [];
Ext.Ajax.request(
{
url: 'text.php',
method: 'GET',
success: function(response)
{
dirs = JSON.parse(response.responseText);
// Creating dropdown list menu
document.write("<select class='select'>");
for (var i = 0; i < dirs.length; i++)
{
document.write("<option>" + dirs[i] + "</option>");
}
document.write("</select>");
},
failure: function(response)
{
alert('server-side failure with status code ' + response.status);
}
});
Also when I put alert(dirs.length) before the for loop, it shows 0,
then correctly generates the list menu...weird????
This is because the alert stop the execution flow of your program until you click on "ok". The data are probably coming from the server during this time, and the dir variable is populated with them.

I can't see any headers being sent out - which is required by most browsers:
header('content-type: application/json; charset=utf8;');
if(sizeof($dirs) > 0){
echo json_encode(array('success' => true, 'data' => $dirs));
}
else {
echo json_encode(array('success' => false, 'error' => 'You do not have any projects.' ));
}
The JavaScript:
var xhr = new Ext.data.Connection();
xhr.request({
url: '/text.php',
method: 'GET',
headers: {'Accept':'application/json'},
success: function(response, opts) {
var obj=Ext.decode(response.responseText);
var html='';
Ext.each(obj.data, function(v,i){html+='<option>'+v+'</option>';});
html='<select>'+html+'</select>';
console.info(html);
}
});
The HTML generation has to reside in the callback function - else it makes no sense at all.
Without having seen the JSON which is being returned - it's hard to tell what's wrong with it.
Down-voting without leaving a comment why exactly is really lame.

Related

My ajax taking too much time in for loop calling a php file

My Ajax is taking too much time on loading am calling ajax from 1 to 3000
It hit on database and get if value exist in database from 1 to 3000 then it will return
Here's my code
function Getdata(e) {
e = e;
jQuery.ajax({
type: "GET",
async: true,
url: "getdata.php",
data: "id=" + e,
success: function(t) {
jQuery(".reult_get_wish-" + e).html(t.htmltext)
},
dataType: "json"
})
}
for (var e = 1; e <= 3000; e++) {
Getdata(e);
}
Here's my getdata.php file code
$id = $_GET['id'];
$sql = "SELECT * from wishing_report where user = '".$id."'";
$result = $mysqli->query($sql);
if ($e = $result->fetch_array(MYSQLI_ASSOC))
{
echo json_encode($e);
}
Explained
If it takes some time, why not use an asynchronous approach, where you can process 'x' amount at a time, i.e. you could use setTimeout and recursion or setInterval, just so you can process a block of information/data at a time.
In this example you can see that there's an onIterate function and a onComplete function, both of these are used in different scenarios, you can use the onIterate function for each iteration, prior to the iterate function being complete. Once you've iterated enough, this is when you can fire the onComplete function, feel free to make any changes you like, i.e. include promises or whatever takes your fancy.
This could also be a better approach for the server as you're allowing the server time to recover from the last request. Alternatively you could alter your back end code so that it's more efficient, etc, you could use some limit and offset parameter(s) within your query to ensure the server isn't handling too much data at one time.
// A function to fire when the ajax request has finished.
const onSuccess = data => {
console.log(data);
};
// Simulate the ajax request.
const getData = (i, callback) => {
setTimeout(() => {
console.log(i);
return callback(i);
}, 500);
}
// A function to fire once complete.
const onComplete = () => console.log('Finished');
// A function to fire if it's not finished/complete.
const onIterate = () => console.log('NOT finished yet');
// A function to iterate, break the loop up into chuncks.
const iterate = (start, end, delay) => {
const process = data => {
iterate(++start, end, delay)
if (start > end) {
onComplete(data);
} else {
onIterate(data);
}
};
if (start <= end) {
setTimeout(() => {
getData(start, process);
}, delay);
}
};
// A starting point.
const start = () => iterate(0, 10, 1500);
// Just start the function.
start();
Your Ajax is taking a lot of time beacause you're running it 3000 times. To avoid calling it many times, I recommend putting all ids in array. I would do something like this.
JavaScript:
function Getdata(e) {
e = e;
jQuery.ajax({
type: "POST",
async: true,
url: "getdata.php",
data: {id: e},
success: function(t) {
$.each(t, function() {
$.each(this, function(k, v) {
jQuery(".reult_get_wish-" + v).html(v.htmltext);
});
});
},
dataType: "json"
})
}
var arr = [];
for (var e = 1; e <= 3000; e++) {
arr.push(e);
}
Getdata(arr);
PHP:
$id = $_POST['id'];
$sql = "SELECT * from wishing_report where user IN ('".implode(',', $id)."')";
$result = $mysqli->query($sql);
if ($e = $result->fetch_array(MYSQLI_ASSOC))
{
echo json_encode($e);
}

Configuring a submit button using AJAX that checks for the value of an incremented variable

I'm trying to use AJAX properly to display an incremented value from a separate PHP file, but I'm a little iffy on the code. This is what it looks like:
$("#submit").click(function()
{
$.ajax({
type: 'POST',
url: 'info.php',
dataType: 'json',
data: {$_SESSION['totalCorrect'}
success: function()
{
if ($_SESSION['totalCorrect'] >= 8 && $_SESSION['totalCorrect'] <= 10)
{
window.location.replace('success.php');
}
else
{
window.location.replace('retake.php');
}
}
});
});
The value is stored in info.php and I'm trying to pull that value from that file, but I'm not sure on how to code the AJAX syntax. I'm certain this data: {$_SESSION['totalCorrect'} code isn't correct.
I can display the incremented value so I know, at least, that the variable is being incremented, but what I want to do now is to use that variable to check if they passed or not. If they did, then they get redirected to success.php. If not, then they get sent to retake.php.
EDIT: info.php
if (empty($_SESSION["totalCorrect"]))
{
$_SESSION["totalCorrect"] = 0;
}
else
{
$totalCorrect = $_SESSION["totalCorrect"];
}
foreach ($correctAns as $key => $answer)
{
if (!empty($_POST[$key]))
{
if ($_POST[$key] == $answer)
{
echo $correct[$index];
$_SESSION["totalCorrect"]++;
}
else if($_POST[$key] != $answer)
{
echo $incorrect[$index];
}
$_SESSION[$key] = true;
}
$index++;
};
You haven't posted all code, so I can only answer the one question.
First:
You're mixing php and javascript. You cannot access php variables in javascript unless you assign them as string to the output html or post them via an ajax - that's what you want to do.
So let's have a look at your jQuery-ajax:
$("#submit").click(function() {
$.ajax({
type: 'POST',
url: 'info.php',
// dataType: 'json', // I deactivated this to recieve a string only
// in data you should get the answers the user gave - another topic
data: {question1: '42', question2: 'Douglas'}, // that ',' was missing
// you'll get whatever you echo in info.php as 'result' as parameter
// in this success-callback-function (as result [json]):
success: function(result) {
// now you can check what the result is:
console.log(result); // make it visible to you for debugging
if (parseInt(result) >= 8 && parseInt(result) <= 10) {
console.log('redirecting to SUCCESS');
//window.location.replace('success.php'); // uncomment when working
}
else {
console.log('redirecting to RETAKE');
//window.location.replace('retake.php'); // uncomment when working
}
}
});
});
now lets adjust your info.php:
if (empty($_SESSION["totalCorrect"]))
{
$_SESSION["totalCorrect"] = 0;
}
else
{
$totalCorrect = $_SESSION["totalCorrect"];
}
foreach ($correctAns as $key => $answer)
{
// remember, that in $_POST you'll get everything you've put in 'data' before!
if (!empty($_POST[$key]))
{
if ($_POST[$key] == $answer) // better change to === if you know what data-types you'll get (and google the difference)
{
//echo $correct[$index]; // do not echo anything else but the result
$_SESSION["totalCorrect"]++;
}
else if($_POST[$key] != $answer)
{
//echo $incorrect[$index];
}
$_SESSION[$key] = true;
}
// $index++; // we don't need that, do we??
};
// here's the actual response/result:
// All you echo will be in 'result' of your ajax succes-callback-function
echo $_SESSION["totalCorrect"];
I don't know what your form looks like, how all the pages are set up, so I can't provide a complete code - also this would go far beyond the question.
But this should give you an idea of how getting are variable from php via ajax works.
Further Info:
Getting form data using JavaScript and sending data with Ajax
usefull stuff about json:
http://www.w3schools.com/js/js_json.asp
http://php.net/manual/en/function.json-encode.php

Get Progress of PHP Script using jQuery.ajax

I am using jQuery's ajax to run a php script with the below:
jQuery.ajax({
type: "POST",
url: "my_php_script.php",
success: function( response ) {
console.log(response);
},
error: function(){
console.log('error is...');
}
});
my_php_script.php loops through an array and on each product runs a function:
$count = count($array);
$i = 0;
foreach ($array as $item) {
myFunction($item);
$i++;
if($i == $count){
echo json_encode('all done and a success');
}
}
This all works but the script can generally take around 2-3 minutes to finish so I need to show the progress for the viewer whilst it runs. How can i do this?
I can get the percent of the loop by adding
$percent = intval($i/$count * 100)."%";
echo json_encode($percent);
into my php loop as so:
$count = count($array);
$i = 0;
foreach ($array as $item) {
myFunction($item);
$percent = intval($i/$count * 100)."%";
echo json_encode($percent);
$i++;
if($i == $count){
echo json_encode('all done and a success');
}
}
But how can i get this value in my jQuery ajax call?
$.ajax({
url: path,
xhrFields: {
onprogress: function (e) {
}
},
success: function (response) {
}
});
Found this example hope it helps.
Got this working in the end by writing the percentage in a uniquely named text file as so in my array loop:
$percent = intval($i/$count * 100)."%";
$_text = file_get_contents($_file);
$_text = $percent;
file_put_contents($_file, $_text);
And then in my html page i check the contents of the file every 2 seconds by:
jQuery.get('file.txt?'+new Date(), function(data) {
console.log(data);
}, 'text');
I'm sure this isn't the best way of doing so but to get this working in a limited time period it's all i could come up with. Hope it helps anyone else

jQuery AJAX Request Doesn't Work on Page Load, However, It Does Work from Debug Console

Turning off asynchronous requests in jQuery fixed the issue.
I have the following Javascript & AJAX request (using jQuery) in my page:
"use strict";
var hsArea, counter, hotspots, count;
counter = 4;
count = 0;
hotspots = {};
function fetchHotspotList() {
$.getJSON ('/alpha/engine/hotspots/gethotspot.php', {'type' : 'list'}, function(json) {
hotspots = json;
});
}
function displayHotspot(type, id, number) {
$.ajax({
url: '/alpha/engine/hotspots/gethotspot.php',
dataType: 'json',
data: {'type' : type, 'id' : id},
success: function(json) {
console.log(json);
var hotspot, extract;
extract = json.content;
extract = extract.replace(/<(?:.|\n)*?>/gm, '');
extract = extract.substring(0, 97);
extract = extract + "...";
json.content = extract;
hotspot = document.createElement("div");
hsArea.append(hotspot);
hotspot.setAttribute('class','hotspot');
hotspot.setAttribute('id','hotspot' + number);
$(hotspot).css('position', 'absolute');
$(hotspot).css('top', number * 100 + 100);
$(hotspot).css('left', number * 100 + 110);
hotspot.innerHTML = "<h1>"+ json.title + "</h1><p>" + json.content + "</p>";
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus, errorThrown);
}
});
}
function listHotspots() {
for(count = 0; count < counter; count++) {
(function(count) {
displayHotspot('scribble',hotspots[count], count);
count = count + 1;
})(count);
}
}
function loadHotspots() {
fetchHotspotList();
listHotspots();
}
$(document).ready(function() {
hsArea = $("#hotspotArea");
fetchHotspotList();
listHotspots();
});
(Sorry the formatting is a bit off!) - Now, the $(document).ready() function assigns the hsArea variable as it should, however, a combination of fetchHotspotList() and listHotspots() returns:
Uncaught TypeError: Cannot call method 'replace' of null
However, if in the Google Chrome Javascript console, I run:
loadHotspots();
it fetches the data from the AJAX request and displays it properly on the page. At first I thought the problem was that I Wasn't using the $(document).ready() handler, but adding it hasn't fixed it. Neither has using an onload handler inside of the body tag.
Any help would be greatly appreciated.
Regards,
Ben.
It's probably due to the fact that your listHotSpots function is called before fetchHotSpots returns (since it's an async call).
You're better off chaining the execution of listHotSpots to the completion of fetchHotSpots, like so:
function fetchHotspotList() {
$.getJSON ('/alpha/engine/hotspots/gethotspot.php', {'type' : 'list'}, function(json) {
hotspots = json;
listHotSpots();
});
}
You may be better off modifying listHotSpots to take the json data returned from your AJAX call. Hope this helps!

AJAX: Problems returning multiple variables

First off sorry if I'm missing something simple just started working with AJAX today. I have an issue where I'm trying to get information from my database, but different records have different amounts of values. For instance, each record has a "features" column. In the features column I store a string. (ex: Feature1~Feature2~Feature3~Feature4... ) When I'm building the object I take apart the string and store all the features into an array. Some objects can have 1 feature others can have up to whatever. So... how do I return this values back to my ajax function from my php page? Below is my ajax function that I was trying and I'll provide a link with my php file. [ next.php : http://pastebin.com/SY74jV7X ]
$("a#next").click(function()
{
$.ajax({
type : 'POST',
url : 'next.php',
dataType : 'json',
data : { nextID : $("a#next").attr("rel") },
success : function ( data ) {
var lastID = $("a#next").attr("rel");
var originID = $("a#next").attr("rev");
if(lastID == 1)
{
lastID = originID;
}
else
{
lastID--;
}
$("img#spotlight").attr("src",data.spotlightimage);
$("div#showcase h1").text(data.title);
$("div#showcase h2").text(data.subtitle);
$("div#showcase p").text(data.description);
$("a#next").attr("rel", lastID);
for(var i=0; i < data.size; i++)
{
$("ul#features").append("<li>").text(data.feature+i).append("</li>");
}
/*
for(var j=1; j < data.picsize; j++)
{
$("div.thumbnails ul").append("<li>").text(data.image+j).append("</li>");
}
*/
},
error : function ( XMLHttpRequest, textStatus, errorThrown) {
$("div#showcase h1").text("An error has occured: " + errorThrown);
}
});
});
First replace the below in your next.php file:
for ( $i=0; $i < $arraySize; $i++ )
{
$return['feature'.$i.''] = $features[0];
}
With:
$return['features'] = $features;
P.S: the current code is wrong you should have ... = $features[$i]; anyway, you don't need that just send the array as is. and then in the JS part replace:
for(var i=0; i < data.size; i++)
{
$("ul#features").append("<li>").text(data.feature+i).append("</li>");
}
With:
$.each(data.features, function(k,v){
var li = '<li>' + v + '</li>';
$("ul#features").append(li);
});
This way, don't need the data.size anymore.

Categories