Jackson
Jackson

Reputation: 483

Select all checkboxes by class, class increments

I have a html table that increments the class for each host, so that each host and child host have the same class like this:

+-------------+--------------+
| host        | child host   | 
+-------------+--------------+
| class=host0 | class=host0  |
+-------------+--------------+
|             | class=host0  |
+-------------+--------------+
|             | class=host0  |
+-------------+--------------+
| class=host1 | class=host1  | 
+-------------+--------------+
|             | class=host1  | 
+-------------+--------------+

Each host/child host has a checkbox.

<input class='host{$hostcount}'type='checkbox'>

I want the host checkbox to select all child hosts. The code below works for host0, how can I get this to work for any host?

$(document).ready(function() {
    $('.host0').change(function () {
        if ($(this).prop('checked')) {            
            $('.host0:checkbox').prop('checked', true);
        } else {
            $('.host0:checkbox').prop('checked', false);
        }
    });
$('#selectAllHost').trigger('change');
});

Upvotes: 1

Views: 275

Answers (3)

Dacre Denny
Dacre Denny

Reputation: 30370

Perhaps you could use the "[class^='host']" selector, to select "any element with a class name starting with 'host'".

This lets you detect when a "host" a checkbox is clicked. From there, extract the actual "host" class for that checkbox:

    var hostClass = $(this).attr('class')
    .split(' ')
    .find(className => className.indexOf('host') !== -1)

If hostClass is found for this checkbox, use that to select and toggle the corresponding "child" checkbox inputs:

$(document).ready(function() {
    
    // Select all checkbox elements from 'host-column' that start 
    // with host 
    $("[class^='host']", ".host-column").change(function () {
    	
        // Extract actual host class for this checkbox	
        var hostClass = $(this).attr('class')
        .split(' ')
        .find(className => className.indexOf('host') !== -1)
        
        if(hostClass) {
        
          // Select corresponding children checkbox elements (exclude this)
          var childCheckboxes = $('.'+ hostClass +':checkbox')
          .not($(this));
        
          if ($(this).prop('checked')) {            
              childCheckboxes.prop('checked', true);
          } else {
              childCheckboxes.prop('checked', false);
          }
        }
    });
  
    $('#selectAllHost').trigger('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<table>
<tbody>
  
<tr>
  <td>host</td>
  <td>child</td>
</tr>
<tr>
  <td class="host-column">
    <input type="checkbox" class="host0">
  </td>
  <td>
    <input type="checkbox" class="host0">
    <input type="checkbox" class="host0">
    <input type="checkbox" class="host0">
    <input type="checkbox" class="host0">
  </td>
</tr>
<tr>
  <td class="host-column">
    <input type="checkbox" class="host1">
  </td>
  <td>
    <input type="checkbox" class="host1">
    <input type="checkbox" class="host1">
    <input type="checkbox" class="host1">
    <input type="checkbox" class="host1">
  </td>
</tr>

</tbody> 

Upvotes: 1

Andy
Andy

Reputation: 63524

I would give them parent/child classes, remove the number from the class name and, instead, add in a data attribute for the number so you can target them more easily.

$(document).ready(function() {

  // change a parent checkbox
  $('.host.parent').change(function() {

    // grab the id and checked value
    const id = $(this).data('id');
    const checked = $(this).prop('checked');

    // toggle all the children with the same id
    $(`.host.child[data-id=${id}]`).prop('checked', checked ? true : false);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>0<input class="host parent" data-id="0" type="checkbox" /></td>
    <td><input class="host child" data-id="0" type="checkbox" /><input class="host child" data-id="0" type="checkbox" /></td>
  </tr>
  <tr>
    <td>1<input class="host parent" data-id="1" type="checkbox" /></td>
    <td><input class="host child" data-id="1" type="checkbox" /><input class="host child" data-id="1" type="checkbox" /></td>
  </tr>
</table>

Upvotes: 3

Taplar
Taplar

Reputation: 24965

First off, you could add an additional class and data attribute to the hosts.

<input class='host host{$hostcount}' data-target='host{$hostcount}' type='checkbox'>

The shared host class will let us generalize the event binding, and the target will tell us what we need to change.

$(document).ready(function() {
  $('.host').change(function (e) {
    var target = $(e.target).data('target');

    $('.'+ target +':checkbox').prop('checked', e.target.checked);
  });

  $('#selectAllHost').trigger('change');
});

Upvotes: 2

Related Questions