views:

93

answers:

4

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

+4  A: 

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
Right on the money.
GaVrA
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
+2  A: 

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
Very thorough solution. +1
Ryan Kinal
+1  A: 

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
+1  A: 

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