jqueryevent-handlingjquery-eventsjquery-click-event

jQuery click action does not trigger onclick attribute


I am having problems getting a function that clicks all search matched checkboxes. The click event seems to fire, but no checkbox gets checked nor is myFunc() called.

It works perfectly when clicking each checkbox manually, but who wants to do that with 40+ checkboxes - not my users.
You may wonder why I use a div-onclick instead of directly on the input checkbox. That is because I want give my users a larger area to click on than a small checkbox.

I want to provide my users with a single hyperlink to select multiple checkboxes that match certain attribute value(s).

HTML

<div id="container">
<a href="#" onclick="clickAndCheckAllMatch('search for this text');return false;">some text</a>
<div id="*actual_ID*" onclick="myFunc(a, b, c, d);">
  <input type="checkbox" id="book-*actual_ID*" onclick="this.parentNode.click;return false;">
</div>
</div>

JS

function myFunc(a, b, c, d) {
  // does stuff
}
function clickAndCheckAllMatch(value) {
  $('div[onclick*='+value+']').each(function(idx,e){
  $('book-'+this.id).click();
}

EDIT
When I changed from div to label then I didnt have to correct the checkbox state. A div or block-element must have some issue there.
I also removed the onclick from the divs, which meant I was able to target the checkboxes directly and could change their ID values to just the actual_ID.

function clickAndCheckAllMatch(value) {
  $('input[onclick*='+value+']').each(function(idx,e){
    // e == this
    $(this)[0].click();
    if ($(this).attr('disabled')) {
      //do nothing
    } else {
      if ($(this).attr('checked')) {
        //do nothing
      } else {
        $(this)[0].click(); // only one checkbox per ID
      }
    }
  });
}
function CheckAll() {
  $('#container input[type=checkbox]:not(:checked)').each(function(idx,e){
    $(this).click(); // notice the difference ?
  });
}

Solution

  • Rather than trying to use the event to change the value of the checkbox, I would do two things:

    1. To give the users a large area to click, use a label element, not a div. label elements are directly supported by browsers, you don't have to do anything to make them work. There are two ways to use them:

      <label><input type='checkbox'>Foo</label>
      

      or

      <input type='checkbox' id='chk1'><label for='chk1'>Foo</label>
      

      The former is nice because you don't have to use IDs (which have to be totally unique on the page, so it starts getting to be a pain); the latter is nice for markup situations where you can't have the input be a child of the label for whatever reason.

    2. If you need to change the state in code, change the state directly rather than by trying to trigger an event. For instance, if I want to change the state of the checkbox chk1, I just do this:

      $('#chk1').attr("checked", true); // or false, of course
      

      ...or to clear all of the checkboxes in a container (useful for those "all" or "none" links):

      $('#container input[type=checkbox]').attr("checked", false); // or true, of course