Feralheart
Feralheart

Reputation: 1920

jQuery check the parent checkbox if the child checkbox is checked

I want to make a logic that if a child checkbox is checked, it checks the parent checkbox too. The input can parent, child and both:

<input type="checkbox" name="checkbox[$counter]" class="parent" />
<input type="checkbox" name="checkbox[$counter]" class="child" />
<input type="checkbox" name="checkbox[$counter]" class="parent child" />

This structure:

will be look like this:

<table class="table">
  <tr>
    <td>
      <input type="checkbox" name="checkbox[1]" class="parent" />
    </td>
    <td>
     .
     .
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[2]" class="child" />
    </td>
    <td>
     .
     .
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[3]" class="child" />
    </td>
    <td>
     .
     .
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[4]" class="parent" />
    </td>
    <td>
     .
     .
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[5]" class="child parent" />
    </td>
    <td>
     .
     .
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[6]" class="child" />
    </td>
    <td>
     .
     .
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[7]" class="child" />
    </td>
    <td>
     .
     .
  </tr>
</table>

I want if I check 3, it checks 1 and if I check 6 it checks 5 and 4, too.

Also the checkboxes are in separate table rows, becouse I want to show some information structured in table next to the checkbox.

Can you show me a script what does it? I tried this, but it's not working:

$(document).ready(function() {
    $('input.child').change(function() {
        if ($(this).is(':checked')) {
            $(this).closest('input.parent:checkbox').attr('checked', true);
        }
    });
});

Upvotes: 0

Views: 2937

Answers (3)

Satpal
Satpal

Reputation: 133403

The checkboxes are not parent-child relationship, thus the method .closest() will not work as it traverse's up starting from itself.

I would recommend you to assign classes with TR element and also attach event handler with them, traversing DOM will be easy.

<tr class="parent">...</tr>
<tr class="child">...</tr>

You could use combination of .prevAll() and .first() to get the targeted TR, then use .find() to get the checkbox.

Additionally, If you want to fire the change event trigger() method can be used.

$(document).ready(function() {
  $('.child').on('change', ':checkbox', function() {
    if ($(this).is(':checked')) {
      var currentRow = $(this).closest('tr');
      var targetedRow = currentRow.prevAll('.parent').first();
      var targetedCheckbox = targetedRow.find(':checkbox');
      targetedCheckbox.prop('checked', true).trigger('change');
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<table class="table">
  <tr class="parent">
    <td>
      <input type="checkbox" name="checkbox[1]" />
    </td>
  </tr>
  <tr class="child">
    <td>
      <input type="checkbox" name="checkbox[2]" />
    </td>
  </tr>
  <tr class="child">
    <td>
      <input type="checkbox" name="checkbox[3]" />
    </td>
  </tr>
  <tr class="parent">
    <td>
      <input type="checkbox" name="checkbox[4]" />
    </td>
  </tr>
  <tr class="child parent">
    <td>
      <input type="checkbox" name="checkbox[5]" />
    </td>
  </tr>
  <tr class="child">
    <td>
      <input type="checkbox" name="checkbox[6]" />
    </td>
  </tr>
  <tr class="child">
    <td>
      <input type="checkbox" name="checkbox[7]" />
    </td>
  </tr>
</table>

Upvotes: 2

Pedram
Pedram

Reputation: 16575

With your current html structure you need make a link between childs and parents, for example with data attribute, now it works with any html structure, table, ul li or without these.

$(document).ready(function() {
  $('input.child').on('change', function() {
    var data = $(this).data('name');

    if (this.checked) {
      $('input.parent:checkbox[data-name="' + data + '"]').prop('checked', true);
      $('input.parent:checkbox[data-parent="' + data + '"]').prop('checked', true);
    } else {
      $('input.parent:checkbox[data-name="' + data + '"]').prop('checked', false);
      $('input.parent:checkbox[data-parent="' + data + '"]').prop('checked', false);
    }
  });
});

/* Optional, This is what I added for better look */

$('.child').each(function() {
  $(this).parent().css({
    paddingLeft: 20,
    backgroundColor: '#c0c0c0'
  });
});

$('.parent').each(function() {
  $(this).parent().css({
    backgroundColor: 'black'
  });
});
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table">
  <tr>
    <td>
      <input type="checkbox" name="checkbox[1]" class="parent" data-name="chck-1" />
    </td>
    <td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[2]" class="child" data-name="chck-1" />
    </td>
    <td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[3]" class="child" data-name="chck-1" />
    </td>
    <td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[4]" class="parent" data-name="chck-2" />
    </td>
    <td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[5]" class="child parent" data-name="chck-2" data-parent="chck-3" />
    </td>
    <td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[6]" class="child" data-name="chck-3" />
    </td>
    <td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="checkbox[7]" class="child" data-name="chck-3" />
    </td>
    <td>
  </tr>
</table>

Upvotes: 0

programtreasures
programtreasures

Reputation: 4298

Try below script,

$(document).on('change', 'input[type=checkbox]', function(e) {
  $(this).siblings('ul').find("input[type='checkbox']").prop('checked', this.checked);
  $(this).parentsUntil('input[type=checkbox]').children("input[type='checkbox']").prop('checked', this.checked);
  e.stopPropagation();
});

Upvotes: 0

Related Questions