Just for the sake of correctness this can be done in a clean asynchrounous way with jQuery Deferreds. These objects represent a task that will be completed in the future, and event handlers can be attached to it's completion. You can call complete on a Deferred manually.
These objects are what jQuery works with behind the scenes for most async task that has callbacks, and you can actually wait for them to be completed.
You need to change your code a little bit.
In the click eventhandler for #printpng
, you need to create deferred objects for every task you want to be completed.
Let's say all 3 click events you trigger manually have something to wait for, so we create 3 deferreds.
$('#printpng').click(function () {
var def1 = $.Deferred();
var def2 = $.Deferred();
var def3 = $.Deferred();
.......... other code not yet included
});
Now we have 3 objects that represent tasks. If you call .resolve()
on them, it means that the task is completed. We want these tasks to be completed when the #tool_export
's click eventhandler is done.
Let's say this #tool_export
has a click event handler and we are somehow able to pass the deferred object to it.
$('#tool_export').click(function (e, deferred) {
$.ajax({
url: 'your_url',
success: function(result){
// your code does stuff with the result
if (deferred !== undefined) {
deferred.resolve();
}
},
error: function(result){
if (deferred !== undefined) {
deferred.reject();
}
},
});
});
As you can see it makes an AJAX call, and calls deferred.resolve()
if the call was successful and deferred.reject()
if something went wrong. Very simple.
Now the problem is: how to pass this deferred parameter to the click event handlers?
You have written:
$('#tool_docprops').click();
Which is a shorthand for:
$('#tool_docprops').trigger('click');
To pass the def1
object as a parameter, you can simply write:
$('#tool_docprops').trigger('click', def1);
So your event handler gets modified to:
$('#printpng').click(function () {
var def1 = $.Deferred();
var def2 = $.Deferred();
var def3 = $.Deferred();
$('#tool_docprops').trigger('click', def1);
$('#tool_docprops_save').trigger('click', def2);
$('#tool_export').trigger('click', def3);
..... something is still missing from here
});
You can pass as many parameters as you want.
The last thing to do is sumbscribing to this deferreds to complete. There is a very cool helper method called .when()
which waits for any number of deferreds to be resolved. Since it also creates a deferred, you can call deferred.done()
on it to get a callback. So to wait all 3 deferreds you have created earlier, you could write:
$.when(def1, def2, def3).done(function() {
window.location.href = "<?php echo $base_url ?>/sign/print";
});
So your final click event handler for #printpng
would be:
$('#printpng').click(function () {
var def1 = $.Deferred();
var def2 = $.Deferred();
var def3 = $.Deferred();
$('#tool_docprops').trigger('click', def1);
$('#tool_docprops_save').trigger('click', def2);
$('#tool_export').trigger('click', def3);
$.when(def1, def2, def3).done(function() {
window.location.href = "<?php echo $base_url ?>/sign/print";
});
});
I have made a very simple example to show this. There is no ajax call there only a timeout, but you can get the idea.
If you click on start, you will need to wait 4 seconds for it to complete:
http://jsfiddle.net/3ZDEe/2/