1

I am trying to combine parameters from PHP and JS. I looked thru internet and went thru the answers of simular questions in this forum. But still I did not get an elegant solution.

The "(de)select all checkboxes" function from JS selected all checkboxes from the page and not the ones belonging to a single groupname. To solve that I used different ID='' for each groupname.

Dont get me wrong. But the code below WORKS! And it does what it has to do, but it is, by my opinion, not the best way to do it. Has anyone a more elegant, and maybe faster, solution?

The PHP code:

   echo("<div id='MainMenu'><div class='list-group panel'>");
   $iRow = 1;
   foreach($aAllClasses as $aClassName){
     $sGroupname = str_replace('.', '_', $aClassName[0]);
       echo("<a href='#class".$iRow."' class='list-group-item list-group-item-success' data-toggle='collapse' data-parent='#MainMenu'>".$aClassName[0]."<i class='fa fa-caret-down'></i></a>
             <div class='collapse' id='class".$iRow."'>");
               $aClassStudents = $this->fetchClassStudents($aClassName[0]);                                        
               echo("<input type='checkbox' id='checkUncheckAll".$sGroupname."' onClick='CheckUncheckAll".$sGroupname."()'><b> De gehele groep.</b><br>");
               foreach($aClassStudents as $aStudentRecord){
                  echo("<input type='checkbox' class='selectable".$sGroupname."' value='T' name='student".$aStudentRecord['id']."'> ".$aStudentRecord['sStudentSurname'].", ".$aStudentRecord['sStudentFirstname']." ".$aStudentRecord['sStudentInsertion']." (".$aStudentRecord['iStudentNumber'].")<br>");
               }                                        
               echo("</div>");
               $iRow++;
    }
    echo("</div></div>");

The JS script looks horrible:

<?php
$aAllClasses = $oDBactions->fetchAllClasses($eUserIP);                         
?>
<script>
<?php
foreach($aAllClasses as $aClassName){
    $sGroupname = str_replace('.', '_', $aClassName[0]);
    ?>            
        function CheckUncheckAll<?php echo($sGroupname); ?>(){
            var  selectAllCheckbox=document.getElementById("checkUncheckAll<?php echo($sGroupname); ?>");
            if(selectAllCheckbox.checked==true){
             var checkboxes =  document.getElementsByClassName("selectable<?php echo($sGroupname); ?>");
              for(var i=0, n=checkboxes.length;i<n;i++) {
               checkboxes[i].checked = true;       
              }
             }else {
              var checkboxes =  document.getElementsByClassName("selectable<?php echo($sGroupname); ?>");
              for(var i=0, n=checkboxes.length;i<n;i++) {
               checkboxes[i].checked = false;
              }
            }
        }            
<?php } ?>
</script>

1 Answer 1

1

The more elegant way to do this would be to use use common classes on all the repeated HTML. This way you can remove the unnecessary incremental id attributes, which cause more problems than they solve, and use the same JS for all elements.

All the JS then needs to do is to find all checkboxes related to the 'toggle all', using DOM traversal instead of static selectors, and then set the checked state to match, like this:

$('.checkUncheckAll').on('change', function() {
  $(this).closest('div').find(':checkbox').not(this).prop('checked', this.checked);
});
label { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="MainMenu">
  <div class="list-group panel">
    <a href="#class1" class="list-group-item list-group-item-success" data-toggle="collapse" data-parent="#MainMenu">
      Classname 1
      <i class="fa fa-caret-down"></i>
    </a>
    <div class="collapse">
      <label><input type="checkbox" class="checkUncheckAll"><b> De gehele groep.</b><br>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 1</label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 2</label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 3</label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 4</label>
    </div>
  </div>
  <div class="list-group panel">
    <a href="#class2" class="list-group-item list-group-item-success" data-toggle="collapse" data-parent="#MainMenu">
      Classname 2
      <i class="fa fa-caret-down"></i>
    </a>
    <div class="collapse">
      <label><input type="checkbox" class="checkUncheckAll"><b> De gehele groep.</b></label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 1</label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 2</label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 3</label>
      <label><input type="checkbox" class="selectable" value="T" name="student[]"> Surname, Firstname 4</label>
    </div>
  </div>
</div>

Note that I wrapped the checkboxes in label elements to make the hit areas bigger; you can now select the box by clicking the text next to it.

Sign up to request clarification or add additional context in comments.

1 Comment

Rory, great! Its clear that I realy do not know enough about JS and Jquery. Thank you for the help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.