Check if all radio buttons are clicked in vanilla JavaScript - javascript

For exercise, I've created a small HTML-CSS-JavaScript quiz. The quiz itself works but when I tried to edit a way to check if all radio buttons of the quiz are working (and if not, alert a message to the user), it became broken.
Here is the quiz, with the funcion that checks if the radio buttons are clicked:
let result = 0;
function right() {
result += 50;
}
function wrong() {
result -= 50;
}
function obcpq() {
if (document.querySelector('#quiz:not(:has(:radio:checked))').length) {
return alert("At least one group is blank");
} else {
function showScore() {
totalScore = result;
alert(totalScore);
}
}
}
<form id="quiz">
<label>Q1 - X?</label>
<input type="radio" onclick="right()">Yes
<input type="radio" onclick="wrong()">No
<br>
<label>Q2 - Y?</label>
<input type="radio" onclick="wrong()">Yes
<input type="radio" onclick="right()">No
<br>
<input type="button" onclick="obcpq()" />
<!-- One Button Chcked Per Question -->
</form>
I tried this code after reading of it in this QA session. I also found this session which deals with jQuery and I don't run jQuery on this HTML page.
Why isn't the condition working in my vanilla JavaScript version?

Looking at your HTML code, there's one proportion that can be useful to solve your problem: you want the same number of checked inputs as the number of labels that describe the boxes. When the numbers don't match it's the indicator that not all questions were answered:
let result = 0;
function right() {
result += 50;
}
function wrong() {
result -= 50;
}
function obcpq() {
const labelCount = document.querySelectorAll('#quiz label').length;
const checkedInputsCount = document.querySelectorAll("#quiz :checked").length;
if (labelCount !== checkedInputsCount) {
return alert("At least one group is blank");
} else {
function showScore() {
totalScore = result;
alert(totalScore);
}
}
}
<form id="quiz">
<label>Q1 - X?</label>
<input type="radio" onclick="right()">Yes
<input type="radio" onclick="wrong()">No
<br>
<label>Q2 - Y?</label>
<input type="radio" onclick="wrong()">Yes
<input type="radio" onclick="right()">No
<br>
<input type="button" onclick="obcpq()" />
<!-- One Button Chcked Per Question -->
</form>

Try to add every question in a separate div then loop through them and check if the group has at least one checked option radio, then use a flag to store the loop result and finally show the right message, like :
let result = 0;
function right() {
result += 50;
}
function wrong() {
result -= 50;
}
function obcpq() {
var groups = document.querySelectorAll('#quiz div');
var all_checked = true;
for (i = 0; i < groups.length; i++) {
if (groups[i].querySelectorAll(':checked').length==0) {
all_checked = false;
}
}
if (!all_checked) {
console.log('Check please all the radios');
} else {
console.log('showScore');
}
}
<form id="quiz">
<div>
<label>Q1 - X?</label>
<input type="radio" onclick="right()">Yes
<input type="radio" onclick="wrong()">No
</div>
<div> <label>Q2 - Y?</label>
<input type="radio" onclick="wrong()">Yes
<input type="radio" onclick="right()">No
</div>
<input type="button" onclick="obcpq()" value="CHECK"/>
<!-- One Button Chcked Per Question -->
</form>

Related

Validation with input[type="radio"] return always false

