0

For each record in my <table> I have a checkbox. When this checkbox is clicked, an ID value is sent to an array for the record that is checked:

function setIds(){
var recordIds = []; //array to store IDs
$(".row-check").change(function(e){
    var checkedRecord = dataTable.getRecord(e.currentTarget.id); //gets ID of record object
    var id = checkedRecord.toJSON().id;
    if(this.checked){
        recordIds.push(id);
    } else { // Return array record ID that was unchecked
        recordIds.splice( $.inArray(id, recordIds), 1 );
    }
    console.log(recordIds); 
});
}

I also have a checkbox in my table header that checks all the records on the table:

function selectAll(){
   $('input[name="all"]').click(function () {
       $('input[name="row-check"]').prop('checked', this.checked);
   });
}

Here's how the table looks (cuz I like to doodle) enter image description here

However the .change() function does not pick up the records selected when I select the "select all" checkbox. I've tried placing the .row-check .change() method within my selectAll function, but no luck. How can I send all my IDs to an array when the "select all" checkbox is checked?

Clay Banks
  • 4,483
  • 15
  • 71
  • 143

1 Answers1

2

The easiest solution would be to trigger the change event on the changed-inputs, inside of the selectAll() funcition, which will then be caught – and handled – by the change listener function setIds():

function selectAll(){
   $('input[name="all"]').click(function () {

       // using the change() method - with no arguments - to fire
       // the change event, which is caught - and handled - by the
       // named change event-handler function:
       $('input[name="row-check"]').prop('checked', this.checked).change();
   });
}

A simple proof-of-concept of how the above code might work in practice (albeit in a reduced-functionality demonstration):

// caching the 'child' inputs:
var childInputs = $('input[type=checkbox].childInput');

// a simple change-handler function to demonstrate:
function changeHandler() {
  $(this).closest('li').toggleClass('checked', this.checked);
}

// binding the change-handler function to the childInputs:
childInputs.on('change', changeHandler);

// binding an anonymous 'check-all' function to the 'all'/'parent' checkbox:
$('input[name=all]').on('change', function() {
  
  // setting the checked property of each of the childInput elements
  // equal to the changed 'parent' checked-state, and
  // firing the 'change' event on each of those childInputs
  // to allow their change-handler to process/deal with the event:
  childInputs.prop('checked', this.checked).change();
});
li {
  border: 2px solid transparent;
  margin-bottom: 0.2em;
}
.checked {
  border-color: limegreen
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>
    <input type="checkbox" name="all">
    <label for="">All</label>
    <ul>
      <li>
        <label>
          <input type="checkbox" value="input1" class="childInput">input 1</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input2" class="childInput">input 2</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input3" class="childInput">input 3</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input4" class="childInput">input 4</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input5" class="childInput">input 5</label>
      </li>
    </ul>
  </li>
</ul>

And a proof-of-concept of how checking, or un-checking, all the 'child' <input> elements might serve to appropriately check, or un-check, the 'check-all' <input>:

var childInputs = $('input[type=checkbox].childInput');

function changeHandler() {
  $(this).closest('li').toggleClass('checked', this.checked);

  // finding out whether the number of childInputs is equal to the nummber
  // of checked childInputs; if it is the assessment returns true (if not
  // it returns false):
  var check = childInputs.length == childInputs.filter(':checked').length;
  
  // here we set the checked property of the 'all' checkbox to be equal to
  // the Boolean (true/false) value of the 'check' variable. Note that because
  // we're inside of the changeHandler function we do not want to trigger the
  // change event of the 'all' checkbox, which would then iterate over all
  // the childInputs and fire their change-handler again which would then
  // refire the 'change' event on 'all' checkbox (again and again and again...):
  $('input[name=all]').prop('checked', check);
}

childInputs.on('change', changeHandler);

$('input[name=all]').on('change', function() {
  childInputs.prop('checked', this.checked).change();
});
li {
  border: 2px solid transparent;
  margin-bottom: 0.2em;
}
.checked {
  border-color: limegreen
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>
    <input type="checkbox" name="all">
    <label for="">All</label>
    <ul>
      <li>
        <label>
          <input type="checkbox" value="input1" class="childInput">input 1</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input2" class="childInput">input 2</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input3" class="childInput">input 3</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input4" class="childInput">input 4</label>
      </li>
      <li>
        <label>
          <input type="checkbox" value="input5" class="childInput">input 5</label>
      </li>
    </ul>
  </li>
</ul>

Simplified proof-of-concept external JS Fiddle demo for experimentation and development.

References

David Thomas
  • 249,100
  • 51
  • 377
  • 410