skip to Main Content

I have a working code logic that triggers the alert('hello') function when a radio button, under a dynamically added class .show, is checked. Here’s the current code:

HTML:

<div class="collapse question-group show">
  <div class="progress">...</div>
  <div class="question">
    <div class="form-check">
      <input type="radio" />
      <label>yes</label>
    </div>
  </div>
</div>

JavaScript:

document.querySelectorAll(".question-group").forEach((showEl) => {
  showEl.addEventListener("change", (event) => {
    const target = event.target;
    if (
      target.closest(".question-group")?.classList.contains("show") &&
      target.tagName === "INPUT" &&
      target.type === "radio" &&
      target.checked
    ) {
      alert("Hello");
    }
  });
});

The current code works as expected. However, I have added more radio buttons under the .show class:

HTML:

<div class="collapse question-group show">
  <div class="progress">...</div>

  <div class="question">
    <div class="form-check">
      <input type="radio" />
      <label>yes1</label>
    </div>
  </div>

  <div class="question">
    <div class="form-check">
      <input type="radio" />
      <label>yes2</label>
    </div>
  </div>

  <div class="question">
    <div class="form-check">
      <input type="radio" />
      <label>yes3</label>
    </div>
  </div>
</div>

Now, I need to modify the current code to ensure that the alert('hello') function is triggered only when all the radio buttons under the .show .question class have been checked. If any radio button remains unchecked, the alert should not be triggered. How can I achieve this?

Here is what I tried, but it does not work; the alert window did not pop up:

document.querySelectorAll(".question-group").forEach((showEl) => {
  const allRadios = showEl.querySelectorAll('.form-check input[type="radio"]');
  let allChecked = false;

  showEl.addEventListener("change", () => {
    allChecked = Array.from(allRadios).every((radio) => radio.checked);
    if (allChecked) {
      alert("Hello");
    }
  });
});

2

Answers


  1. I am maintaining a counter which gets incremented/decremented within the event listener. Another approach might be to put the querySelectorAll statement within the event listener and use the every method.

    
    const radioButtons=[] 
    document.querySelectorAll(
      '.question-group'
    ).forEach(d =>{
    if(d.classList.contains('show')){
        radioButtons.push(...d.querySelectorAll('.question input[type="radio"]'));
    }
    });
    console.log('radioButtons',radioButtons.length);
    let checked = 0;
    radioButtons.forEach((button) => {
      button.addEventListener("change", (event) => {
        if (event.target.checked) {
          checked++;
        } else {
          checked--;
        }
    
        if (checked === radioButtons.length) {
          alert("hello");
        }
      });
    });
    
    Login or Signup to reply.
  2. You can have an event listener on the form (assuming that all radio buttons are in the same form) listening for change. You can then filter for the radio button that are not checked and if none is returned, display the alert. That is the first example.

    In the second example I replaced the radio buttons with checkboxes. One could argue that checkboxes are better suited for this use case, because you can give the checkboxes the same name and select multiple. Whereas the radio buttons when having the same name, you can only select one at a time. So, the second example I use checkboxes.

    Radio buttons:

    document.forms.form01.addEventListener('change', e => {
      let form = e.target.form;
      let notselected = [...form.elements]
        .filter(input => input.type == 'radio')
        .filter(input => input.checked == false);
      if(notselected.length == 0){
        alert('Hello');
      }
    });
    <form name="form01">
      <input type="text" name="test">
      <div class="collapse question-group show">
        <div class="progress">...</div>
    
        <div class="question">
          <div class="form-check">
            <input type="radio" name="q1" />
            <label>yes1</label>
          </div>
        </div>
    
        <div class="question">
          <div class="form-check">
            <input type="radio" name="q2" />
            <label>yes2</label>
          </div>
        </div>
    
        <div class="question">
          <div class="form-check">
            <input type="radio" name="q3" />
            <label>yes3</label>
          </div>
        </div>
      </div>
    </form>

    Checkboxes:

    document.forms.form01.addEventListener('change', e => {
      let form = e.target.form;
      let notselected = [...form.elements.group1]
        .filter(input => input.checked == false);
      if(notselected.length == 0){
        alert('Hello');
      }
    });
    <form name="form01">
      <input type="text" name="test">
      <div class="collapse question-group show">
        <div class="progress">...</div>
    
        <div class="question">
          <div class="form-check">
            <input type="checkbox" name="group1" />
            <label>yes1</label>
          </div>
        </div>
    
        <div class="question">
          <div class="form-check">
            <input type="checkbox" name="group1" />
            <label>yes2</label>
          </div>
        </div>
    
        <div class="question">
          <div class="form-check">
            <input type="checkbox" name="group1" />
            <label>yes3</label>
          </div>
        </div>
      </div>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search