I have an input[type="radio"], with no checked option by default, and i need to return false if none of these options are checked.
I'm exploring javascript only, so a jquery, angular or any other will be useles (at this moment).
I'm able to iterate over a radioObj and select its value, but i can't return false if no option is checked (actually, i can't return true)
not exactly what i have, but...
<input type="radio" id="rd1" name="radioGrp">opt1
<br>
<input type="radio" id="rd2" name="radioGrp">opt2
and in JS i have...
var rdObj = document.getElementByName("radioGrp");
var selectedValue;
for (var i = 0, length = rdObj.length; i < length; i++){
if(!rdObj[i].checked){
alert("Select one option");
return false;
}else{
//do something with value of radio checked value
}
}
This code always gives me the alert("Select one option"), no matter if i select one option or not.
Need for validation.
Any hel will be very appreciated
You probably want to wait for an event before you do any sort of value checking, otherwise your script will only run once, and at this point in time, nothing would have ever had the chance be checked.
You can attach a change event listener to each of your radios...
var myRadios = document.querySelectorAll('[name=radioGrp]');
var selectedValue;
myRadios.forEach(radio => {
radio.addEventListener('change', changeHandler);
})
function changeHandler(evt) {
// do some check in here
console.log(evt.target.value)
}
<input type="radio" id="rd1" name="radioGrp" value='opt1'>opt1
<br>
<input type="radio" id="rd2" name="radioGrp" value='opt2'>opt2
...or you can attach a submit event handler to your form and do some checking of your data then.
const myForm = document.querySelector('form');
myForm.addEventListener('submit', submitHandler);
function submitHandler(evt) {
evt.preventDefault();
const data = new FormData(evt.target);
const optionVal = data.get('radioGrp');
// do some check in here
if (!optionVal) {
console.log(`Please select a value`)
} else {
console.log(`Thanks for selecting ${optionVal}`)
}
}
<form>
<input type="radio" id="rd1" name="radioGrp" value='opt1'>opt1
<br>
<input type="radio" id="rd2" name="radioGrp" value='opt2'>opt2
<input type="submit">
</form>
You can try this:
function validateForm() {
var radios = document.getElementsByName("radioGrp");
var formValid = false;
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
formValid = true;
break;
}
}
if (!formValid) {
alert("Select one option");
}
return formValid;
}
<form name="form1" action="#" onsubmit="return validateForm();" method="post">
<input type="radio" id="rd1" name="radioGrp">opt1
<br>
<input type="radio" id="rd2" name="radioGrp">opt2
<br>
<input type="submit" value="Submit">
</form>

JavaScript Checkbox

