views:

3496

answers:

7

I have a problem with the following code in an ASPX page:

<script type="text/javascript">
$(document).ready(function() {
 $('.test').click(function() {
  alert("click")
 })
});
</script>

<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />

In the browser (FF3.5 / IE8) I have the following problem:

  • if I click the checkbox (the small square), it works as expected
  • if I click the checkbox's text ("Checkbox XYZ"), then the click event is fired twice, and the alert is shown twice

I guess this has to do with the way the checkbox is rendered to HTML, which is like this:

<span class="test">
 <input id="ctl00_c1_cb1" type="checkbox" name="ctl00$c1$cb1" checked="checked" />
 <label for="ctl00_c1_cb1">Checkbox XYZ</label>
</span>

How do I correctly setup the click event handler to prevent it from being called twice?

+1  A: 

Well after reading my question again, I found a way how to solve it.

Just add "input" to the jQuery selector:

<script type="text/javascript">
$(document).ready(function() {
        $('.test input').click(function() {
                alert("click")
        })
});
</script>

I'm not sure if this is the recommended/correct way.

M4N
@Martin - I think it's because a label with a `for` attrbute raises the click event of the element that is attached to. So in your jQuery code, you set up a click event handler for both the label and the input. when clicking on the label, the click event handler that you set up on the label will execute, then the click event handler set up on the input will execute when the label raises the click event.
Russ Cam
Thanks Russ, that makes sense. I would have upvoted if you had created an answer.
M4N
A: 

What you are seeing is event bubbling. The click event is first handled by the label and is then passed on to the checkbox. You get one alert for each. To prevent event bubbling you need to return false in your click handler.

$(document).ready(function() {
        $('.test').click(function() {
                alert("Click");
       return false;
        })
});

However while this prevents event bubbling it also has the undesirable side effect of preventing the checkbox from changing state. So you'll need to code around that.

Andrew
+4  A: 

I think it's because a <label> with a for attribute raises the click event of <input type="radio"> or <input type="checkbox"> element that is associated for when clicked.

So in your jQuery code, you set up a click event handler for both the <label> and the <input> inside <span class="test">. When clicking on the <label>, the click event handler that you set up on the label will execute, then the click event handler set up on the <input> will execute when the label raises the click event on the <input>.

Russ Cam
you can see this if you change `alert("click");` to `alert(e.target.tagName);` - first you see `LABEL` then `INPUT`, indicating that the label first raises a click event, then checks/unchecks the associated checkbox, causing the input to raise a click event.
Russ Cam
+1  A: 
$(document).ready(function() {
    $('.test').click(function(event) {
                    event.stopImmediatePropagation();
                    alert("Click");
                    })
                 }
              );

I was able to get my code working by stopping the event Propagation. It did not affect the status change of the checkbox.

Juma
Unfortunately this doesn't work for me (tested in IE8). When I click the label/text associated with the checkbox, the alert is still shown twice.
M4N
+3  A: 

I have just experienced the same thing, but am not sure that event bubbling is causing my issue. I have a custom tree control, and when an item is opened, I use $(id).click() to attach a handler to all elements of a certain kind. I suspect that this means that existing items elsewhere, that already have the event, may then have it added again. I found that unbinding everything then re-binding solved my problem, thus:

$('img.load_expand').unbind("click").click(function()
{
  // handler
}

Hope that helps someone :o)

halfer
A: 

No solution work for me here. And I really frustrated to find the solution. The same explanation found here.

http://praveenbattula.blogspot.com/2010/02/aspnet-checkbox-click-on-label-calling.html

Rare Solutions
A: 

The unbind result worked for me. Note the .click() was in a usercontrol

marsahll