Search code examples
javascriptcheckboxforeach

How to uncheck all checkboxes with a single click?


I made this in JavaScript for selecting checkboxes using the SHIFT key. Now I want to deselect it by a single click.

HTML:

<div class="inbox">
      <div class="item">
        <input type="checkbox" />
        <p>This is an inbox layout.</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Check one item</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Hold down your Shift key</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Check a lower item</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Everything in between should also be set to checked</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Try do it without any libraries</p>
      </div>
    </div>

JavaScript to select the checkbox:

 const checkboxes = document.querySelectorAll(
        '.inbox input[type="checkbox"]'
      );

      let lastChecked;

      function handleCheck(e) {
        //for selecting the checkboxes
        let inBetween = false;
        // Check if they had the shift key down
        // AND check that they are checking it

        if (e.shiftKey && this.checked) {
          // go ahead and do what we please
          // loop over every single checkbox
          checkboxes.forEach(checkbox => {
            console.log(checkbox);
            if (checkbox === this || checkbox === lastChecked) {
              inBetween = !inBetween;
              console.log('Starting to check them in between!');
            }

            if (inBetween) {
              checkbox.checked = true;
            }
          });
        }

        lastChecked = this;
      }

      checkboxes.forEach(checkbox =>
        checkbox.addEventListener('click', handleCheck)
      );

I want after selecting with SHIFT key, when I click on a selected checkbox the selected checkboxes which comes after that to be unchecked with a single click.


Solution

  • With a couple changes to your code, this should accomplish unchecking as well as checking. It will stop at the lastChecked (or unchecked) as in your original example, I assumed that's the behavior you wanted.

    const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');
    
    let lastChecked;
    
    function handleCheck(e) {
        //for selecting the checkboxes
        let inBetween = false;
        // Check if they had the shift key down
        // AND check that they are checking it
    
        if (e.shiftKey/* && this.checked */) { // ignore current checked state
            // go ahead and do what we please
            // loop over every single checkbox
            checkboxes.forEach((checkbox) => {
                console.log(checkbox);
                if (checkbox === this || checkbox === lastChecked) {
                    inBetween = !inBetween;
                    console.log("Starting to check them in between!");
                }
    
                if (inBetween) {
                    checkbox.checked = this.checked; // handles both checked/unchecked
                }
            });
        }
    
        lastChecked = this;
    }
    
    checkboxes.forEach((checkbox) =>
        checkbox.addEventListener("click", handleCheck)
    );