I am having troubles with a script with JS, I am still learning but I am stuck for a while.
The solution should be,
IF a checkbox is checked and the value is "" <-- the msgbox should say an message that the textbox should be filled with a value, and so for each checked checkbox, if you uncheck the checkbox, it should dissapear.
Code of 2 checkboxes in html page
<label>
bangkirai
<input id="chk_bangkirai" type="checkbox" onchange="enableTextBox()" />
</label>
<input type="text" id="bangkirai" name="bangkirai" disabled onchange="enableTextBox()" />
<label>
beukenhout
<input id="chk_beukenhout" type="checkbox" />
</label>
<input type="text" id="beukenhout" name="beukenhout" disabled/>
and the JavaScript, I made for each checkbox an other function, but I need to combine the error message in the same msgbox.
function enableTextBox() {
divOutput = document.getElementById("msgbox2");
strValideer = "<ul>";
if (document.getElementById("chk_bangkirai").checked === true) {
document.getElementById("bangkirai").disabled = false;
}
else {
document.getElementById("bangkirai").disabled = true;
}
if (document.getElementById("bangkirai").value === "") {
strValideer += "<li><b>bangkirai: </b>verplicht veld</li>";
}
strValideer += "</ul>";
divOutput.innerHTML = strValideer;
}
function enableTextBox2() {
divOutput = document.getElementById("msgbox2");
strValideer = "<ul>";
if (document.getElementById("chk_beukenhout").checked === true) {
document.getElementById("beukenhout").disabled = false;
}
else {
document.getElementById("beukenhout").disabled = true;
}
if (document.getElementById("beukenhout").value === "") {
strValideer += "<li><b>beukenhout: </b>verplicht veld</li>";
}
strValideer += "</ul>";
divOutput.innerHTML = strValideer;
}
I should probably use an array or an for each itteration ... but I can only find examples with forms ...
I will keep looking for a solution myself, but I hope I can get some inspiration here by experienced coders.
Thanks in advance
You could simplify this a lot and make it more... Concise and less dependent on which checkbox you have. We will do this with an external script and no onClick attributes on our HTML. This will enable us to separate our logic code from our design code. I will also use a placeholder instead of value, as it will create issues when people need to start entering a value (aka, you need to only have the text there when theres no value etc...) It just makes it more complicated.
Since we are dealing with numbers ('stuks' or amounts), lets also only allow number values to be inserted. Lastly, I have not bothered to replicate your HTML as I think the simplified example will make it easier to understand. Update I have also added the required and disabled sattributes here, settings your input to required when the checkbox is checked and disabled when not.
Check the below snippet for comments on the steps taken to do this:
// First, let select all fieldsets like this:
var fieldsets = document.querySelectorAll( 'fieldset.checkbox-message' );
// Lets loop through them
for( let i = 0; i < fieldsets.length; i++ ){
// Lets create variables to store our fieldset, checkbox and input for later use.
let fieldset = fieldsets[ i ];
let checkbox = fieldset.querySelector( 'input[type="checkbox"]' );
let input = fieldset.querySelector( 'input[type="number"]' );
// Lets also store the message we put in placeholder
// We will also give it a default value,
// in case you forget to set the placeholder.
let message = input.placeholder || 'Please fill in the amount';
// Now lets define a function that will fill the placeholder
// based on the checked value of the checkbox
// We will be storing it in a variable because of the scope of a `for` block.
// If you would use function setState() it might be defined globally
// So multiply checkboxes would not work.
let setState = function(){
if( checkbox.checked ){
input.placeholder = message;
input.disabled = false;
input.required = true;
} else {
input.placeholder = '';
input.disabled = true;
input.required = false;
}
}
// Now lets listen for changes to the checkbox and call our setState
checkbox.addEventListener( 'change', setState );
// Lrts also call setState once to initialise the correct placeholder
// for our input element to get started. This will remove any placeholders
// if the checkboxes are unchecked.
setState();
}
<fieldset class="checkbox-message">
<label for="bangkirai">Bangkirai</label>
<input type="checkbox" id="bangkirai" />
<input type="number" placeholder="Tell us, how many 'bangkirai'?" />
<span>stuks</span>
</fieldset>
<fieldset class="checkbox-message">
<label for="beukenhout">Beukenhout</label>
<input type="checkbox" id="beukenhout" />
<input type="number" placeholder="How many 'beukenhout'?" />
<span>stuks</span>
</fieldset>
Good luck coding!
#somethinghere's answer is concise but if we modify your answer as it is you could check this
function enableTextBox() {
bangkirai_validation = document.getElementById("bangkirai_validation");
if (document.getElementById("chk_bangkirai").checked === true) {
document.getElementById("bangkirai").disabled = false;
}
else {
document.getElementById("bangkirai").disabled = true;
bangkirai_validation.style.display='none';
return;
}
if (document.getElementById("bangkirai").value =="") {
bangkirai_validation.style.display='block';
}else
{
bangkirai_validation.style.display='none';
}
}
function enableTextBox2() {
beukenhout_validation = document.getElementById("beukenhout_validation");
if (document.getElementById("chk_beukenhout").checked === true) {
document.getElementById("beukenhout").disabled = false;
}
else {
document.getElementById("beukenhout").disabled = true;
beukenhout_validation.style.display='none';
return;
}
if (document.getElementById("beukenhout").value == "") {
beukenhout_validation.style.display='block';
}else
{
beukenhout_validation.style.display='none';
}
}
<fieldset>
<legend>Bestel gegevens</legend>
<div class="container">
<div class="row">
<div class="span7 id=" houtsoorten"">
<div class="control-group">
<label class="control-label">
bangkirai
<input id="chk_bangkirai" type="checkbox"
onchange="enableTextBox()" >
</label>
<div class="controls">
<div class="input-append">
<input class="inpbox input-mini"
type="number" id="bangkirai" name="bangkirai" placeholder="aantal" disabled
onkeyup="enableTextBox()" onchange="enableTextBox()">
<span class="add-on">stuks</span>
<div style="display:none;" id="bangkirai_validation">Please enter a value</div>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">
beukenhout
<input id="chk_beukenhout" type="checkbox" onchange="enableTextBox2()" >
</label>
<div class="controls">
<div class="input-append">
<input class="inpbox input-mini"
type="number" id="beukenhout" name="beukenhout" placeholder="aantal"
disabled onkeyup="enableTextBox2()" onchange="enableTextBox2()" >
<span class="add-on">stuks</span>
<div style="display:none;" id="beukenhout_validation">Please enter a value</div>
</div>
</div>
</div>

