JQuery.done on click event

I'm not a javascript developer, so carry me on this ...

I need to redirect after the jQuery click event has completed. This is what I have, but I cannot apply .done to .click . A wrap of just $.when does not work ether ...

 $("#printpng").click(function(){ $('#tool_docprops').click(); $('#tool_docprops_save').click(); $('#tool_export').click() }).done(function(){ window.location.href = "<?php echo $base_url ?>/sign/print" }); 

Does anyone have any better solutions?

thanks

+7
javascript jquery
source share
5 answers

Assuming that every click triggers an Ajax call out of your control (otherwise, why do you have this problem), you can just wait for all / all Ajax requests to complete:

 $(document).ajaxStop(function () { window.location.href = "<?php echo $base_url ?>/sign/print" }); 

You can also add a timeout, if necessary, before changing the URL in case of additional processing after loading Ajax. If this is not an Ajax problem, please clarify and I will adjust (or delete) this answer.

The full version (with an additional delay of 1 second after waiting for Ajax) might look something like this:

 $("#printpng").click(function(){ $('#tool_docprops').click(); $('#tool_docprops_save').click(); $('#tool_export').click(); $(document).ajaxStop(function () { setTimeout(function(){ window.location.href = "<?php echo $base_url ?>/sign/print" }, 1000); }); }); 

As promised [sic], the best solution using promises

Since full code was never provided, the solution was a guess, assuming several ajax calls.

The general solution is to not trigger click events, but simply call the associated code for every click that is promise-friendly.

Assuming each click handler has a special function, just make each function return a promise:

eg.

  function loadPropsViaAjax(){ // simply return the ajax call as $.ajax returns a promise return $.ajax({parameters here}); } function saveDocPropsViaAjax(){ // simply return the ajax call as $.ajax returns a promise return $.ajax({parameters here}); } function waitForImageToload(){ // create a deferred object var def = $.Deferred(); // When the image eventually loads, resolve the promise $('#someimageselector').on('load', function(){ def.resolve(); }); // Return the promise immediately return def.promise(); } 

Then, to use it in your example (executed sequentially with .then() ):

  // On click button event... $("#printpng").click(function(){ // Run operations sequentially loadPropsViaAjax().then(saveDocPropsViaAjax).then(waitForImageToload) .done(function(){ window.location.href = "<?php echo $base_url ?>/sign/print" }); }); 

Or, if they can work in parallel, use $.when :

  // On click button event... $("#printpng").click(function(){ // Run operations in parallel $.when(loadPropsViaAjax, saveDocPropsViaAjax, waitForImageToload) .done(function(){ window.location.href = "<?php echo $base_url ?>/sign/print" }); }); 
+8
source share

Just for the sake of correctness, this can be done in a clean asynchronous way with jQuery Deferred . These objects represent a task that will be completed in the future, and event handlers can be tied to completion. You can invoke the "Snooze manually" command.

These objects are what jQuery works behind the scenes for most async tasks that have callbacks , and you really can wait for them to complete.

You need to change your code a bit.

In the click event handler for #printpng you need to create deferred objects for each task that you want to complete.

Let's say all three click events that you trigger manually must wait, so we create 3 snoozes.

 $('#printpng').click(function () { var def1 = $.Deferred(); var def2 = $.Deferred(); var def3 = $.Deferred(); .......... other code not yet included }); 

Now we have 3 objects that represent the tasks. If you call .resolve() , it means the task is complete. We want these tasks to be performed after executing the #tool_export click event handler.

Say this #tool_export has a click event handler, and somehow we can pass a pending 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 calls the AJAX call and calls deferred.resolve() if the call was successful and deferred.reject() if something went wrong. Very simple.

Now the problem is this: how do I pass this pending parameter to click event handlers?

You wrote:

 $('#tool_docprops').click(); 

This is a shorthand for:

 $('#tool_docprops').trigger('click'); 

To pass def1 as a parameter, you can simply write:

 $('#tool_docprops').trigger('click', def1); 

So your event handler changes 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 to defer this delay until completion. There is a very cool helper method .when() that expects any number of pending requests to be resolved. Since it also creates deferred, you can call deferred.done() to get a callback. So, to wait for all 3 pending before, you could write:

 $.when(def1, def2, def3).done(function() { window.location.href = "<?php echo $base_url ?>/sign/print"; }); 

So your last click event handler for #printpng will look like this:

 $('#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 made a very simple example to show this. There is no ajax call there just a timeout, but you can get this idea.

If you press the Start button, you will need to wait 4 seconds to complete:

http://jsfiddle.net/3ZDEe/2/

+6
source share

try something like this

 $("#printpng").click(function(){ $('#tool_docprops').click(); $('#tool_docprops_save').click(); $('#tool_export').click() window.location.href = "<?php echo $base_url ?>/sign/print" }); 

try to do asyc = false

 $.ajax({ url:"demo_test.txt", async: false, success:function(result){ $("#div1").html(result); } }); 
-one
source share

as I understand that you need to redirect the page after the click event has completed. To do this, you just need to add the callback function to the click event.

When the click is complete, this function calls the callback function, and in this function you write the redirection code.

, eg:

 $("#printpng").click(function(){ $('#tool_docprops').click(function(e){ // write here your redirection code }); $('#tool_docprops_save').click(function(e){ // write here your redirection code }); $('#tool_export').click(function(e){ // write here your redirection code }); }); 

thanks

-one
source share

Just write your redirect code at the end of the click handler.

 $("#printpng").click(function(){ $('#tool_docprops').click(); $('#tool_docprops_save').click(); $('#tool_export').click(); window.location.href = "<?php echo $base_url ?>/sign/print"; }); 

If you need to wait until the asynchronization process (caused by click events) is completed before the page location is updated, you need to fix your decision.

i.e. your asynchronous process is an ajax call that generates a request after pressing #tool_docprops_save. Then you must attach the success event to this ajax call, which will update window.location.href after the ajax call is completed.

-2
source share

All Articles