wait to leave page until ajax is done - php

Basically, I am sending a $.POST() when an element is clicked. this element brings the user to a different page, and the POST request is not going all the way through. If i step through it slowly the script gets ran, however.
How can i make the page wait until the script has run until it navigates away from the page? or is there a different issue here? Sort of new to AJAX
$('.ad-link').on('click', function() {
$.get('http://easyuniv.com/php/clickPP.php?id='+$(this).attr('id'));
});
and then clickPP.php is just a simple SQL query that i have verified to work.
Thanks

You can use a callback for this, like so:
$('.ad-link').on('click', function(e) {
e.preventDefault();
var url_to_redirect = $(this).attr('href');
$.get(
'http://easyuniv.com/php/clickPP.php?id='+$(this).attr('id'),
{},
function(return_data){ // callback function, wait till request is finished
// use the return_data if you need it
location.href = url_to_redirect; // redirect the user
}
);
});

Related

Making two simultaneous AJAX calls to PHP

I have a form which submits an AJAX request to one of my controllers which uploads a file using PHP's curl. I want to show the user the status of that (PHP) upload, so I store the PHP upload progress in a session variable. Meanwhile, the submission of the form also starts a setInterval() which makes a different AJAX request to controller which checks the session variable. My problem is that the second AJAX call seems to only fire once (instead of throughout the upload process) and so instead of progressively updating the progress, it just returns 100 at the end. What am I doing wrong?
Here's my code:
(note: I'm using the jQuery form plugin to assist with the file upload. It also adds some additional callbacks)
<script>
var check_progress = function() {
$.ajax(
{
url : '/media/upload_progress',
success : function(data) {
console.log(data);
},
async : false
}
);
var options = {
beforeSend : function() {
$("#MediaSubmitForm").hide();
$("#MediaSubmitForm").after('<img class="hula-hippo" src="/img/hippo-hula.gif" />');
t = setInterval( check_progress, 500 );
},
success : function(data){
$(".hula-hippo").hide();
$("#MediaSubmitForm").after("<h3>Upload complete!</h3><p>Do <strong>you</strong> want to <a href='#'>create a project</a> of your own?</p>");
window.clearInterval(t);
console.log(data);
}
};
$("#MediaSubmitForm").ajaxForm(options);
</script>
Use setTimeout();. setInterval() executes the code after the time specified and setTimeout() executes the code every time it reaches the specific time.
These question explain well of their difference :)
setTimeout or setInterval?
'setInterval' vs 'setTimeout'
setInterval & setTimeout?
setInterval and setTimeout
JavaScript setInterval and setTimeout
And a search of this on SO will solve your problem :)
It sounds like this is a PHP locking issue. See the first comment in the answer to this question:
jQuery: Making simultaneous ajax requests, is it possible?

Loading external php page

