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.
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/
Related
I'm trying to validate radio buttons but the valuation does not work, the next page gets loaded even if no radio button is checked. I have tried different approaches but none of them work, at one point I had pop-up window appearing, as for other messages, but next page was loaded anyway.
Here is my code:
HTML:
<fieldset id="Radio">
Smoking <input type="radio" name="smoking" id="smoking1" value="Smoking">
Non-smoking <input type="radio" name="smoking" id="smoking2" value="Non-smoking">
</fieldset>
JavaScript:
var radio1 = document.getElementById("smoking1");
var radio2 = document.getElementById("smoking2");
if ((!radio1.checked) && (!radio2.checked)){
window.alert("You must check one of the options in Smoking Preferences field!");
reservation.radio1.focus();
return false;
}
I would appreciate any suggestions! Thanks!
reservation.radio1.focus();
There is no element with the name radio1 in your code sample.
add name="radio1" to both your radio buttons.
Now the focus will not work since name will return two so you need to select the first one.
reservation.radio1[0].focus();
I have an unordered list containing radio inputs and labels. When a user clicks on the list item it toggles some info and selects the radio input.
However, due to the above, if the user clicks onto the actual radio input itself, it does not select it, as I guess the click is registered against the radio and not the list item itself?
Is there any cure?
jQuery('#sdmlist li.item').click(function(e) {
jQuery('#sdmlist li.item address').slideUp();
jQuery("address",this).slideToggle("slow");
jQuery("input[type=radio]", this).attr('checked',true);
var element = jQuery("input[type=radio]", this).val();
...
return false;
});
and some html:
<ul id="sdmlist">
<li class="item"><input type="radio" name="1" id="1">1 <address>test 123</address></li>
<li class="item"><input type="radio" name="2" id="2">2 <address>test 23</address></li>
<li class="item"><input type="radio" name="3" id="3">3 <address>test 3</address></li>
</ul>
That behavior is caused by return false stopping the default behavior of the click event who has been propagated by then click on the radio. The default behavior of the radio is, of course, the radio beign checked.
Just remove the return false and it work : http://jsfiddle.net/4v9R9/2/
I'm 95% there in writing an HTML5 'required' attribute fallback, I'm having a small issue and I've come to the end of the road in my knowledge!
What works:
Detecting 'required' attributes, looping through and alerting the user in several ways (onsubmit and entering data into the field).
Problem:
I'm taking the form one step further and want to make checkboxes and radio buttons required as well. By doing this, I need to add a required attribute to each radio/checkbox. I need to find out how to differentiate the group of buttons, as currently you need to tick/untick both sets of buttons for the form to validate and let you submit. So in a nutshell, I have three required radios for example, each will need to be ticked, how can I detect whilst looping through the inputs that one of the required radios/checked is ticked - I assume this would be done by matching the 'name' attribute, and if none in the name group are selected then alert just one error.
Here's the state of my loop, you can see I detect the input type as well, just unsure of the next steps forward. a jsFiddle is also below if anyone would be kind enough to help out. Many thanks.
// loop through class name required
$('.required').each(function () {
// this
var self = $(this)
// check shorthand if statement for input[type] detection
var checked = (self.is(':checkbox') || self.is(':radio')) ? self.is(':not(:checked)') : false
// run the empty/not:checked test
if (self.val() === '' || checked) {
// show error if the values are empty still (or re-emptied)
// this will fire after it's already been checked once
self.siblings('.form-error').show()
// stop form submitting
e.preventDefault()
// if it's passed the check
} else {
// hide the error
self.siblings('.form-error').hide()
}
})
Here's my jsFiddle: http://jsfiddle.net/zykF9/
With class selectors you could archive it
http://jsbin.com/owokuw/1/edit
UPDATE
to make easier to understand, here a update:
<input type="radio" name="myradio" class="myradio" />
<input type="radio" name="myradio" class="myradio" />
<input type="radio" name="myradio" class="myradio" />
<input type="radio" name="myradio" class="myradio" />
<input type="hidden" id="selectedRadioYes" />
<input type="button" id="botton" value="Botton" />
Jquery
$(".myradio").click(function(){
$("#selectedRadioYes").val(1);
});
$("#botton").click(function(){
if($("#selectedRadioYes").val() === "1")
alert("you can go on");
else
alert("need select one radio");
});
http://jsbin.com/owokuw/2/edit
I am going to try to be as concise as I can :) I am working on a project. This project generates many pages full of thumbnail images with checkboxes next to them. There can be a varying ammount of total thumbnails. The thumbnails are sorted into 1000 item html pages. So 1000 thumbnails an html page. These pages full of thumbnails are called by a parent html page via iframe. My goal is to have the ability for a user to check checkboxes near these thumbnails, then load a new page into the iframe, checkboxes there, then be able to load the previous page into the iframe, and for the javascript to check the boxes the user had previously checked. I keep track of which checkboxes the user checked by using an array.
Here is the javascript. There is TWO issues! First issue is, I have the alert there for debugging. It does alert the correct values, but it alerts all of the values stored in the array. I wish it to only alert the checkboxes that exist within the iframe page, which is why I have it to the document.getElementByNames. Then... it doesn't check any of the boxes! No box checks :(
Any thoughts on how to accomplish this? the JS and HTML is below...
JS
function repGenChk(valNam) {
var chkN = valNam.name;
parent.genL.push(chkN);
alert(parent.genL);
}
function chkSet() {
for (var i = 0; i < parent.genL.length; i++) {
var item = parent.genL[i];
var item = document.getElementsByName(item);
if (item != null) { document.getElementsByName(item).checked=true; }
alert(parent.genL[i]);
}}
window.onload = chkSet();
HTML
<input type="checkbox" onClick="repGenChk(this);" value="1" name="1">
<input type="checkbox" onClick="repGenChk(this);" value="2" name="2">
<input type="checkbox" onClick="repGenChk(this);" value="3" name="3">
<input type="checkbox" onClick="repGenChk(this);" value="4" name="4">
so on and so forth for Xthousands of checkboxes....
Any thoughts, ideas, constructive criticism and critiques are EXTREMELY welcome! I've gotten alot of jQuery suggestions in the past, and i'm heavily starting to consider it.
Thanks so much everyone!
EDIT - I was able to figure it out. I didn't think I could use IDs with checkboxes, I can. Woo!
JS
function repGenChk(valNam) {
var chkN = valNam.id;
parent.genL.push(chkN);
alert(parent.genL);
}
window.onload = function chkSet() {
for (var i = 0; i < parent.genL.length; i++) {
if (document.getElementById(parent.genL[i]) != null) { document.getElementById(parent.genL[i]).checked=true; }
}
}
HTML
<input type="checkbox" onClick="repGenChk(this);" id="1">
<input type="checkbox" onClick="repGenChk(this);" id="2">
<input type="checkbox" onClick="repGenChk(this);" id="3">
<input type="checkbox" onClick="repGenChk(this);" id="4">
etc etc etc.....
:)
Consider putting a single click listener on an element containing the checkboxes. Give each checkbox a unique id or name. When you get a click on the container, check where it came from. If it's from a checkbox, add or remove the name/id of the checkbox to an object storing which ones are checked depending on whether the checkbox is checked or not.
When you want to re-check them, iterate over the object (using for..in) and use getElementById or getElementsByName(…)[0] to check the checkbox. That way you only iterate over as many object properties as there are checked checkboxes and also getElementById is very fast, so things should be simpler and faster.
BTW, getElementsByName returns a collection, which is array-like but it isn't an array.
I've got the a piece of a form where I've applied some javascript (the end-purpose of the js is to show the appropriate follow up question), but the part that loads the input's and select's values into variables doesn't seem to be working.
Here's the exact code:
# HTML
<ul id="m_mlt_t">
<li>How long have you known <span class="nom">__</span>?</li>
<li><input name="m_mlt_n" type="text" maxlength="3" /> <select name="m_mlt_t"><option></option><option>days</option><option>months</option><option>years</option></select></li>
<li><input name="m_mlt_n" type="radio" value="777" />I prefer not to answer</li>
<li><input name="m_mlt_n" type="radio" value="999" />Don't know</li>
<li><span class="m_mlt_t" style="display:none;"></span></li>
</ul>
# JAVASCRIPT
$('select[name="m_mlt_t"], input[name="m_mlt_n"]').change(function() {
var time = $('input[name="m_mlt_n"]').val();
$("span#m_mlt_t").text(time);
$("span#m_mlt_t").fadeIn();
var period = $('select[name="m_mlt_t"]').val();
$("span#m_mlt_t").append(" " + period);
$("span#m_mlt_t").fadeIn();
});
In the fiddle, I expect the span to fade in and display the values of the textfield and the dropdown.
http://jsfiddle.net/vxvSU/
btw the code for the following custom functions isn't included, but I know they work
counter_multiChoice(),fadeOUT_sect(),fadeIN_sect()
A first problem is your selector
$('select[name="m_mlt_t"] input[name="m_mlt_n"]')
This selects any child input elements inside the select element, which doesn't make any sense and should probably be...
$('select[name="m_mlt_t"], input[name="m_mlt_n"]')
Which selects all matching select, and input elements with the appropriate names.