Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to determine if each radio group has a selected radio, when multiple groups are present?

Evening all, I’ve spent the last few days trying to figure out how to validate multiple radio groups in javascript. I aim to determine if the user has made a selection; if not, prompt them via an error message.

I’ve dug around Stack and Google etc. But no matter what I try/find, I just can’t seem to get the behaviour I’m looking for. The questions/resources I’ve found so far have guided me to my current example (Shown Below), but I’m hoping one of you lovely people could guide me across the finish line.

Specifically, I’m looking for an example of how to validate all radio groups, making sure that the user has made a selection within each. (I would appreciate good commenting and explaining each step, as the loops are pretty challenging for me to understand.)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Thanks in advance. 😅👌

I’ve attached below a complete snippet with my workings inside; I’ve tweaked the snippet to cut out all of the non-essential stuff in the hopes it makes it easier to understand.

EDIT:
Forgot to mention the problems with the below code. The below code seems to validate on certain selection combinations but fails on others, I suspect it might be a loop error, but I’ll admit when I don’t think I understand them well enough.

EDIT:
For those yet to come, I’ve accepted @KooiInc’s answer because it answers the question. Though Mister Jojo is correct, I should be using forms and HTML5 for validation. Stupid oversight that ended up in me wasting a tonne of time. 😅 Ah, well, it’s all a learning experience. 👍👌

Example Snippet

class radioChecks {

  // Constructor.
  constructor() {
    this.inputs = document.querySelectorAll("input");
    this.radioGroups = document.querySelectorAll(".radioGroup");
    this.errors = document.getElementById("errors");
    this.bindEvents();
  }

  // Bind Events.
  bindEvents() {
    for (let i = 0; i < this.inputs.length; i++) {
      this.inputs[i].addEventListener("click", function(e) {
        if (e.target.dataset.direction) {
          e.target.dataset.direction === "next"
          this.validate();
        }
      }.bind(this));
    }
  }

  validate() {
    const _this = this;

    function isRadioGroupValid() {
      let checked = false;
      let inputName = "";
      for (let i = 0; i < _this.radioGroups.length; i++) {
        const radios = _this.radioGroups[i].querySelectorAll('[type="radio"]');

        for (let j = 0; j < radios.length; j++) {
          radios[i].checked ? checked = true : checked = false;
          inputName = radios[i].name;
        }
      }

      !checked
        ?
        _this.errorHandler(_this, `Please select an option for ${inputName}.`, true) :
        _this.errorHandler(_this, "", false);

    }

    isRadioGroupValid();
    console.log("All radio groups have selection.");
    return true;
  }

  errorHandler(_this, message, error) {
    // Show any errors.
    function showErrors(message) {
      _this.errors.innerHTML = message;
      _this.errors.classList.add("invalid");
      throw new Error(message);
    }

    // Clear any existing errors.
    function clearErrors() {
      _this.errors.innerHTML = "";
      _this.errors.classList.remove("invalid");
    }

    // if error true. Show error.
    error ? showErrors(message) : clearErrors();
  }
}


new radioChecks();
* {
  text-align: center;
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, Arial, sans-serif;
}

.radioGroup {
  display: flex;
  justify-content: center;
  align-items: center;
  /* flex-flow: row nowrap; */
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: space-between;
  gap: 1em;
  max-width: 640px;
  margin: 0 auto;
}

.radioGroup:first-of-type {
  margin-top: 3em;
}

@media screen and (max-width: 768px) {
  flex-direction: column;
}

.radioOption {
  flex-grow: 1;
  width: 100%;
  margin-bottom: 1em;
}

input[type="radio"] {
  position: absolute;
  left: -9999px;
  opacity: 0;
  z-index: 100;
}

label {
  display: block;
  padding: 0.5em 1em;
  border: 1px solid #999;
  color: #999;
  width: 100%;
  cursor: pointer;
  transition: all 0.2s ease;
}

input[type="radio"]:checked+label {
  border: 1px solid #000;
  color: #000;
  transition: all 0.2s ease;
}

input[type="button"] {
  margin-top: 3em;
  background-color: #ddd;
  border: none;
  color: #000;
  padding: 0.5em 2em;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  cursor: pointer;
}

input[type="button"]:hover {
  background-color: #ccc;
}

#errors.invalid {
  display: block;
}

#errors {
  display: none;
  color: #842029;
  background-color: #f8d7da;
  border: 1px solid #f5c2c7;
  font-weight: bold;
  padding: 0.5em 2em;
  width: 300px;
  margin: 2em auto;
}
<div class="radioGroup">
  <div class="radioOption">
    <input type="radio" id="radioOne" name="group_one" value="Foo">
    <label for="radioOne">My Foo Radio</label>
  </div>
  <div class="radioOption">
    <input type="radio" id="radioTwo" name="group_one" value="Bar">
    <label for="radioTwo">My Bar Radio</label>
  </div>
</div>

<div class="radioGroup">
  <div class="radioOption">
    <input type="radio" id="radioThree" name="group_two" value="Baz">
    <label for="radioThree">My Baz Radio</label>
  </div>
  <div class="radioOption">
    <input type="radio" id="radioFour" name="group_two" value="Qux">
    <label for="radioFour">My Qux Radio</label>
  </div>
</div>

<div class="btn">
  <input type="button" data-direction="next" value="Next" />
</div>

<div id="errors"> Testing! </div>

>Solution :

You can use a css-selector to determine the radio check states. Here a minimal example for that:

document.addEventListener(`click`, evt => {
  if (evt.target.id === `allchecked`) {
    console.clear();
    const bothChecked = document
      .querySelectorAll(`.rGroup input[type='radio']:checked`)
      .length === 2;
    console.log(`both groups checked? ${
      bothChecked ? `Yep`: `Nope`}`);
  }
})
<div class="rGroup" id="group1">
  <input type="radio" name="rg1"> one
  <input type="radio" name="rg1"> two
  <input type="radio" name="rg1"> tree
</div>
<div class="rGroup" id="group2">
  <input type="radio" name="rg2"> one
  <input type="radio" name="rg2"> two
  <input type="radio" name="rg2"> tree
</div>
<button id="allchecked">both checked?</button>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading