1

I have a click that triggers payment. I'm using the .One method to disallow further clicking, but in case the payment comes back declined I'd like to re-enable the click for another try - one time again of course. And let this re-occur in case of another decline.

    $(".pay").one("click", function(event){ 

        ...//payment code executes

      });

Ajax

$.ajax({
   ...
    success: function(data){
        $('.pay').html(data); //comes back declined. Re-enable .one click again.
    }
obreezy
  • 303
  • 1
  • 5
  • 18
  • [Looking through the documentation](http://api.jquery.com/one/) it says that `jquery.one('click'...)` would be the same as `jquery.on('click', function(e){... $(this).off(e)} `, which may give you a starting point – Jhecht Nov 21 '16 at 01:24

5 Answers5

2

I would say, the best way is to:

  • Add a class.
  • Check if the class is present, then don't execute.
  • Fire the AJAX call.
  • Remove the class.

This is how disabling works.

This is better to use:

.addClass();
.removeClass();

Than writing entire function again and again, duplicating the code.


Update: If DOM manipulation is harder, or costlier, it is better to store the context sensitive values as a key-value pair using $.data(element, key, value); method and set the flag for execution.

Thanks to the Soviut and adeneo for their comments. :D


Example

added as per request...

$(".pay").on("click", function (event) {
  if ($(this).hasClass("stop"))
    return false;
  $(this).addClass("stop");
  // Other codes to follow.
});

$.ajax({
  //...
  success: function (data) {
    $('.pay').html(data)           //comes back declined. Re-enable .one click again.
             .removeClass("stop"); // remove the class that disables.
  }
});
Community
  • 1
  • 1
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
1

One way is to define the event again in the ajax success

$.ajax({
   ...
    success: function(data){
        $('.pay').html(data); //comes back declined. Re-enable .one click again.
        $(".pay").one("click", function(event){ 
        ...//payment code executes
        });
    }
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Jorge Londoño
  • 588
  • 2
  • 14
1

Delegate the function explicitly instead of using closure.

var triggerPayment = function (evt) {
    ... //payment code executes
}

$(".pay").one("click", triggerPayment);

$.ajax({
   ...
    success: function(data){
        if (isDeclined(data)) {
            $(".pay").one("click", triggerPayment);
        }
    }
});
choz
  • 17,242
  • 4
  • 53
  • 73
0

Newer versions of JQuery $.ajax() return promises, allowing you to easily perform a final step if the ajax call succceeds or fails.

var jqxhr = $.ajax("example.php")
  .done(function() {
    console.log("success");
  })
  .fail(function() {
    console.log("error");
  })
  .always(function() {
    console.log("complete");

    // re-apply click event
    $(".pay").one("click", function(event) { 
    });
  });
Soviut
  • 88,194
  • 49
  • 192
  • 260
0

//Let's say you have your button like this:

<!--Button 1-->
<button type='submit' class='pay pay-button'>Pay Now</button>

//Create a similar button, for example..

<!--Button 2-->
<button type='button' class='wait pay-button' style='display: none'>Pay Now</button>

$(".pay").on("click", function(e) {
    $(".pay-button").hide(); //Hides the two buttons
    $(".wait").show(); //Shows the dummy button

    return false;
});


//The Ajax request:
var jqxhr = $.ajax("example.php")
  .done(function() {
    allow_click = false;
  })
  .fail(function() {
      $(".pay-button").hide(); //Hides the two buttons
    $(".pay").show(); //Shows the dummy button
    console.log("error");   
  });

I hope this works for you.

Popsyjunior
  • 185
  • 10