7

I am dealing with a legacy application where they use [a] tags for many Ajax form "submits". If we were using [input] buttons we could just set the disable attribute of the [input] tag. But on hyperlinks disable is not part of the spec and is not consistent cross-browser.

We are looking for a simple solution for blocking the extra clicks on a hyperlink.

Note: we are using JavaScript with jQuery

BuddyJoe
  • 69,735
  • 114
  • 291
  • 466
  • 1
    This worked for me.http://stackoverflow.com/questions/16777003/what-is-the-easiest-way-to-disable-enable-buttons-and-links-jquery-bootstrap – radztech Jan 23 '14 at 23:21
  • radztech, cool method for doing that. thanks for the heads up – BuddyJoe Jan 29 '14 at 15:42

6 Answers6

7

womp's solution is a very very thorough way to go about this.

However, if you want something a little simpler, I would probably implement a semaphore. Simply set a "submitting" flag, and test to see if the semaphore is set when the user clicks the link. You can do this by setting the flag on the DOM object itself, or use a global boolean.

$('#link').each(function() {
    this.submitting = false;
}).click(function() {
    if (!this.submitting)
    {
        this.submitting = true;
        var self = this;
        $.ajax({
             success: function() {
                 self.submitting = false;
             },
             error:  function() {
                 self.submitting = false; // make sure they can try again
             }
        });
    }
});

I've obviously shortened the $.ajax call, but I think you get the point.

Edit: Er... actually, forgot the most important part. The if (!submitting).

Ryan Kinal
  • 17,414
  • 6
  • 46
  • 63
  • 2
    Since you always set the `self.submitting` status in the response you could simplify the callback hook to: `$.ajax({ complete: function() { self.submitting = false; } });` – matsev Nov 22 '11 at 13:46
  • This will not work if the second click appears between lines `if (!this.submitting)` and `this.submitting = true;`. This is a classical example of how not to implement semaphore ;-) – Steves Jun 20 '13 at 11:06
  • @Steves that is impossible under the JS execution model. Did you mistake this thread for Java? :P – Esailija Jun 20 '13 at 13:16
  • This was a life-saver. My jQuery-UJS forms kept submitting doubly for no reason and now it doesn't :-) – Sprachprofi Dec 09 '13 at 20:23
4

In your "click" handler either return false or prevent default -

$('#target').click(function(e) {
  e.preventDefault();
  alert('Handler for .click() called.');
});

$('#target').click(function(e) {
  alert('Handler for .click() called.');
  return false;
});

Hmm... to only allow the button to be pressed once (throughout the life of the page) then maybe utilize .data() -

http://api.jquery.com/data/

Or toggle an attribute.

Kris Krause
  • 7,304
  • 2
  • 23
  • 26
  • 3
    This will prevent the default action for the link, yes. However, I think tyndall wants to prevent further AJAX calls, in which case, I don't believe this will work. – Ryan Kinal Jul 06 '10 at 16:56
3

I like Ben Nadel's routine for handling this.

Essentially you create a wrapper around the jQuery .ajax function, and you can build in all kinds of things that happen for every ajax request in your application. One of those things is request tracking.

You'll see that in his getJSON wrapper method, it takes an optional "name" parameter for the request name. This can be anything, it's just a key to identify where the request originated from. In your case, it would be supplied by each link click. If the name parameter exists, then he stores it in a tracking collection.

If another call comes in with the same request name, it is simply dropped. Once the original request returns, he clears the tracking flag for that request name.

This method is great for extending a lot of common functionality to all ajax requests in your application. I've created a multiple request handler that also allows you to specify the behaviour of new requests - whether it would abort any existing ones or just be dropped. This is useful when you want the latest request to be processed, like for autocompletes.

womp
  • 115,835
  • 26
  • 236
  • 269
1

What happens when this links does it do an ajax request? If so you could look at this

http://www.protofunc.com/scripts/jquery/ajaxManager3/ (not their is 3.05 version in the repository you might want to take).

This has an option to stop duplicate ajax requests.

Also you can look at

http://jquery.malsup.com/block/

They click on the link and a loading sign comes up and they can no longer click on that link.

chobo2
  • 83,322
  • 195
  • 530
  • 832
1

For all events that trigger ajax call, It's a good practize to add a loading layer on the parent component or on all the page at the first hand to prevent new event trigger and at the other hand to inform user that a loading data is in progress. You can do this by using jQuery BlockUI Plugin for example which is very simple to implement

Salim Hamidi
  • 20,731
  • 1
  • 26
  • 31
0
var fooObj = {
    isAdd : true,
    add : function(){
        if(fooObj.isAdd == true){
            fooObj.isAdd = false;
            var opt = {
                url : 'http://yoururl.com',
                type : 'post',
                success : function(response){
                    if(response=='save'){
                        fooObj.isAdd = true;
                    }
                }
            }
            $.ajax(opt);    
        }
    }
}

I think this is working. I notice also IE Browser response slowly when using ajax.

adietan63
  • 125
  • 5
  • Please use the Ctrl+K option to format your code rather than HTML, it's much easier to read (and for you to format). – DaveShaw Mar 19 '12 at 21:29