The function below grabs a php page, then reloads it every 5 seconds. The only thing coming from that roomdata.php page is a string with a color name (blue, yellow, etc.). I wanted to be able to use that name in the function modifyLight(color), but it's not letting me. I don't know why, but no matter what I tried, it's not treating the variable data as a string, even if I clarify it as one.
Any help is appreciated, thanks!
$(function(){
function loadData()
{
var data = load('roomdata.php');
modifyLight(data);
setTimeout(loadData, 5000); // makes it reload every 5 sec
}
loadData(); // start the process...
});
You are using async ajad calls. You need to configure your request to be sync.
$.ajax(URL, {async : false});
In that way the execution of the next line will be done until the ajax request Is finished.
EDIT
Your function should be like this:
$(function(){
function loadData() {
$.post("roomdata.php", function(result) {
modifyLight(result);
setTiemout(function() { loadData(); }, 5000);
}
}
loadData(); // start the process...
});
The problem with the way you were doing it is that $.load(); only loads something with Ajax and put the content on $('#yourdiv'); It does not return anything. You need an ajax request with something in the "success" event. In the code I gave you, $.post makes an ajax request via post to roomdata.php and then, once the ajax is finnished, it executes the function function(result) { ... }

Have one function to wait for an AJAX call, without synchronous AJAX(SJAX)

I am creating a dynamic todo-list on a webpage. On the page you have a form for registering todo's and a table showing all the registrated todo's. The idea is that you register something you want done in a form, hit the submit button, and then the todo-list-table is automatically updated with the latest registered todo. My script manages all of this except for automatically updating the latest registered todo.
Here's my code:
$(document).ready( function() {
$('#todo_registration input[type="submit"]').click(function(evt){
evt.preventDefault();
var todo = $('#todo_registration input[name="daily_todo"]').val();
$('#todo_registration input[name="daily_todo"]').val(null);
$.when( registerTodo(todo) )
.then (
updateTodoDisplay()
);
});
});
function updateTodoDisplay() {
$.post("./daily_todo_display.php", null, replaceTbodyHTML);
}
function replaceTbodyHTML(data) {
$('#todo_display_table tbody').html(data);
}
function registerTodo(todo) {
var parameters = {
daily_todo: todo,
registration_button: 'clicked'
};
$.post("./daily_todo_registration.php", parameters); //, printRegistrationStatus);
}
I have checked that the script successfully registrates the todo in the database. The php-script that gets the updated todo-list also works. My problem, I think, is that the function updateTodoDisplay() doesn't wait for the AJAX call in registerTodo() to successfully complete before it runs. But I thought my use of #.when() was supposed to make updateTodoDisplay() wait.
I know making the AJAX call synchronous would probably fix my problem, but in my opinion that is a bad solution. I only want this one and only function to wait for the AJAX call to complete. Thus I want the rest of the webpage to function while these calls are made.
Any one know a fix for my problem? Thnx.
What you need is possible, but it looks like you have an error in your code.
Change the
.then (
updateTodoDisplay()
);
to
.then (function(){ updateTodoDisplay(); } );
or even
.then (updateTodoDisplay);
The problem is that when you are registering the callback, in your current code you are passing the result of executing updateTodoDisplay() instead of passing it as a function. That is why you get it executed right away.
You should $.post your data, AND when server-side updating is done, respond from server-side too - sending text/json/xml back to the UI. You save one (the second) request with that, you keep ajax asynchronous, you keep your code shorter/more-maintainable, and you get rid of this issue. =)
$.post("url/todo.php", params, function (data) {
// callback
// do UI update here
// "json" but you can say "xml" too
}, "json");
All you need to do is to figure out your server-side response.
jQuery.post()
Have a nice time implementing! =)

How to make PHP function run after javascript ends?

