Ovesh
Ovesh

Reputation: 5379

How can I temporarily disable click events on a button without actually disabling it?

Using jQuery, I would like to, without changing the disabled attribute of a given button, disable all click events for it.

I was thinking of retrieving the click event handlers, unbind them, and storing them (say, using data()).

Then I can re-bind them once the button is enabled again.

Upvotes: 14

Views: 40497

Answers (8)

The Alster
The Alster

Reputation: 1

You can save the events and then restore them, this seems to work (note that the _ may need to be omitted depending on the version of JQuery).

This example stops the bootstrap toggle on-change event firing, then triggers the toggle then resets the events to whatever were there previously. You can do the same with click etc.

var events;
// Save change events associated with this control
events = $._data($(this)[0], "events").change;
$._data($(this)[0], "events").change = null;

// Do your stuff here
$(this).bootstrapToggle("off");

// Reset change events
$._data($(this)[0], "events").change = events;

Upvotes: 0

David Tang
David Tang

Reputation: 93674

Not hard to do since jQuery already stores all of its event handlers as data() on the element itself. You can get (and modify) this object through .data().events.

Now you can easily save a reference to the handlers with:

 events._click = events.click;
 events.click = null;

And then restore them by using:

 events.click = events._click;
 events._click = null;

Note that this won't disable events that are bound via .delegate() or .live(), as they work by event bubbling/propagation. To disable those as well, simply bind a new handler that blocks propagation to ancestor elements:

 events._click = events.click;
 events.click = null;
 // Block .live() and .delegate()
 $("#el").click(function (e) {
     e.stopPropagation();
 });

You don't even need to unbind this blocker function when it's time to enable the handlers again, since events.click = events._click will override the function you just bound with all the old handlers.

Upvotes: 17

Adam
Adam

Reputation: 1606

All answers here are now outdated - as of jQuery 1.7 you should use .off() as explained on the official jQuery site

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>off demo</title>
  <style>
  button {
    margin: 5px;
  }
  button#theone {
    color: red;
    background: yellow;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
 
<button id="theone">Does nothing...</button>
<button id="bind">Add Click</button>
<button id="unbind">Remove Click</button>
<div style="display:none;">Click!</div>
 
<script>
function flash() {
  $( "div" ).show().fadeOut( "slow" );
}
$( "#bind" ).click(function() {
  $( "body" )
    .on( "click", "#theone", flash )
    .find( "#theone" )
      .text( "Can Click!" );
});
$( "#unbind" ).click(function() {
  $( "body" )
    .off( "click", "#theone", flash )
    .find( "#theone" )
      .text( "Does nothing..." );
});
</script>
 
</body>
</html>

Upvotes: 1

Nilesh Rahinj
Nilesh Rahinj

Reputation: 1

Instead of doing this thing Use Core Javascript to do this task e.g. Look following example.

function MakeSaveDisabled(flg) {
    if (flg != null) {
        $(".btnpost").each(function () {
            this.removeAttribute("disabled");
            if (this.hasAttribute("oclickevt")) {
                this.setAttribute("onclick", this.getAttribute("oclickevt"));
            }
        });
    }
    else {
        $(".btnpost").each(function () {
            this.setAttribute("disabled", "true");
            if (this.getAttribute("onclick") != null) {
                this.setAttribute("oclickevt", this.getAttribute("onclick"));
            }
            this.removeAttribute("onclick");
        });
    }
}

Save the javascript function in some temporary attribute and bind it when you required.

Upvotes: 0

Malcolm Dwyer
Malcolm Dwyer

Reputation: 1155

I'll expand on the answer(s) offered by Barry and Thariama... which I think will satisfy Ovesh's objections:

You can add a namespace to your event binding. That lets you refer to that specific event binding later, without colliding with other bindings. I think this is cleaner than the accepted answer... (To be fair, this may not have been available in jQuery at the time of the original question).

// A generic click handler:
$('.myButton').click(function() { ... });

// A namespaced click handler:
$('.myButton').bind('click.someSituation', function()  { ... });

// Later you can unbind only the handler you want by using the namespace:
$('.myButton').unbind('click.someSituation');

// The default click handler still works.

Upvotes: 0

Shadow Wizard
Shadow Wizard

Reputation: 66389

Here is yet another way:

$("#myButton").click(function() {
    if ($(this).attr("temp_disable") == "disabled") {
        //nothing to do, temporarily disabled...
    }
    else {
        alert("You clicked me!");
    }
});

To "disable" it for 10 seconds:

$("#myButton").attr("temp_disable", "disabled");
window.setTimeout(function() { $("#myButton").attr("temp_disable", ""); }, 10000);

Live test case: http://jsfiddle.net/yahavbr/ByM6h/

Upvotes: 4

Thariama
Thariama

Reputation: 50832

That is the way to go. If you have onclick specified as an attribute you may switch the attribute busing

 $(button_element).attr('click', '');

and

 $(button_element).attr('click', 'do_the_regular_action()');

Upvotes: 2

codingbadger
codingbadger

Reputation: 43984

You can use unbind and bind

$('#control').unbind('click');

and

$('#control').bind('click', NameOfFunctionToCall);

Upvotes: 0

Related Questions