This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Kill Ajax requests using JavaScript using jQuery
Here is the simple code I am working with:
$("#friend_search").keyup(function() {
if($(this).val().length > 0) {
obtainFriendlist($(this).val());
} else {
obtainFriendlist("");
}
});
function obtainFriendlist(strseg) {
$.ajax({
type: "GET",
url: "getFriendlist.php",
data: "search="+strseg,
success: function(msg){
UIDisplayFriends(msg);
}
});
}
Essentially, if a keyup event is fired before the function obtainFriendlist returns a result (and triggers UIDisplayFriends(msg), I need to cancel the in-flight request. The issue I have been having is that they build up, and then suddenly the function UIDisplayFriends is fired repeatedly.
Thank you very much, and advice is helpful too
The return value of $.ajax is an XHR object that you can call actions on. To abort the function you would do something like:
var xhr = $.ajax(...)
...
xhr.abort()
It may be smart to add some debouncing as well to ease the load on the server. The following will only send an XHR call only after the user has stopped typing for 100ms.
var delay = 100,
handle = null;
$("#friend_search").keyup(function() {
var that = this;
clearTimeout(handle);
handle = setTimeout(function() {
if($(that).val().length > 0) {
obtainFriendlist($(that).val());
} else {
obtainFriendlist("");
}
}, delay);
});
A third thing that you should really be doing is filtering the XHR responses based on whether or not the request is still valid:
var lastXHR, lastStrseg;
function obtainFriendlist(strseg) {
// Kill the last XHR request if it still exists.
lastXHR && lastXHR.abort && lastXHR.abort();
lastStrseg = strseg;
lastXHR = $.ajax({
type: "GET",
url: "getFriendlist.php",
data: "search="+strseg,
success: function(msg){
// Only display friends if the search is the last search.
if(lastStrseg == strseg)
UIDisplayFriends(msg);
}
});
}
How about using a variable, say isLoading, that you set to true through using the beforeSend(jqXHR, settings) option for .ajax, and then using the complete setting to set the variable back to false. Then you just validate against that variable before you trigger another ajax call?
var isLoading = false;
$("#friend_search").keyup(function() {
if (!isLoading) {
if($(this).val().length > 0) {
obtainFriendlist($(this).val());
} else {
obtainFriendlist("");
}
}
});
function obtainFriendlist(strseg) {
$.ajax({
type: "GET",
url: "getFriendlist.php",
beforeSend: function () { isLoading = true; },
data: "search="+strseg,
success: function(msg){
UIDisplayFriends(msg);
},
complete: function() { isLoading = false; }
});
}
Related
I have a page showing log files which I want to give the user the ability to select and delete. The deletion is done through an AJAX request where the ID of each log-for-deletion is sent via the parameters.
The problem is that there are instances where there are hundreds of logs and in these cases the AJAX request seems to fail. I assume because there is just too much data sent via the parameters. I have tried breaking the AJAX request into parts, but only the first request is sent, afterwards all other requests are shown in Chorme as "cancelled". Following is my code:
var logFiles = [];
function deleteLogBatch() {
if (logFiles.length == 0)
return false;
if (logFiles.length > 10)
var elements = 10;
else
var elements = logFiles.length;
var params = 'action=deletelog';
for (var i = 0; i < elements; i++) {
params += '&lf' + i + '=' + escape(logFiles.shift());
}
$.ajax({
type: "POST",
url: './ajax/logs.php',
data: params,
success: function(response) {
checkResponse(response);
deleteLogBatch();
}
});
}
$('body').on('click', '#confirm-log-delete', function(event) {
event.preventDefault();
$('.select-log').each(function() {
if ($(this).is(":checked")) {
logFiles.push($(this).attr('id'));
}
});
deleteLogBatch();
}
Any help as to why this is happening and what is the proper way of doing this would be appreciated.
You should use async ajax calls
$.ajax({
type: "POST",
url: './ajax/logs.php',
async: true,
data: params,
success: function(response) {
checkResponse(response);
deleteLogBatch();
}
});
It will not wait to previous ajax call
I have a simple AJAX script that suppose to to call a PHP file and get data back.
window.addEvent('domready', function() {
$('dbform').addEvent('submit', function(e) {
new Event(e).stop();
var intervalId =setInterval(function()
{
var Ajax2 = new Request({
url: '/tools/getdata.php',
method: 'post',
data: 'read=true',
onComplete: function(response)
{
$('results').set('html', response);
}
}).send();
},1000);
var postString = 'subbutton=' + $('subbutton').value;
var Ajax = new Request({
url: '/tools/getdata.php',
method: 'post',
data: postString,
onRequest: function()
{
$('message').set('text', 'loading...');
},
onComplete: function(response)
{
$('message').set('text','completed');
clearInterval(intervalId);
},
onFailure: function()
{
$('message').set('text', 'ajax failed');
}
}).send();
});
});
The file that it is submitting too is.
$object= new compare();
if(isset($_POST['subbutton'])=='Run')
{
// This take about 5 minutes to complete
$run=$object->do_compare();
}
if(isset($_POST['read'])=='true')
{
/// in the mean time, the first ajax function is suppose to return data from here..while
// the do_compare() function finish.
// the problem is that it only return it once the do_compare() finish
///
echo 'read==true';
}
the script is working fine, expect, that when the Ajax request check the file every one second, it doesn't return any thing from $_POST['read'], till $run=$object->do_compare(); has finished.
why does it do that? what What I am trying to accomplish is that one Ajax function get data from do_compare function and the other ajax function also independently get that from the getdata.php file.
The problem is in line:
if(isset($_POST['subbutton'])=='Run')
isset returns boolean true or false so if $_POST['subbutton'] is set than it returns true and due to the weak type system of php true == 'Run' because 'Run' evaluates to true. Use
if(isset($_POST['subbutton']) && $_POST['subbutton'] === 'Run')
and
if(isset($_POST['read']) && $_POST['read'] === 'true')
Are you using session in the PHP AJAX handlers? If so, your session file is probably blocked.
Second: Javascript is internally single threaded in the browser (see google for more information).
I have checked around, but can't seem to figure out how this is done.
I would like to send form data to PHP to have it processed and inserted into a database (this is working).
Then I would like to send a variable ($selected_moid) back from PHP to a JavaScript function (the same one if possible) so that it can be used again.
function submit_data() {
"use strict";
$.post('insert.php', $('#formName').formSerialize());
$.get('add_host.cgi?moid='.$selected_moid.');
}
Here is my latest attempt, but still getting errors:
PHP:
$get_moid = "
SELECT ID FROM nagios.view_all_monitored_objects
WHERE CoID='$company'
AND MoTypeID='$type'
AND MoName='$name'
AND DNS='$name.$selected_shortname.mon'
AND IP='$ip'
";
while($MonitoredObjectID = mysql_fetch_row($get_moid)){
//Sets MonitoredObjectID for added/edited device.
$Response = $MonitoredObjectID;
if ($logon_choice = '1') {
$Response = $Response'&'$logon_id;
$Response = $Response'&'$logon_pwd;
}
}
echo json_encode($response);
JS:
function submit_data(action, formName) {
"use strict";
$.ajax({
cache: false,
type: 'POST',
url: 'library/plugins/' + action + '.php',
data: $('#' + formName).serialize(),
success: function (response) {
// PROCESS DATA HERE
var resp = $.parseJSON(response);
$.get('/nagios/cgi-bin/add_host.cgi', {moid: resp });
alert('success!');
},
error: function (response) {
//PROCESS HERE FOR FAILURE
alert('failure 'response);
}
});
}
I am going out on a limb on this since your question is not 100% clear. First of all, Javascript AJAX calls are asynchronous, meaning both the $.get and $.post will be call almost simultaneously.
If you are trying to get the response from one and using it in a second call, then you need to nest them in the success function. Since you are using jQuery, take a look at their API to see the arguments your AJAX call can handle (http://api.jquery.com/jQuery.post/)
$.post('insert.php', $('#formName').formSerialize(),function(data){
$.get('add_host.cgi?moid='+data);
});
In your PHP script, after you have updated the database and everything, just echo the data want. Javascript will take the text and put it in the data variable in the success function.
You need to use a callback function to get the returned value.
function submit_data(action, formName) {
"use strict";
$.post('insert.php', $('#' + formName).formSerialize(), function (selected_moid) {
$.get('add_host.cgi', {moid: selected_moid });
});
}
$("ID OF THE SUBMIT BUTTON").click(function() {
$.ajax({
cache: false,
type: 'POST',
url: 'FILE IN HERE FOR PROCESSING',
data: $("ID HERE OF THE FORM").serialize(),
success: function(data) {
// PROCESS DATA HERE
},
error: function(data) {
//PROCESS HERE FOR FAILURE
}
});
return false; //This stops the Button from Actually Preforming
});
Now for the Php
<?php
start_session(); <-- This will make it share the same Session Princables
//error check and soforth use $_POST[] to get everything
$Response = array('success'=>true, 'VAR'=>'DATA'); <--- Success
$Response = array('success'=>false, 'VAR'=>'DATA'); <--- fails
echo json_encode($Response);
?>
I forgot to Mention, this is using JavaScript/jQuery, and ajax to do this.
Example of this as a Function
Var Form_Data = THIS IS THE DATA OF THE FORM;
function YOUR FUNCTION HERE(VARS HERE) {
$.ajax({
cache: false,
type: 'POST',
url: 'FILE IN HERE FOR PROCESSING',
data:Form_Data.serialize(),
success: function(data) {
// PROCESS DATA HERE
},
error: function(data) {
//PROCESS HERE FOR FAILURE
}
});
}
Now you could use this as the Button Click which would also function :3
updated my question below
I made a script where a user can import large amounts of data. After the form is submitted and the data validated I add 2 background tasks: 1 is a script that imports all the data. This script also lets the databases know how many in total and how many he has done. The second is a script that reads how much is done from the database and displays it in a nice progress bar.
Code:
$.ajax({
type: "GET",
url: "import-process.php",
success: function(data) {}
});
var process = 0;
var checkPercentage = function() {
$.ajax({
type: "GET",
url: "get-process-status.php",
data: "importcode=123456",
success: function(data) {
if (!data.indexOf("ERROR") !== -1) {
process = data;
$("#process_balk").css('width', process + '%');
}
}
});
if (process != 100) {
setTimeout(checkPercentage, 1000);
} else {
window.location.href = "import-finished.php";
}
}
checkPercentage();
Both scripts, work fine. Except that the second script (getting the status of the process) isn't started after the first (importing the data) is finished. Which makes the complete thing kinda useless.
Any ideas how to solve this?
update:
I found out that the background process gets called only once. That's the problem. I'm just not sure how to fix it..
var checkPercentage = function() {
alert("Is this function getting called every second?");
$.ajax({
type: "GET",
async: true,
url: "required/get-process-status.php",
data: "importcode=123456",
success: function(data) {
alert(data);
}
});
setTimeout(checkPercentage, 1000);
}
The code above alerts "Is this function getting called every second?" every second. Like it should. However, the value 'data' is called only once. That's not what I expected.. Any ideas?
You mean like this?:
$.ajax({
type: "GET",
url: "import-process.php",
success: function(data) {
checkPercentage();
}
});
var process = 0;
var checkPercentage = function() {
$.ajax({
type: "GET",
url: "get-process-status.php",
data: "importcode=123456",
success: function(data) {
if (!data.indexOf("ERROR") !== -1) {
process = data;
$("#process_balk").css('width', process + '%');
}
}
});
if (process != 100) {
setTimeout(checkPercentage, 1000);
} else {
window.location.href = "import-finished.php";
}
}
I just moved checkPercantage function call from end of script to success function of first ajax. You can also move it to complete function if you wish to run it despite of errors.
Set your callback function to be:
success: function(data) {
if (!data.indexOf("ERROR") !== -1) {
process = data;
$("#process_balk").css('width', process + '%');
if (process != 100) {
setInterval(checkPercentage, 1000);
} else {
window.location.href = "import-finished.php";
}
}
}
Firstly, the if statement has to be in a callback function to work the way you want it. Secondly, you should use setInterval() instead of setTimeout() because it will recheck it every interval time.
Also, yabol is right saying that the top of your code should look like this:
$.ajax({
type: "GET",
url: "import-process.php",
success: function(data) {
checkPercentage();
}
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 10 years ago.
Trying to run a script, (test.al();) and inside test.al, its called getcrypt.php();, the php script is on a webserver, and it is working. Currently, these are my scripts
JS
var getcrypt = {
php: function () {
$.ajax({
url: "server.com/return.php",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
return v;
}
});
}
}
var test = {
al: function () {
a = getcrypt.php();
alert(a);
}
}
PHP
<?php
$id = $_POST['id'];
if ('getit' == $id){
$value = 'VALUE';
echo $value;
}else{
echo 0;
}
?>
In this way, it will show an alert with 'unidefined', and if i add a alert(v); right before return v, it will show me 'VALUE', but not able to use it outside the variable...
var getcrypt = {
php: function () {
$.ajax({
url: "server.com/return.php",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
alert(v);
return v;
}
});
}
}
This will give me an alert with the correct value (AFTER THE 'undefined')
This is because of the asynchronous call you're making. The return is only for the success function and not for the php function.
To get the value out you would need to write:
var value;
var getcrypt = {
php: function (callback) {
$.ajax({
url: "",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
alert(v);
callback(v);
}
});
}
}
getcrypt.php(function(v) {
alert(v);
// This happens later than the below
value = v;
});
// The below will still not work since execution has already passed this place
// alert will still return undefined
alert(value);
The problem is jQuery ajax works with callbacks and does not work with return value's so you need to add an callback to your getcrypt function so say
var getcrypt = {
php: function (callback) {
$.ajax({
url: "server.com/return.php",
type: "POST",
async: true,
data: "id=getit",
success: function (msg) {
var v = msg.match(/^.*$/m)[0];
callback(v);
}
});
}
}
so now if you call
getcrypt.php(function(returnVar){
alert(returnVar)
});
you will get an alert with VALUE
$.ajax returns immidiately (well, almost :)) upon calling, before the response is received. You should rewrite your code to accomodate to this fact, something like this;
var getcrypt = {
php: function(){
$.ajax({
//..other params ..//
success: function(msg){
var v = msg.match(/^.*$/m)[0];
alertResponse(v);
}
});
},
alertResponse: function(processedResponse) {
alert(v);
}
}
var test = {
al: function(){
getcrypt.php();
}
}
If you need your response in test object, you move alertResponse to that object and call it from success method. I think this tutorial might be useful for you to learn javascript event-driven programming model.
$.ajax calls are async. So what you get is the return value of $.ajax (when the request is sent, before a response is received). It is only when the browser receives a response to the ajax call that the success callback is run, as a seerate process from the $.ajax call. In other words the return value of $.ajax will always be null. I'm not sure it's possible to do anythging with the return value of the success callback, you need to put your logic (or a call to another function with the logic) in the success callback itself, in the same way you did with the alert in your final example