Alert Radio Input in form

I am trying to write a form when I ask the user to write if they like to eat or not. However, no matter what they answer, the answer comes out "yes". What is the problem with this code?
<form>
Do you like food?<br>
<input type="radio" id="validate" value="yes">Yes<br>
<input type="radio" id="validate" value="no">No<br>
<br><br>
<input id="submit" name="submit" type="submit" value="Submit" onclick="eatFood()">
</form>
<script>
function eatFood() {
var y = document.getElementById("validate").value;
alert(y);
}
</script>
Here is the most simple way to get a radio input value using JavaScript:
function eatFood() {
var choice = document.querySelector('input[name = validate]:checked').value;
alert(choice);
}
Working demo : https://codepen.io/andreds/pen/ppQzeL
Here is the a second way :
function eatFood() {
var radios = document.getElementsByName('validate');
for (var i = 0, length = radios.length; i < length; i++)
{
if (radios[i].checked)
{
alert(radios[i].value);
break;
}
}
}
Second way working demo : https://codepen.io/andreds/pen/XVyrJB
Here is third way, if you only have two radios input :
function eatFood() {
if (document.getElementById('yes').checked) {
result = document.getElementById('yes').value;
}
if (document.getElementById('no').checked) {
result = document.getElementById('no').value;
}
alert(result);
}
Third way working demo : https://codepen.io/andreds/pen/KZrPVy
You missed the name attribute, this is necessary to group radio buttons:
<input type="radio" name="validate" value="yes">Yes<br>
<input type="radio" name="validate" value="no">No<br>
The id must be unique, fixing the JavaScript function with this, the result would be the next (as André's answer):
function eatFood() {
var radios = document.getElementsByName('validate');
for (var i = 0, length = radios.length; i < length; i++)
{
if (radios[i].checked)
{
alert(radios[i].value);
break;
}
}
}

I need to calculate the value of some checked radio buttons using DOM

My code so far is:
HTML
<input type="radio" name="age" value="0">1-25
<input type="radio" name="age" value="5">26-27
<input type="radio" name="age" value="7">28-29
<input type="radio" name="bmi" value="0">0-25
<input type="radio" name="bmi" value="0">26-30
<input type="radio" name="bmi" value="9">31-35
So I need to get the value of the checked radio buttons and calculate them
Javascript as the first answer that I've got
function CalculateValue(){
//call getAgeValue(), getBmiValue() here and do desired calculations here
}
function getAgeValue()
{
for (var i = 0; i < document.getElementsByName('age').length; i++)
{
if (document.getElementsByName('age')[i].checked)
{
return document.getElementsByName('age')[i].value;
}
}
}
function getBmiValue()
{
for (var i = 0; i < document.getElementsByName('bmi').length; i++)
{
if (document.getElementsByName('bmi')[i].checked)
{
return document.getElementsByName('bmi')[i].value;
}
}
Making use of the vanilla document.querySelector
function doCalculation(ageValue, bmiValue) {
// whatever
return ageValue + bmiValue;
}
function getRadioValue(radio_name) {
return ( // parenthesis to let us do an OR
document.querySelector('input[type="radio"][name="' + radio_name + '"]:checked')
|| // or if none is checked
{} // so we don't get an error
).value;
}
function handlerForButton(e) {
var age = +getRadioValue('age'),
bmi = +getRadioValue('bmi'),
foo = doCalculation(age, bmi);
// do whateverwith foo
console.log(foo);
}
// after elements exist
document.querySelector('input[type="button"][value="Calculate"]')
.addEventListener('click', handlerForButton);
DEMO
You may find it easier to use classes and ids to find your elements rather than seeking them out using their other attributes. This would also improve performance

Jquery Conditional Statements for Multiple Checkbox Values

I'm new to posting/stackoverflow, so please forgive me for any faux pas. I have multiple buttons and checkboxes that I need to store the values of to place into conditional statements.
The HTML code:
<h1>SECTION 1: GENDER</h1>
<p>What is your gender?</p>
<input type="button" onclick="storeGender(this.value)" value="Male"/>
<input type="button" onclick="storeGender(this.value)" value="Female"/>
<hr />
<h1>SECTION 2: AGE</h1>
<p>What is your age?</p>
<input type="button" onclick="storeAge(this.value)" value="18–22"/>
<input type="button" onclick="storeAge(this.value)" value="23–30"/>
<hr />
<h1>SECTION 3: TRAITS</h1>
<h3>Choose Two:</h3>
<form>
<input name="field" type="checkbox" value="1"/> Casual <br />
<input name="field" type="checkbox" value="10"/> Cheerful <br />
<input name="field" type="checkbox" value="100"/> Confident <br />
<input name="field" type="checkbox" value="1000"/> Tough <br />
<input type="button" id="storeTraits" value="SUBMIT" /> <br />
</form>
<hr />
<h2>Here is what I suggest</h2>
<p id="feedback">Feedback goes here.</p>
jQuery code:
// set up variables
var gender;
var age;
var string;
$(document).ready(function() {
startGame();
$("#storeTraits").click( function() {
serializeCheckbox();
}
); }
);
function startGame() {
document.getElementById("feedback").innerHTML = "Answer all the questions.";
}
function storeGender(value) {
gender = value;
}
function storeAge(value) {
age = value;
}
function serializeCheckbox() {
// clear out any previous selections
string = [ ];
var inputs = document.getElementsByTagName('input');
for( var i = 0; i < inputs.length; i++ ) {
if(inputs[i].type == "checkbox" && inputs[i].name == "field") {
if(inputs[i].checked == true) {
string.push(inputs[i].value);
}
}
}
checkFeedback();
}
//Limit number of checkbox selections
$(function(){
var max = 2;
var checkboxes = $('input[type="checkbox"]');
checkboxes.change(function(){
var current = checkboxes.filter(':checked').length;
checkboxes.filter(':not(:checked)').prop('disabled', current >= max);
});
});
function checkFeedback() {
if(gender == "Male") {
if (age == "18–22" && string == 11){
document.getElementById("feedback").innerHTML = "test1";
} else if (age == "18–22" && string == 110){
document.getElementById("feedback").innerHTML = "test2";
} else if (age == "18–22" && string == 1100){
document.getElementById("feedback").innerHTML = "test3";
} else if (age == "18–22" && string == 101){
document.getElementById("feedback").innerHTML = "test4";
}
}
}
I found this code on JSFiddle: http://jsfiddle.net/GNDAG/ which is what I want to do for adding together my trait values. However, when I try to incorporate it my conditional statements don't work. How do I add the code from the jsfiddle example and get the conditional statements to work? Thank you!
You need an integer, not a string array. Here's the code you need:
var traits = 0;
$('input[name=field]:checked').each(function () {
traits += parseInt($(this).val(), 10);
});
This will set the "traits" variable to an integer like 1, 11, 101, or 1001.
BTW: The second parameter to parseInt() is the base.
But a few suggestions:
Don't use "string" as a variable name.
Use radio buttons for gender and age.
Put all the input elements in the form.
Have one button that submits the form.
Attach a handler to the form submit event, and do your processing in that function, but call e.preventDefault() to prevent the form from submitting to the server. Alternatively, you could have the single button not be a submit button and attach an on-click handler to it.
Here's a jsfiddle with the code above and all the suggestions implemented.

Categories