Fix for ASP.NET Checkbox -jQuery click event getting fired twice issue

This is really interesting. If ASP.NET checkboxes or checkbox list is placed within any container element like div or span, and click event is attached on checkbox. And then clicking on checkbox text will call click event twice. For example, consider the following HTML/ASP.NET code.

<div id="dvList">
<asp:CheckBox ID="chk1" runat="server" Text="Check1" CssClass="Dummy" /> 
<asp:CheckBox ID="chk2" runat="server" Text="Check2" CssClass="Dummy" /> 
</div>

Now using jQuery, bind click event to all the checkboxes which are child element of div element with ID "dvList".

$(document).ready(function(){
   $('#dvList').find('.Dummy').on('click',function(){
      alert('Test');
   });
});

If checkbox is clicked, then alert will come only once. But if click is made on text associate with checkbox, then alert will be displayed twice.

Surprise!!! This is happening due to event bubbling. Before moving to event bubbling it is important to understand how checkbox is rendered in browser. A single ASP.NET checkbox,

<asp:CheckBox ID="chk1" runat="server" Text="Check1" CssClass="Dummy" /> 

is rendered in browser like,

<span class="Dummy">
   <input id="chk1" type="checkbox" name="chk1" />
   <label for="chk1">Check1 </label>
</span>

In above jQuery code, though we have setup click event handler for elements with class "Dummy" only but all the child elements also get wired to click event. We have set up a click event handler for both the <label> and the <input> and <span class="Dummy"> elements. So clicking on the <label>, the click event handler that on the label will execute, and then the click event handler set up on the <input> will execute as the label raises the click event on the <input> as well. This is exactly what event bubbling is.

To stop event bubbling, jQuery provides a method "stopPropagation()". See below jQuery code.

$(document).ready(function () {
   $('#dvList').find('.Dummy').on('click', function (evt) {
     alert('Test');
     evt.stopPropagation();
     evt.preventDefault();
  });
});

With this code, you will see alert appearing only once when you click on text but you will find that checkbox status is not getting updated. Which is due to

So, now what is the solution. Well, the solution is to first identify the element which was clicked. Whether its <label> or <span>. If its <label> or <span> then the click event will be fired twice. As explained earlier, click event first gets fired for the <label> or <span> and second time for <input>. So for the first trigger, we should simply ignore the click event by checking event target. And for next trigger, the source will be <input> so alert is fired.

$(document).ready(function(){
   $('#dvList').find('.Dummy').on('click',function(evt){
      var target = evt.target.tagName.toUpperCase();
      if (target === "LABEL" || target === "SPAN") { 
         return;
      }
      alert('Test');
   });
});

Feel free to contact me for any help related to jQuery, I will gladly help you.



Responsive Menu
Add more content here...