5

When a user closes a browser tab, I want to make an ajax request based on what option he clicks.

If he clicks on Leave this page -> Ajax Call 1

If he clicks on Stay on this page -> Ajax Call 2

here is how my code looks like now

I want to do this ajax call after what the user has selected any one of the option. But currently the ajax call runs automatically if the user tries to close the tab

window.onbeforeunload = userConfirmation;

function userConfirmation(){
  var cookieName  = $.trim("<?php echo $this->uri->segment('5') ?>");
  var toValue     = $.trim($('#toValue').val());
  document.cookie = cookieName+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/';
  var confirmation = 'The message will be discarded.';
  $.ajax({
    type: 'POST',
    url: "<?php echo BASE_URL.'index.php/admin/mail_actions/deleteSessionDatas' ?>",
    data: {'toValue':toValue},
    dataType: 'html',
    success: function(response){
      console.log(response);
      var response = $.trim(response);
    }
  });
  return confirmation;
}
Abhinav
  • 8,028
  • 12
  • 48
  • 89
  • did you mean "page tab" instead of "browser tab" ? – Pedro Lobito Apr 20 '15 at 06:22
  • yes... an individual page tab – Abhinav Apr 20 '15 at 06:25
  • 1
    please post the html of `Leave this page` and `Stay on this page` – Pedro Lobito Apr 20 '15 at 06:26
  • no..I want to make an ajax request based on the click – Abhinav Apr 20 '15 at 06:29
  • I'm sorry but not following you, please edit your question in order to make it more clear. – Pedro Lobito Apr 20 '15 at 06:30
  • Right now, wen user tries to close a tab I am successful in bringing browser's default confirm box where it asks the user whether to stay in that page or leave the page. Now I want to detect what option the user has selected from that confirm box and i will do any custom action like sending an ajax request based on that selection. Hope that clears your doubt – Abhinav Apr 20 '15 at 06:38
  • I think you can check the response inside a single if (or saving the functions return value in a variable) like when you use JS confirm(). On the other hand, if the user clicks leave, all scripts will stop (IMO) so technically you don't need to check anything... – Balázs Varga Apr 20 '15 at 06:50
  • Can u post a working code for that? – Abhinav Apr 20 '15 at 06:53
  • What you're trying to do is to add an `after-beforeunload` event, which is impossible. – Al.G. Apr 20 '15 at 07:32
  • 1
    possible duplicate of [Way to know if user clicked Cancel on a Javascript onbeforeunload Dialog?](http://stackoverflow.com/questions/4650692/way-to-know-if-user-clicked-cancel-on-a-javascript-onbeforeunload-dialog) – Al.G. Apr 20 '15 at 07:33
  • 1
    You may want to do ajax query synchronously. – xpereta May 06 '15 at 16:25
  • I do not see why you didn't use the .click() method? this is supported by jquery***, or even to run an ajax functions... – Fariz Luqman May 08 '15 at 06:36
  • Not enough information, do you have a fiddle of the code? – Lupin May 14 '15 at 06:42

1 Answers1

3

Well, I put forward that this is a hack and not the solution, this is just a solution.

In order to execute a piece of code (this is suitable not just for AJAX) only when the user clicks on Stay on this page you have to make it run asychronously, thus javaScript keeps running synchronous code (the return statement).

jQuery.ajax() calls must include the async: true parameter, then the code to be executed after user's click must be included in a setTimeout() function with the proper timeout (if the page takes too much time to unload the timeout must be higher)

var stayHere = ""; // this variable helps with the "stay on this page"_code cancellation when user chooses "leave this page"
window.onbeforeunload = userConfirmation;

function userConfirmation() {
    var confirmation = "Your edits will be lost";
    stayHere = setTimeout(function() { // the timeout will be cleared on "leave this page" click
        $.ajax({
            url: "ajax-call.php",
            type: "post",
            data: {chosenOpt: "stay"},
            async: true, // important
            success: function(data) { console.log(data);},
            error: function() { alert("error");}
        });
    }, 2000); // Here you must put the proper time for your application
    return confirmation;
}

How to run code if user clicks on Leave this page

If the user chooses to leave the page, then the page starts to unload and when it has completely unloaded the unload event fires, so I'll put code in its listener:

jQuery(window).on("unload", function() {
clearTimeout(stayHere); // This is another assurance that the "stay here"_code is not executed
$.ajax({
    url: "ajax-call.php",
    type: "post",
    data: { chosenOpt: "leave"},
    async: false, // If set to "true" the code will not be executed
    success: function(data) { console.log(data);},
    error: function() { console.log("Error");} // In chrome, on unload, an alert will be blocked
});

});

Note: be careful with the code that executes inside an unload handler. Since the unload event fires after everything is unloaded, none object in the page is still available.

Here is a jsfiddle to see how does it works.

The ajax-call.php contains just

echo $_POST["chosenOpt"] . "_" . rand(1, 9999);

And the output will be leave_[number] on Leave this page and stay_[number] on Stay on this page

Note: You can see leave_[number] only refreshing the page and if Preserve Log is checked in console.

Cliff Burton
  • 3,414
  • 20
  • 33
  • 47
  • This is tested and with the given "settings" (stay_on_page's ajax `async: true`, leave_the_page's ajax `async: false`, the asynchronous with `setTimeout()` function and the `clearTimeout(stayHere)` function to stop the stay_on_page's code to be executed) in about 3000 (this is not a joke) attempts in Chrome, Firefox and IE this works perfectly with no errors!! **;)** – Cliff Burton May 14 '15 at 21:38
  • You're welcome! Let me know if it fits to your request, it took me hours to develop it in the best way!! **XD** – Cliff Burton May 15 '15 at 16:21
  • 4
    Hi @IdentityUnkn0wn, I have added a [jsfiddle](https://jsfiddle.net/j96mbedh/4/) to show you how does it works, but it hasn't `AJAX`. I hope it will be of help. – Cliff Burton May 16 '15 at 19:39
  • 1
    This worked brilliantly...thts what I needed. thnx for your time and effort – Abhinav May 17 '15 at 05:11