-2

I have found a small code that I would really need to update or improve a bit and I can't figure it out so here it is

<tr><td><input type="checkbox" name="progress" id="progress1" value="1" tabIndex="1" 
onClick="ckChange(this)">01</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress2" value="1" tabIndex="1" 
onClick="ckChange(this)">02</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress3" value="1" tabIndex="1" 
onClick="ckChange(this)">03</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress4" value="1" tabIndex="1" 
onClick="ckChange(this)">04</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress5" value="1" tabIndex="1" 
onClick="ckChange(this)">05</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress6" value="1" tabIndex="1" 
onClick="ckChange(this)">06</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress7" value="1" tabIndex="1" 
onClick="ckChange(this)">07</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress8" value="1" tabIndex="1" 
onClick="ckChange(this)">08</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress9" value="1" tabIndex="1" 
onClick="ckChange(this)">09</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress10" value="1" tabIndex="1" 
onClick="ckChange(this)">10</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress11" value="1" tabIndex="1" 
onClick="ckChange(this)">11</td></tr>
<tr><td><input type="checkbox" name="progress" id="progress12" value="1" tabIndex="1" 
onClick="ckChange(this)">12</td></tr>

<script>
function ckChange(ckType){
var ckName = document.getElementsByName(ckType.name);
var checked = document.getElementById(ckType.id);

if (checked.checked) {
  for(var i=0; i < ckName.length; i++){

      if(!ckName[i].checked){
          ckName[i].disabled = true;
      }else{
          ckName[i].disabled = false;
      }
  } 
}
else {
  for(var i=0; i < ckName.length; i++){
    ckName[i].disabled = false;
  } 
}    
}
</script>

You can check it and see what it does, but simply put it shows 12 checkboxes and when I mark one of them the rest will be disabled. What I need is that that, no matter how many checkboxes there are, when I check 6 of them (not only one) then the rest will be disabled. I have to improve or update it more, but for now let's not take much of your time.

Patrick Q
  • 6,373
  • 2
  • 25
  • 34
  • 1
    I'm voting to close this question as off-topic because it is asking to clean up code. – vonbrand Feb 20 '20 at 21:32
  • You are expected to show some effort and make an attempt to achieve your desired result. If you do, and have a specific error/problem, you should post your attempted code along with the expected result, actual result, and what debugging you have already done. – Patrick Q Feb 20 '20 at 21:36
  • thank you for your help – Michael Constantine Feb 20 '20 at 21:39

2 Answers2

0

Do all your event handling in JavaScript, not with HTML event attributes.

Next, don't use getElementsByName(), instead use querySelectorAll().

Also, there's no need for ids on the checkboxes or tabindex as long as you're ok with the default tabbing.

For the rest, see the comments inline below:

<table>
  <tr><td><input type="checkbox" name="progress" value="1">01</td></tr>
  <tr><td><input type="checkbox" name="progress" value="2">02</td></tr>
  <tr><td><input type="checkbox" name="progress" value="3">03</td></tr>
  <tr><td><input type="checkbox" name="progress" value="4">04</td></tr>
  <tr><td><input type="checkbox" name="progress" value="5">05</td></tr>
  <tr><td><input type="checkbox" name="progress" value="6">06</td></tr>
  <tr><td><input type="checkbox" name="progress" value="7">07</td></tr>
  <tr><td><input type="checkbox" name="progress" value="8">08</td></tr>
  <tr><td><input type="checkbox" name="progress" value="9">09</td></tr>
  <tr><td><input type="checkbox" name="progress" value="10">10</td></tr>
  <tr><td><input type="checkbox" name="progress" value="11">11</td></tr>
  <tr><td><input type="checkbox" name="progress" value="12">12</td></tr>
</table>

<script>
  // Do you event handling in JavaScript, not with HTML event attributes.
  
  // Just set up a click event handler on the table and let the clicks
  // from the checkboxes bubble up to the table to be handled there.
  document.querySelector("table").addEventListener("click", ckChange);
  
  // Get a reference to all the checkboxes
  let boxes = document.querySelectorAll("table input[type='checkbox']");
 
  function ckChange(event){
    // Determine if it was a checkbox that got clicked
    if(event.target.type = "checkbox"){
      // Get the count of all the checked checkboxes
      let checkedCount = document.querySelectorAll("table input[type='checkbox']:checked").length;
      
      // If the count is 6 or more disable all of them
      if(checkedCount >=6){
        // Loop over all the checkboxes
        boxes.forEach(function(box){
          box.disabled = true;  // Disable the box
        });
      }
    }
  }
</script>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
0

I would just skip all the event listeners and use on change event on the table. I would use querySelectorAll to count and get the unchecked checkboxes. This solution allows the user to go back and make changes to their selections.

// grab parent that contains all of the checkboxes
let tbody = document.querySelector("#progressTable tbody")
// store state so we do not waste time removing disabled
let isDisabled

// bind just one event listener, use event delegation 
tbody.addEventListener('change', function() {
  // select the checked checkboxes and get the count
  const checkedCount = document.querySelectorAll('[name="progress"]:checked').length
  // see if we are maxed out
  const isMaxed = checkedCount >= 6
  // if we are maxed out ot they unchecked a checkbox
  if (isMaxed || isDisabled) {
    // set flag based on maxed out (true) or they removed one 
    // so we are no longer maxed out
    isDisabled = isMaxed
    // grab all the unchecked checkboxes
    const unchecked = document.querySelectorAll('[name="progress"]:not(:checked)')
    // loop over and either disable or enable it
    unchecked.forEach( function (cb) {
      cb.disabled = isDisabled
    })  
  }
})
<table id="progressTable">
  <tbody>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
    <tr><td><input type="checkbox" name="progress" /></td></tr>
  </tbody>
</table>
epascarello
  • 204,599
  • 20
  • 195
  • 236