user2201650 user2201650 - 7 months ago 25
HTML Question

JavaScript - Select radio button if any checkbox is checked

I'm trying to write JavaScript code where a radio button should be populated if a checkbox is checked.

Following is the HTML code:

<form>
<h3>Radio Buttons</h3>
<input type="radio" name="radio1" id="radio1"> Radio 1
<br>
<input type="radio" name="radio2" id="radio2">Radio 2
<br>
<br>

<h3>Checkbox Groups</h3>

<h4><u>Group 1</u></h4>
<p align="center"><u>PD</u></p>
<ul>
<li>
<input id="pdcb" type="checkbox" name="G1PD1" onclick="validate()">G1 PD1</li>
<li>
<input id="pdcb" type="checkbox" name="G1PD2" onclick="validate()">G1 PD2</li>
</ul>
<p align="center"><u>ID</u></p>
<ul>
<li>
<input id="idcb" type="checkbox" name="G1ID1" onclick="validate()">G1 ID1</li>
<li>
<input id="idcb" type="checkbox" name="G1ID2" onclick="validate()">G1 ID2</li>
</ul>

<h4><u>Group 2</u></h4>
<p align="center"><u>PD</u></p>
<ul>
<li>
<input id="pdcb" type="checkbox" name="G2PD1" onclick="validate()">G2 PD1</li>
<li>
<input id="pdcb" type="checkbox" name="G2PD2" onclick="validate()">G2 PD2</li>
</ul>
<p align="center"><u>ID</u></p>
<ul>
<li>
<input id="idcb" type="checkbox" name="G2ID1" onclick="validate()">G2 ID1</li>
<li>
<input id="idcb" type="checkbox" name="G2ID2" onclick="validate()">G2 ID2</li>
</ul>
</form>


So here's what I want the JavaScript to do: If any of the
PD
checkboxes are selected, then the radio button
Radio 1
should get selected. If none of the
PD
checkboxes are selected, then the radio button
Radio 2
should get selected. Similarly, if none of the checkboxes are selected, then NONE of the radio buttons should get selected.

So far, I've written the following JS code:

function validate()
{
if(document.getElementById("pdcb").checked) //if pdcb checkbox(es) is/are checked
{
document.getElementById("radio1").checked = true;
document.getElementById("radio2").checked = false;
}
else if (!document.getElementById("pdcb").checked) //if none of the pdcb checkbox(es) is/are checked
{
document.getElementById("radio1").checked = false;
document.getElementById("radio2").checked = true;
}
else //if no checkbox is checked, then don't populate any radio button
{
document.getElementById("radio1").checked = false;
document.getElementById("radio2").checked = false;
}

}


PS: I need the code to be in pure JavaScript. I can't use jQuery

EDIT:
I apologize for getting my requirements wrong. But here's the correct requirement. If any of the
PD
checkboxes are selected, then the radio button
Radio 1
should get selected. If none of the
PD
checkboxes are selected, then the radio button
Radio 2
should get selected. Similarly, if none of the checkboxes are selected, then NONE of the radio buttons should get selected.

Could anyone help me out here?

Thanks in advance!

Answer

I want to first point out that if you were testing this in a JSFiddle, the LOAD TYPE needs to be set to "No Wrap-in " for your inline onclick events to work.

Now, to your code. Document elements can either be tied to a class or ID. Classes are for when you're using elements that share the same functionality, styling, etc.; ID's are for unique elements and unique elements only. For example, in your JavaScript, when you try to test for checked pdcb elements with

document.getElementById("pdcb").checked

JavaScript simply grabs the first element on the page with the ID of pdcb. You have four elements with this ID name; this means that the last three pdcb elements are ignored and never evaluated.

Instead, let's utilize

document.getElementsByClassName("pdcb")

Note the plural form of the word 'Element'. What this does is it returns an array of all elements with the class name of pdcb. We'll get to the fact that we're dealing with an array in a few minutes. First, let's change most of your HTML ID's to classes.

<ul>
   <li>
      <input class="pdcb" type="checkbox" name="G1PD1" onclick="validate()">G1 PD1</li>
   <li>
      <input class="pdcb" type="checkbox" name="G1PD2" onclick="validate()">G1 PD2</li>
</ul>

You're going to want to do this for all of your pdcb and idcb elements. Feel free to preserve radio1 and radio2 as ID's because they're unique elements, not reused like pdcb and idcb are.


Now we can address the JavaScript; you're HTML is fine from here assuming you've made the changes necessary from above. Since we changed things from ID's to classes, expressions like the following simply won't do.

document.getElementById("pdcb")

Recall the solution that I wrote earlier:

document.getElementsByClassName("pdcb")

Also recall that I said that this will return an array of elements; in your case, four pdcb elements.

One option that you have at your disposal for tackling this problem is that you can iterate through the array of elements returned by document.getElementsByClassName("pdcb") to evaluate whether any pdcb class has been checked. It'll look something like this:

var pdcbClass = document.getElementsByClassName("pdcb");

    //for each pdcb class on our HTML document
    for (var i = 0; i < pdcbClass.length; i++) {
       if (pdcbClass[i].checked == true) {
          //the next two lines are straight from your JavaScript code
          document.getElementById("radio1").checked = true;
          document.getElementById("radio2").checked = false;
        }
    }

As you can imagine, we can use the exact same idea for the idcb class elements on your page. By the time we're done, we should have something like what you see below.

function validate()
{
  var pdcbClass = document.getElementsByClassName("pdcb");
  var idcbClass = document.getElementsByClassName("idcb");
  console.log(this);
    for (var i = 0; i < pdcbClass.length; i++) {
    if (pdcbClass[i].checked == true) {
       document.getElementById("radio1").checked = true;
         document.getElementById("radio2").checked = false;
    }
  }

  for (var i = 0; i < idcbClass.length; i++) {
    if (idcbClass[i].checked == true) {
      document.getElementById("radio1").checked = false;
      document.getElementById("radio2").checked = true;
    }
  }
}

But there's a problem! No matter what check box fires off this validate() function, no check box is ever turned off. That means if we check a box with the pdcb class and then check a box with the idcb class, the pdcb box still stays checked; we never said to uncheck it. What this means is that even though it was an idcb click that triggered validate(), all of the code in the function gets executed. Either you have to have the user manually uncheck the previous box before checking a new one, or you need to write some code that does this same thing. Specifically, when a new check box is checked, you need to clear the previous box(es) of their checked property.

That is an entirely different problem and merits a different question. Also consider that this isn't the only way to write this event/functionality, but you're making good progress.

Here's essentially the code you need to keep on going.

https://jsfiddle.net/a4k9xggu/

Comments