JQuery: Chaining not working as expected

I have a "chain" of checkboxes (parent checkbox and children) and the problem is this:

The first click on the "parent" checkbox works well, but after that, when the "childs" is clicked, the "parent" checkbox does not do what it is supposed to do. The parent checks / unchecks children, except for the child that was clicked earlier.

Here is the code:

JavaScript

checks_bind();
function checks_bind(){
  $("#x_main").off('click');
  $("#x_main").on('click',function(){
  var obj   = $(this);
    var val = obj.is(':checked');
    $("#checks").find("input[type='checkbox']").attr('checked',val);
  });
}

      

Html

<input id='x_main' type='checkbox'/>Main<br>
<p>--------------------------------</p>
<div id='checks'>
<input type='checkbox'/>1<br>
<input type='checkbox'/>2<br>
</div>
<p>--------------------------------</p>
<i>1 - Click on 1 or 2 <br>2 - Try <b>Main</b> checkbox. <br>
3 - Main checkbox isn't working</i>

      

jsfiddle example

And one more question:

Is it good to use .on('click.namespace')

on checkboxes since it works well? I can use the method .change()

, but I want to call .off('click.namespace')

(or something to unbind) before .on()

every time I call the function.

+3


source to share


3 answers


Since it checked

is a property, you need to use .prop()

instead.attr()

$("#checks").find("input[type='checkbox']").prop('checked', val);

      



Updated script , good read .prop () vs .attr ()

If you want to use .off()

then it makes sense to use the named event.

+3


source


Try this: custom 'prop' instead of attribute and you can check all or uncheck all according to the condition of the main checkbox. Alternatively, you can check the "Count of All" checkbox to check / uncheck the box. see below

Note: bind a click handler when the DOM is ready, so the user $(document).ready

or$(function(){})



$(function(){
    $("#x_main").on("change", function(){
    $("#checks").find("input[type='checkbox']").prop("checked",$(this).is(":checked"));
  });

  $("#checks input[type='checkbox']").on("change", function(){
      var total = $("#checks").find("input[type='checkbox']").length;
      var checked = $("#checks").find("input[type='checkbox']:checked").length;
      $("#x_main").prop("checked",total==checked);
  });
});

      

JSFiddle Demo

0


source


checked

The value of the attribute property <input>

and checked

are two different things. They should probably be linked / linked, but they are not. To change a property, you either access the element DOM

( $(...)[0].checked

):

$("#x_main").on('click',function(){
  var checked = $(this).is(':checked');
  $("input[type='checkbox']", $("#checks")).each(function(){
    $(this)[0].checked = checked;
  })
})

      

... or, use jQuery prop () :

$('#x_main').on('click', function(){
   $('input[type="checkbox"]', $('#checks'))
      .prop('checked', $(this).is(':checked'))
})

      

0


source







All Articles