Trying to figure out proper way to make a click event not fire on the icon of a disabled link. The problem is when you click the Icon, it triggers the click event. I need the selector to include child objects(I think) so that clicking them triggers the event whenever the link is enabled, but it needs to exclude the children when the parent is disabled.
Links get disabled attribute set dynamically AFTER page load. That's why I'm using .on
Demo here:(New link, forgot to set link to disabled)
/
<div class="container">
<div class="hero-unit">
<h1>Bootstrap jsFiddle Skeleton</h1>
<p>Fork this fiddle to test your Bootstrap stuff.</p>
<p>
<a class="btn" disabled>
<i class="icon-file"></i>
Test
</a>
</p>
</div>
</diV>
$('.btn').on('click', ':not([disabled])', function () { alert("test"); });
Update:
I feel like I'm not using .on right, because it doesn't take the $('.btn') into account, only searching child events. So I find myself doing things like $('someParentElement').on
or $('body').on
, one being more difficult to maintain because it assumes the elements appear in a certain context(someone moves the link and now the javascript breaks) and the second method I think is inefficient.
Here is a second example that works properly in both enabled/disabled scenarios, but I feel like having to first select the parent element is really bad, because the event will break if someone rearranges the page layout:
/
Trying to figure out proper way to make a click event not fire on the icon of a disabled link. The problem is when you click the Icon, it triggers the click event. I need the selector to include child objects(I think) so that clicking them triggers the event whenever the link is enabled, but it needs to exclude the children when the parent is disabled.
Links get disabled attribute set dynamically AFTER page load. That's why I'm using .on
Demo here:(New link, forgot to set link to disabled)
http://jsfiddle/f5Ytj/9/
<div class="container">
<div class="hero-unit">
<h1>Bootstrap jsFiddle Skeleton</h1>
<p>Fork this fiddle to test your Bootstrap stuff.</p>
<p>
<a class="btn" disabled>
<i class="icon-file"></i>
Test
</a>
</p>
</div>
</diV>
$('.btn').on('click', ':not([disabled])', function () { alert("test"); });
Update:
I feel like I'm not using .on right, because it doesn't take the $('.btn') into account, only searching child events. So I find myself doing things like $('someParentElement').on
or $('body').on
, one being more difficult to maintain because it assumes the elements appear in a certain context(someone moves the link and now the javascript breaks) and the second method I think is inefficient.
Here is a second example that works properly in both enabled/disabled scenarios, but I feel like having to first select the parent element is really bad, because the event will break if someone rearranges the page layout:
http://jsfiddle/f5Ytj/32/
Share Improve this question edited Nov 28, 2012 at 19:36 AaronLS asked Nov 28, 2012 at 19:17 AaronLSAaronLS 38.4k24 gold badges150 silver badges215 bronze badges 2- Why do you use event delegation here? – Bergi Commented Nov 28, 2012 at 19:28
- Because elements may bee disabled at anytime. For example, we have links/buttons which bee disabled for a few seconds when clicked. So I want the click handler to not fire while buttons/input[submit]/links are disabled. – AaronLS Commented Nov 28, 2012 at 19:31
6 Answers
Reset to default 1Don't use event delegation if you only want to listen for clicks on the .btn
element itself:
$('.btn').on('click', function() {
if (!this.hasAttribute("disabled"))
alert("test");
});
If you'd use event delegation, the button would need to be the matching element:
$(someParent).on('click', '.btn:not([disabled])', function(e) {
alert('test!!');
});
- Demo
Or use a true button
, which can really be disabled:
<button class="btn" [disabled]><span class="file-icon" /> Test</button>
- Demo, disabled.
Here, no click event will fire at all when disabled, because it's a proper form element instead of a simple anchor. Just use
$('.btn').on('click', function() {
if (!this.disabled) // check actually not needed
this.diabled = true;
var that = this;
// async action:
setTimeout(function() {
that.disabled = false;
}, 1000);
});
.on('click', ':not([disabled])'
^ This means that, since the icon is a child of the button ".btn"
, and it is not disabled, the function will execute.
Either disable the icon, also, or apply the event listener only to the <a>
tag that is your button, or use e.stopPropagation();
I would suggest using e.stopPropagation();
, this should prevent the icon from responding to the click.
That doesn't seem to work for me ^
Disabling the icon, however, does.
I would prefer to add the event using delegation here as you are trying to base the event based on the attributes of the element.
You can add a check condition to see if you want to run the code or not.
$('.container').on('click', '.btn', function() {
if( $(this).attr('disabled') !== 'disabled'){
alert('test!!');
}
});
Check Fiddle
You're not using the selector properly.
$('.btn').not('[disabled]').on('click', function () {
alert("test");
});
See it live here.
Edit:
$('.container').on('click', '.btn:not([disabled])', function () {
alert("test");
});
I think what you need is:
e.stopPropagation();
See: http://api.jquery./event.stopPropagation/
Basically something like the following should work
$('.icon-file').on('click', function(event){event.stopPropagation();});
You may want to add some logic to only stop bubbling the event when the button ist disabled.
Update:
not sure, but this selector should work:
$('.btn:disabled .icon-file')