I have two PHP functions - one that builds a html form and another that handles it when it's submitted.
I want to add to the html a javascript onClick function that sends one of the form's fields to an external API (Google Maps) and saves the reply in a hidden field in the form so that the handling PHP function will get that data as well.
My question is - how do I make sure the handling PHP function only fires after the onClick function has finished?
Or maybe I can't and I have to use ajax?
You'll need 2 events to accomplish this.
the onClick event for your button that executes the google map request and saves the data into the local form
an onSubmit event for your form. You will use this event to see if the form is submittable. Basically, check to make sure that your google map request has been run and has completed before allowing the form to submit.
Example:
<script>
var googleMapsDone = false;
$('#gmap_button').click(function(event)
{
doGoogleMapThing(function()//callback from googlemaps
{
//save data to local form for processing by script once posted
googleMapsDone = true;
});
});
$('#form').submit(function(event)
{
//check to see if we did our google maps stuff, and that its done
if (false == googleMapsDone)
{
event.preventDefault();
return false;
}
});
</script>
With that code, any time the user is waiting for google maps and clicks submit, nothing will happen. They would have to wait on the response from GMaps, THEN click submit. This is okay for some things, but if you're trying to do background requests to GMaps that require no user input/interaction/feedback (maybe getting Long/Lat of their address when they submit a form), then you can modify the code a bit to post when you get the response. An example of that would be:
<script>
var googleMapsDone = false, submitWaiting = false;
$('#gmap_button').click(function(event)
{
doGoogleMapThing(function()//callback from googlemaps
{
//save data to local form for processing by script once posted
googleMapsDone = true;
/* check to see if submitWaiting is TRUE. If it is, automatically
post the form when we get the response.
*/
if (submitWaiting)
{
$('#form').submit();
}
});
});
$('#form').submit(function(event)
{
//check to see if we did our google maps stuff, and that its done
if (false == googleMapsDone)
{
event.preventDefault();
/* set our submitWaiting flag which we will use in our clalback
so when we get our google maps response, we post our form right
away
*/
submitWaiting = true;
/* You might want to display a modal or some other kind of notification
that the form post is 'working' or 'processing' so when the user
clicks it and doesn't see anything happening, they don't bail
or click it 800 times out of frustration
*/
return false;
}
});
</script>
edit: I realize my comment below on how this works are...hard to understand, so let me explain here, then show an alternative.
User fills out form
User clicks button to do stuff on google maps (example was written before I knew the scope/context of the GMaps request, so that's why it's done this way)
If user then clicks 'submit' before the GMap request is complete, we CANCEL the submit and set a flag submitWaiting
GMaps request returns, and executes our callback. Our callback knows how to look for submitWaiting and if it is set to true it submits the form
An alternative to this, instead of requiring user interaction for the GMaps request you could change the event to an onChange event for the input box of the address, or you can do it all via the submit button/event, like so:
<script>
$('#form').submit(function(event)
{
//lets look up our user's address!
doGoogleMapThing(function()//callback from googlemaps
{
//do stuff with your inputs, or whatever
$('#form').submit();
});
event.preventDefault();
return false;
});
</script>
edit note: the examples above assumes you're using jquery, and that your google map API request is done via javascript
If your google map api request is not using the google maps javascript library, this is STILL possible, just requires you to make a "proxy" script to the API via a php script on your local domain. (Browser restrictions). It'd be something like THIS:
<script>
function doGoogleMapThing(callback_when_done)
{
$.post("/path/to/proxy/script.php", { data: to, post: to_server }, function(response)
{
//check & parse response
callback_when_done(/* Data needed to populate form */);
});
}
</script>
note: both of these examples assume jquery usage. because...well..why wouldn't you.
Below is an implementation of your exact script. I changed it a bit to use jquery, because it makes things a bit less painful.
<script type=”text/javascript”
src=”http://maps.google.com/maps/api/js?sensor=false”></script>
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.6.min.js"></script>
<script type=”text/javascript”>
function codeAddress(callback)
{
var address = $('#address').val();
geocoder.geocode( { 'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
$('#latitude').val( results[0].geometry.location.latitude );
$('#longitude').val( results[0].geometry.location.longitude );
if (typeof callback != 'undefined') //call the callback.
{
callback(true);
}
}
});
/* Just in case google returns a bad response or doesn't return at all
we need to add a timeout that will call the callback after 10 seconds
just so we make sure our user doesn't hang.
*/
setTimeout(function(){
callback(false); //pass false indicating no/invalid response
}, 10000); //10000ms = 10s
}
/* We are using the reallySubmit variable as a flag here, to know when we finish
our call to google maps and that we want to really submit our form.
we have to do this because the form.submit() call fires the form's submit event
again, and we end up going into an infinite loop.
an alternative to this would be to bind your form processing to the form's submit
button's click event. that should also pick up any presses of the enter key, also.
the solution below also works.
*/
var reallySubmit = false;
$('#form').submit(function(event)
{
if (false == reallySubmit)
{
//lets look up our user's address!
codeAddress(function(success)//callback from googlemaps
{
reallySubmit = true;
$('#form').submit();
});
event.preventDefault();
return false;
}
});
</script>
This is fundamentally impossible - PHP runs on the server, JavaScript runs on the client. You will indeed need to use Ajax.
You can have a hidden IFRAME element where you load a php document as soon as your javascript ends. Simple, but effective (as long as your php document comes from the same URL).
AJAX is a must I am afraid. You need to redirect the user to a page with the script.
Once the server has run the PHP to generate the HTML, then sent it to the browser, there is no way to run it again, or indeed run anything from the server, without making a request to the server. That is the nature of a server side scripting language, of which PHP is.

stop running ajax calls

i have a dynamic search in php with jquery.
When i'm entering a letter, an ajax call starts.
My problem is, that all ajax calls are working till end, so that every letter is a full call.
When a user is entering a full word then i have unused requests.
How can i stop the unused calls?
Thank you very much
Use timeouts to delay the request for a few millisecond, and clear it when a new key is pressed.
something like
var searchtimeout;
$('#search').keyup( function(){
if (searchtimeout)
{
clearTimeout(searchtimeout);
}
searchtimeout = setTimeout(function(){
// initiate the ajax call here..
}, 300);
} );
Either use a button to process the request that the user has to click when their finished or perhaps use something like debouncing.
One way you could do it , is to send the request when the user presses the return key , or atleast wait a few seconds ( 1-3 ) to see if the user stoped typing then make the request , you don't have to do the search for all changes on the input box .
Why dont you use the autocomplete plugin in jquery.. I am assuming you have handcoded the dynamic lookup.. auto complete takes care of most of these things and it is also configurable as to after how many letters you want to post to the server..it also implements caching.
I have used it in a lot of asp.net projects and it is pretty neat..
docs.jquery.com/Plugins/autocomplete
Ok, here is my solution:
if (searchtimeout)
{
clearTimeout(searchtimeout);
}
searchtimeout = setTimeout(function(){
if(x){
x.abort();
alert("MACH WEG!");
}
x = $.post(url + "ajax.html?nsearch=1&ckey="+SID, {queryString: ""+inputString+""}, function(data) { // Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
x = null;
});
}, 300);

Categories