I'm trying to make a simple quiz with radio button options. The quiz has one button that should dynamically remove and add the next question, and set of radio buttons. The questions and options stored in separate arrays. I am stuck on trying to connect each option with a radio button. Any ideas how to go about with this?
P.S. Just started learning JS as you might tell from my code
<script type="text/javascript">
var questionsArray = new Array();
questionsArray[0] = "1. Who's the president of the US?";
questionsArray[1] = "2. What is the capital city of France?";
questionsArray[2] = "3. What is your favorite food?";
var choicesArray = new Array();
choicesArray[0] = ["Lebron James", "Barack Obama", "George Bush","George Clooney"];
choicesArray[1] = ["Nairobi","London","Paris","Sydney"];
choicesArray[2] = ["Pizza","Sushi","Pasta","Lobster"];
function createRadioElement(name){
var radioHTML = '<input type="radio" name="'+name+'"'+'/>';
var radioFragment = document.createElement("div");
radioFragment.innerHTML = radioHTML;
return radioFragment.firstChild;
}
var index = -1;
function questionSwapOnclick(){
while(index < questionsArray.length){
index++;
document.getElementById("question").innerHTML = questionsArray[index];
if(document.getElementById("question").innerHTML == "undefined"){
document.getElementById("question").innerHTML = "Finished the quiz!"
document.getElementById("choices").innerHTML = ""
}
var splitChoices = choicesArray[index].join("<br />");
document.getElementById("choices").innerHTML = splitChoices;
return true;
}
}
</script>
Why not keep the questions in the html?
JS Fiddle
<form id="questions">
<div class="question active">
<p>1. Who's the president of the US?</p>
<label>
<input type="radio" name="q1" value="1">Lebron James</label>
<label>
<input type="radio" name="q1" value="2">Barack Obama</label>
<label>
<input type="radio" name="q1" value="3">George Bush</label>
</div>
<div class="question" style="display: none;">
<p>2. What is the capital city of France?</p><label>
<input type="radio" name="q2" value="1">Nairobi</label>
<label>
<input type="radio" name="q2" value="2">London</label>
<label>
<input type="radio" name="q2" value="3">Paris</label>
</div>
<div class="question" style="display: none;">
<p>3. What is your favorite food?</p>
<input type="radio" name="q3" value="1">Pizza</label>
<label>
<input type="radio" name="q3" value="2">Sushi</label>
<label>
<input type="radio" name="q3" value="3">Pasta</label>
</div>
<hr> Next question ยป
// used jquery 1.11.0
$(function () {
var questions = $('#questions');
var next_btn = $('#next');
next_btn.on('click', function () {
var active_question = questions.find('.active');
if (active_question.find('input[type=radio]:checked').length) {
active_question.slideUp(500, function(){
active_question.removeClass('active');
});
if(active_question.next('.question').length){
active_question.next('.question').addClass('active').slideDown(500);
}
else {
alert('Thank you!');
alert(questions.serialize());
questions.hide();
}
}
else {
alert('Select answer!');
}
});
});
Related
I am trying to make a small quiz web app using javascript/html. The individual questions on the page are separated by div tags with the same "quiz" class. There are 2 buttons on the page, a previous and a next button. Depending on what the user clicks, the page will display the next quiz on the page by hiding/showing the divs. What I am trying to do is add an input validation to the application. Before the user moves onto the next question I want to make it so that one radio button must be selected, otherwise show an alert box. The radio buttons that belong to the same question all have the same class (i.e. the radio buttons for question 1 all have the same class quiz1). Currently app is able to check which input has been selected (by using if element.checked). Following this logic, I tried using if(!element.checked) create an alert, however the alert box get stuck in a loop. Thus, so far the only other solution I have been able to come up with is to check if at least one radio button within the same class has been selected, which I am unsure how to achieve.
let savedAns = [];
const nextBtn = document.getElementById('next');
const prevBtn = document.getElementById('prev');
const quizes = document.querySelectorAll('.quiz');
const form = document.querySelector('form');
const inputEl = document.querySelectorAll('input');
const total = quizes.length;
//a variable to increment the classes
let ind = 0;
//get all the input elements for each question, assign a class
quizes.forEach(function(element) {
ind++;
let inputs = element.querySelectorAll('input');
inputs.forEach((input) => {
input.classList.add(`quiz${ind}`)
})
})
//keep a track of which question is visible
let count = 0;
//function to hide all the quizes
const hide = function() {
quizes.forEach((element) => {
element.style.display = 'none'
})
}
//show and hide divs when user presses next
nextBtn.addEventListener('click', function() {
if (count < total - 1) {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
count++;
} else {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
alert('no more questions left')
return
}
hide();
quizes[count].style.display = 'block'
})
prevBtn.addEventListener('click', function() {
if (count > 0) {
count--;
} else {
alert('no more previous questions')
return
}
hide();
quizes[count].style.display = 'block'
})
<div class="content">
<form>
<div class="quiz">
<p>Question 1</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 2</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 3</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 4</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
</form>
<button id="prev">Prev</button>
<button id="next">Next</button>
</div>
If there are any other ways to solve the problem, hints towards the right direction is greatly appreciated. I am also writing this application using purely javascript so no jquery please. Thank you.
Since you already know which question is active currently, you can check if any of the input under the active question is checked.
let selectedAnswer = -1;
const activeInputs = quizes[count].querySelectorAll('input');
activeInputs.forEach((input, index) => {
if(input.checked) selectedAnswer = index;
});
if (selectedAnswer === -1) {
alert('Select answer');
return;
}
below is the working code snippet.
let savedAns = [];
const nextBtn = document.getElementById('next');
const prevBtn = document.getElementById('prev');
const quizes = document.querySelectorAll('.quiz');
const form = document.querySelector('form');
const inputEl = document.querySelectorAll('input');
const total = quizes.length;
//a variable to increment the classes
let ind = 0;
//get all the input elements for each question, assign a class
quizes.forEach(function(element) {
ind++;
let inputs = element.querySelectorAll('input');
inputs.forEach((input) => {
input.classList.add(`quiz${ind}`)
})
})
//keep a track of which question is visible
let count = 0;
//function to hide all the quizes
const hide = function() {
quizes.forEach((element) => {
element.style.display = 'none'
})
}
//show and hide divs when user presses next
nextBtn.addEventListener('click', function() {
let selectedAnswer = -1;
const activeInputs = quizes[count].querySelectorAll('input');
activeInputs.forEach((input, index) => {
if(input.checked) selectedAnswer = index;
});
if (selectedAnswer === -1) {
alert('Select answer');
return;
}
if (count < total - 1) {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
count++;
} else {
inputEl.forEach(function(element) {
if (element.checked) {
savedAns[count] = element.value;
console.log(savedAns)
}
})
alert('no more questions left')
return
}
hide();
quizes[count].style.display = 'block'
})
prevBtn.addEventListener('click', function() {
if (count > 0) {
count--;
} else {
alert('no more previous questions')
return
}
hide();
quizes[count].style.display = 'block'
})
<div class="content">
<form>
<div class="quiz">
<p>Question 1</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 2</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 3</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 4</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
</form>
<button id="prev">Prev</button>
<button id="next">Next</button>
</div>
Below is the code of a sample radio button quiz where multiple radio buttons are provided. Correct answers and wrong answers are defined in the code. User may check any answer or keep all blank. If user checks any radio button and finally clicks "Grade Me" button, label text of radio button of any wrong answers checked by the user shall appear as red and at the same time correct answer of that particular question shall appear in green (This will help the user know which question he answered wrong and what is its correct answer). I have tried several steps and searched many forums and failed. I think it will be really simple.
Example:
var numQues = 3;
var numChoi = 3;
var answers = new Array(3);
answers[0] = "doesn't like";
answers[1] = "don't come";
answers[2] = "come";
var wrong = new Array(3);
wrong[0] = "don't like";
wrong[1] = "doesn't come";
wrong[2] = "comes";
var wrong1 = new Array(3);
wrong1[0] = "doesn't likes";
wrong1[1] = "doesn't comes";
wrong1[2] = "coming";
function getScore(form) {
var score = 0;
var currElt;
var currSelection;
for (i = 0; i < numQues; i++) {
currElt = i * numChoi;
answered = false;
for (j = 0; j < numChoi; j++) {
currSelection = form.elements[currElt + j];
if (currSelection.checked) {
answered = true;
if (currSelection.value == answers[i]) {
score += 3;
break;
}
if (currSelection.value == wrong[i]) {
score -= 1;
break;
}
if (currSelection.value == wrong1[i]) {
score -= 1;
break;
}
}
}
}
var scoreper = Math.round(score * 100 / 9);
form.percentage.value = scoreper + "%";
form.mark.value = score;
}
<title>Quiz Questions And Answers</title>
<center>
<h1>Quiz Questions</h1>
</center>
<p>
<form name="quiz">
<p>
<b><br>1. He -------------------- it.<br></b>
<label><input type="radio" name="q1" value="don't like">don't like</label><br>
<label><input type="radio" name="q1" value="doesn't like">doesn't like</label><br>
<label><input type="radio" name="q1" value="doesn't likes">doesn't likes</label><br>
<p><b>
<hr>
<br>2. They -------------------- here very often.<br></b>
<label><input type="radio" name="q2" value="don't come">don't come</label><br>
<label><input type="radio" name="q2" value="doesn't come">doesn't come</label><br>
<label><input type="radio" name="q2" value="doesn't comes">doesn't comes</label><br>
<p><b>
<hr>
<br>3. John and Mary -------------------- twice a week.<br></b>
<label><input type="radio" name="q3" value="come">come</label><br>
<label><input type="radio" name="q3" value="comes">comes</label><br>
<label><input type="radio" name="q3" value="coming">coming</label>
<br>
<p><b>
<hr>
<p><b>
<input type="button"value="Grade Me"onClick="getScore(this.form);">
<input type="reset" value="Clear"><p>
Number of score out of 15 = <input type= text size 15 name= "mark">
Score in percentage = <input type=text size=15 name="percentage"><br>
</form>
<p>
<form method="post" name="Form" onsubmit="" action="">
</form>
Here is a rewrite of your code.
I fixed the illegal HTML and used best practices with event listeners, querySelectors and CSS
Please study the code and see if you understand. I can add more comments if needed
var answers = ["doesn't like","don't come","come"];
var rads, quiz; // need to be set after load
window.addEventListener("load",function() { // when page loads
quiz = document.getElementById("quiz");
rads = quiz.querySelectorAll("input[type=radio]"); // all radios in the quiz
document.getElementById("scoreButton").addEventListener("click",function(e) { // on click of scoreme
var score = 0;
for (var i=0;i<rads.length;i++) { // loop over all radios in the form
var rad = rads[i];
var idx = rad.name.substring(1)-1; //remove the q from the name - JS arrays start at 0
var checked = rad.checked;
var correct = rad.value==answers[idx];
if (correct) {
rad.closest("label").classList.toggle("correct");
if (checked) score +=3;
}
else if (checked) {
score--;
rad.closest("label").classList.toggle("error")
}
}
var scoreper = Math.round(score * 100 / rads.length);
document.querySelector("#percentage").innerHTML = scoreper + "%";
quiz.mark.value = score;
});
});
.correct {
color: green
}
.error {
color: red
}
<title>Quiz Questions And Answers</title>
<div class="header">
<h1>Quiz Questions</h1>
</div>
<form id="quiz">
<div class="questions">
<p>
<b>1. He -------------------- it.</b><br/>
<label><input type="radio" name="q1" value="don't like" />don't like</label><br/>
<label><input type="radio" name="q1" value="doesn't like" />doesn't like</label><br/>
<label><input type="radio" name="q1" value="doesn't likes" />doesn't likes</label>
</p>
<hr>
<p><b>2. They -------------------- here very often.</b><br/>
<label><input type="radio" name="q2" value="don't come">don't come</label><br/>
<label><input type="radio" name="q2" value="doesn't come">doesn't come</label><br/>
<label><input type="radio" name="q2" value="doesn't comes">doesn't comes</label>
</p>
<hr>
<p><b>3. John and Mary -------------------- twice a week.</b><br/>
<label><input type="radio" name="q3" value="come">come</label><br/>
<label><input type="radio" name="q3" value="comes">comes</label><br/>
<label><input type="radio" name="q3" value="coming">coming</label><br/>
</p>
<hr>
<p>
<input type="button" value="Grade Me" id="scoreButton">
<input type="reset" value="Clear"><br/>
Number of score out of 15 = <input type="text" size="15" id="mark">
Score in percentage = <span id="percentage"></span>
<p>
</div>
</form>
In your getScore function, when you find out that a certain element has a correct answer selected (whichever var is the label - unless you are using a custom radio button which I would recommend since changing the background of the label element would simply highlight the words), you can give it a new class using JS.
currSelection.classList.add("correct");
or
currSelection.classList.add("incorrect");
Then in your CSS file you can have rules saying
.correct { background: green !important; }
.incorrect { background: red !important; }
WoW!....Close....Thanks for support. But still all the wrong answers are showing red color. This will let the user know which question he answered wrong. That part is Okay. But once the wrong answers are marked with red(I mean only the wrongly selected radio button choice texts and not the entire question and answer choices
the correct answer of that wrong attempt to be shown in green to enlighten the user. And the sad part is that I again failed with the CSS thing. I wanted to create a quiz in blog and added custom CSS with conditional tag in html of blogger post.....Not Working. However, I will add the modified code here so that you get a clear picture if I am doing rightly as you said.(How and where to add the CSS rules inside this code(if that is what you mean))
var answers = ["doesn't like", "don't come", "come"];
var rads, quiz; // need to be set after load
window.addEventListener("load", function() { // when page loads
quiz = document.getElementById("quiz");
rads = quiz.querySelectorAll("input[type=radio]"); // all radios in the quiz
document.getElementById("scoreButton").addEventListener("click", function(e) { // on submit
var score = 0;
var checked = quiz.querySelectorAll("input[type=radio]:checked"); // all checked radios
for (var i = 0; i < checked.length; i++) { // loop over all checked radios in the form
var idx = checked[i].name.substring(1) - 1; //remove the q from the name - JS arrays start at 0
var correct = checked[i].value == answers[idx];
checked[i].closest("p").classList.toggle("error", !correct)
checked[i].closest("p").classList.toggle("correct", correct)
score += correct ? 3 : -1; // this is called a ternary
}
var scoreper = Math.round(score * 100 / rads.length);
document.querySelector("#percentage").innerHTML = scoreper + "%";
quiz.mark.value = score;
});
});
<!DOCTYPE HTML>
<html>
<body>
<title>Quiz Questions And Answers</title>
<div class="header">
<h1>Quiz Questions</h1>
</div>
<form id="quiz">
<div class="questions">
<p>
<b>1. He -------------------- it.</b><br/>
<label><input type="radio" name="q1" value="don't like" />don't like</label><br/>
<label><input type="radio" name="q1" value="doesn't https://stackoverflow.com/questions/53818896/change-label-text-of-all-radio-button-in-quiz-as-red-and-green/59801712#like" />doesn't like</label><br/>
<label><input type="radio" name="q1" value="doesn't likes" />doesn't likes</label>
</p>
<hr>
<p><b>2. They -------------------- here very often.</b><br/>
<label><input type="radio" name="q2" value="don't come">don't come</label><br/>
<label><input type="radio" name="q2" value="doesn't come">doesn't come</label><br/>
<label><input type="radio" name="q2" value="doesn't comes">doesn't comes</label>
</p>
<hr>
<p><b>3. John and Mary -------------------- twice a week.</b><br/>
<label><input type="radio" name="q3" value="come">come</label><br/>
<label><input type="radio" name="q3" value="comes">comes</label><br/>
<label><input type="radio" name="q3" value="coming">coming</label><br/>
</p>
<hr>
<p>
<input type="button" value="Grade Me" id="scoreButton">
<input type="reset" value="Clear"><br/> Number of score out of 15 = <input type="text" size="15" id="mark"> Score in percentage = <span id="percentage"></span>
<p>
</div>
</form>
</body>
</html>
You can try this:
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
var coffee = document.forms[0];
var txt = "";
var i;
for (i = 0; i < coffee.length; i++) {
if (coffee[i].checked) {
document.getElementById("score"+i).style.color = "green";
document.getElementById("order").value = "You Clicked Option " + i;
}
} }
</script>
</head>
<body>
<div id="score1" style="font-size: 50px">1</div>
<div id="score2" style="font-size: 50px">2</div>
<div id="score3" style="font-size: 50px">3</div>
<div id="score4" style="font-size: 50px">4</div>
**<form action="/action_page.php">
<input type="text" id="order" size="50">
<br>
<input type="radio" name="coffee" value="1" onclick="myFunction()">Option 1<br>
<input type="radio" name="coffee" value="2" onclick="myFunction()">Option 2<br>
<input type="radio" name="coffee" value="3" onclick="myFunction()">Option 3<br>
<input type="radio" name="coffee" value="4" onclick="myFunction()">Option 4<br>
</form>**
</body>
</html>
I am trying to make a Js to search & filter items in JSON
so I use many radio in the "form" , the result will be [X,X,X,X,X,X]
I will set 50tags x 3(choose), I can feel my function will be large.
What ways can I change my function to be simpler?
function myFunction() {
var elements1 = document.getElementsByName("chair"),
elements2 = document.getElementsByName("car"),
elements3 = document.getElementsByName("house"),
elements4 = document.getElementsByName("tree"),
elements5 = document.getElementsByName("flower"),
elements6 = document.getElementsByName("grass");
var i;
for (var a = "", i = elements1.length; i--;) {
if (elements1[i].checked) {
var a = elements1[i].value;
break;
}
};
for (var b = "", i = elements2.length; i--;) {
if (elements2[i].checked) {
var b = elements2[i].value;
break;
}
};
for (var c = "", i = elements3.length; i--;) {
if (elements3[i].checked) {
var c = elements3[i].value;
break;
}
};
for (var d = "", i = elements4.length; i--;) {
if (elements4[i].checked) {
var d = elements4[i].value;
break;
}
};
for (var e = "", i = elements5.length; i--;) {
if (elements5[i].checked) {
var e = elements5[i].value;
break;
}
};
for (var f = "", i = elements6.length; i--;) {
if (elements6[i].checked) {
var f = elements6[i].value;
break;
}
};
var o2 = document.getElementById("output2");
o2.value = "[" + a + "," + b + "," + c + "," + d + "," + e + "," + f + "]";
o2.innerHTML = o2.value;
}
<form><input type="radio" id="chair1" name="chair" class="chair" value="1">
<input type="radio" id="chair0" name="chair" class="chair" value="0" checked>
<input type="radio" id="chair-1" name="chair" class="chair" value="-1">
<input type="radio" id="car1" name="car" class="car" value="1">
<input type="radio" id="car0" name="car" class="car" value="0" checked>
<input type="radio" id="car-1" name="car" class="car" value="-1">
<input type="radio" id="house1" name="house" class="house" value="1">
<input type="radio" id="house0" name="house" class="house" value="0" checked>
<input type="radio" id="house-1" name="house" class="house" value="-1">
<input type="radio" id="tree1" name="tree" class="tree" value="1">
<input type="radio" id="tree0" name="tree" class="tree" value="0" checked>
<input type="radio" id="tree-1" name="tree" class="tree" value="-1">
<input type="radio" id="flower1" name="flower" class="flower" value="1">
<input type="radio" id="flower0" name="flower" class="flower" value="0" checked>
<input type="radio" id="flower-1" name="flower" class="flower" value="-1">
<input type="radio" id="grass1" name="grass" class="grass" value="1">
<input type="radio" id="grass0" name="grass" class="grass" value="0" checked>
<input type="radio" id="grass-1" name="grass" class="grass" value="-1">
<div> <input type="button" value="Search" id="filter" onclick="myFunction()" /> </div>
</form>
<div id="output2"></div>
Give the form an id, and you can refer to it as an object.
function myFunction() {
var form = document.getElementById("myForm");
var parts = [
form.chair.value,
form.car.value,
form.house.value,
form.tree.value,
form.flower.value,
form.grass.value
];
var o2 = document.getElementById("output2");
o2.innerHTML = '[' + parts.join(',') + ']';
}
And this is an even simpler solution using a FormData object. It supports an arbitrary number of named form fields without having to actually name them in the function:
function myFunction() {
var myForm = document.getElementById('myForm');
var formData = new FormData(myForm);
var parts = Array.from(formData.values());
var o2 = document.getElementById("output2");
o2.innerHTML = '[' + parts.join(',') + ']';
}
Use document.querySelector() to directly select the value of the checked radio button based on element names.
function myFunction() {
var chair = document.querySelector('input[name="chair"]:checked').value;
var car = document.querySelector('input[name="car"]:checked').value;
var house = document.querySelector('input[name="house"]:checked').value;
var tree = document.querySelector('input[name="tree"]:checked').value;
var flower = document.querySelector('input[name="flower"]:checked').value;
var grass = document.querySelector('input[name="grass"]:checked').value;
var o2 = document.getElementById("output2");
o2.value = "[" + chair + "," + car + "," + house + "," + tree + "," + flower + "," + grass + "]";
o2.innerHTML = o2.value;
}
Use arrays!
function myFunction() {
var elem_ids = [ "chair", "car", "house", "tree", "flower", "grass"];
var elems = elem_ids.map(id => document.getElementById(id));
var elems_check_values = elems.map(el => {
// el is kind of an array so
for(var i = 0; i < el.length; ++i)
if(el[i].checked)
return el[i].value;
return undefined;
}).filter(value => value == undefined) // to filter undefined values;
var output = "[" + elems_check_values.join(",") + "]";
var o2 = document.getElementById("output2");
o2.innerHTML = output
}
Your issue can be generalized to: how can I aggregate values for all fields in a given form?
The solution is a function that can be merely as long as 5 lines, and work for any amount of inputs with any type. The DOM model for <form> elements provides named keys (eg, myform.inputName) which each have a value property. For radio buttons, eg myform.tree.value will automatically provide the value of the selected radio button.
With this knowledge, you can create a function with a simple signature that takes a form HTMLElement, and an array of field names for the values that you need, like below: (hit the search button for results, and feel free to change the radio buttons).
function getFormValues(form, fields) {
var result = [];
for (var i = 0; i < fields.length; i++) {
result.push(form[fields[i]].value);
}
return result;
}
document.getElementById('filter').addEventListener('click', function(e) {
var o2 = document.getElementById("output2");
o2.innerHTML = getFormValues(document.forms[0], ['chair','car','house','tree','flower','grass']);
});
<form><input type="radio" id="chair1" name="chair" class="chair" value="1">
<input type="radio" id="chair0" name="chair" class="chair" value="0" checked>
<input type="radio" id="chair-1" name="chair" class="chair" value="-1">
<input type="radio" id="car1" name="car" class="car" value="1">
<input type="radio" id="car0" name="car" class="car" value="0" checked>
<input type="radio" id="car-1" name="car" class="car" value="-1">
<input type="radio" id="house1" name="house" class="house" value="1">
<input type="radio" id="house0" name="house" class="house" value="0" checked>
<input type="radio" id="house-1" name="house" class="house" value="-1">
<input type="radio" id="tree1" name="tree" class="tree" value="1">
<input type="radio" id="tree0" name="tree" class="tree" value="0" checked>
<input type="radio" id="tree-1" name="tree" class="tree" value="-1">
<input type="radio" id="flower1" name="flower" class="flower" value="1">
<input type="radio" id="flower0" name="flower" class="flower" value="0" checked>
<input type="radio" id="flower-1" name="flower" class="flower" value="-1">
<input type="radio" id="grass1" name="grass" class="grass" value="1">
<input type="radio" id="grass0" name="grass" class="grass" value="0" checked>
<input type="radio" id="grass-1" name="grass" class="grass" value="-1">
<div> <input type="button" value="Search" id="filter"/> </div>
</form>
<div id="output2"></div>
The thing you need to do is break the code up into reusable chunks. So make a method to get the value. That will reduce a lot of code. After than, you should look at a way to reduce how many elements you need to list. Finally, find an easy way to fetch all the values.
So below is code that does this. It uses a helper method to get the elements, find the value. Than it uses an array to know what element groups to look for. And finally it uses map to iterate over the list so you do not have to code multiple function calls.
function getSelected (radioBtnGroup) {
// get the elements for the radio button group
var elms = document.getElementsByName(radioBtnGroup)
// loop over them
for(var i=0; i<elms.length; i++) {
// if checked, return value and exit loop
if (elms[i].checked) {
return elms[i].value
}
}
// if nothing is selected, return undefined
return undefined
}
// list the groups you want to get the values for
var groups = ['rb1', 'rb2', 'rb3', 'rb4']
// call when you want to get the values
function getValues () {
// use map to get the values of the rabio button groups.
// map passes the index value as the first argument.
// code is map(function(k){return getSelected(k)})
var results = groups.map(getSelected)
//displat the results
console.log(results);
}
document.querySelector('#btn').addEventListener('click', getValues);
<form>
<fieldset>
<legend>Item 1</legend>
<label><input type="radio" name="rb1" value="1-1"> One</label>
<label><input type="radio" name="rb1" value="1-2"> Two</label>
<label><input type="radio" name="rb1" value="1-3"> Three</label>
</fieldset>
<fieldset>
<legend>Item 2</legend>
<label><input type="radio" name="rb2" value="2-1"> One</label>
<label><input type="radio" name="rb2" value="2-2"> Two</label>
<label><input type="radio" name="rb2" value="2-3"> Three</label>
</fieldset>
<fieldset>
<legend>Item 3</legend>
<label><input type="radio" name="rb3" value="3-1"> One</label>
<label><input type="radio" name="rb3" value="3-2"> Two</label>
<label><input type="radio" name="rb3" value="3-3"> Three</label>
</fieldset>
<fieldset>
<legend>Item 4</legend>
<label><input type="radio" name="rb4" value="4-1"> One</label>
<label><input type="radio" name="rb4" value="4-2"> Two</label>
<label><input type="radio" name="rb4" value="4-3"> Three</label>
</fieldset>
<button type="button" id="btn">Get Results</button>
</form>
Personally I would not store the values in an array, I would use an object with key value pairs.
var results = groups.reduce(function (obj, name) {
obj[name] = getSelected(name)
return obj
}, {});
So I got a project here with a couple of radiobuttons. The plan is to be able to select a base, a lining, color and a shading technique. The blue box to the right serves the purpose of giving the customer a live overview of example outcome of the selected parts. I want to place an image there, with a variable URL.
My plan would be to do something like: "https://www.example.com/images/calculator/base+line+color+shading.png"
Where base is gotten from the base radio input, and could be for example "fullbody"Where line is gotten from the line radio input, and could be for example "clean"Where color is gotten from the color radio input, and could be for example "colored"Where shading is gotten from the shading radio input, and could be for example "ccel"This would leave us with a variable url of "https://www.example.com/images/calculator/fullbody+clean+colored+ccel.png"
At the same time, I don't want them to have to select all of the inputs to get an overview, if they only select "fullbody", the variable URL should become "https://www.example.com/images/calculator/fullbody.png"
The artist I'm doing this for is rapidly increasing the product base and style choices, and I will be updating it over time, so a solution that is expandable with more options over time would be amazing.
As always, thank you for taking your time to read over, any answers or tips/tricks/hints or pointing in directions is greatly appreciated! Enjoy the weekend folks! <3
small overview of my project layout
data-position="1" is for base group
data-position="2" is for line group
data-position="3" is for color group
data-position="4" is for shade group
..
..
data-position="k" will be for kth value group and so on...
See working example here https://jsfiddle.net/y2khfjwp/40/
<div style="width: 50%; float: Left;">
<h2>
Base
</h2>
<input type="radio" name="base" class="main-inputs" data-position="1" value="fullbody" onchange="makeImage(this)"/>Full Body<br>
<input type="radio" name="base" class="main-inputs" data-position="1" value="halfbody" onchange="makeImage(this)"/>Half Body<br>
<input type="radio" name="base" class="main-inputs" data-position="1" value="xyzbody" onchange="makeImage(this)"/>xyz Body<br>
<input type="radio" name="base" class="main-inputs" data-position="1" value="abcbody" onchange="makeImage(this)"/>abc body<br>
<hr>
<h2>
Line
</h2>
<input type="radio" name="line" class="main-inputs" data-position="2" value="clean" onchange="makeImage(this)"/>Clean<br>
<input type="radio" name="line" class="main-inputs" data-position="2" value="clean2" onchange="makeImage(this)"/>Clean2<br>
<input type="radio" name="line" class="main-inputs" data-position="2" value="clean3" onchange="makeImage(this)"/>Clean3<br>
<input type="radio" name="line" class="main-inputs" data-position="2" value="clean4" onchange="makeImage(this)"/>Clean4<br>
<hr>
<h2>
Color
</h2>
<input type="radio" name="color" class="main-inputs" data-position="3" value="colored" onchange="makeImage(this)"/>Colored<br>
<input type="radio" name="color" class="main-inputs" data-position="3" value="colored2" onchange="makeImage(this)"/>Colored2<br>
<input type="radio" name="color" class="main-inputs" data-position="3" value="colored3" onchange="makeImage(this)"/>Colored3<br>
<input type="radio" name="color" class="main-inputs" data-position="3" value="colored4" onchange="makeImage(this)"/>Colored4<br>
<hr>
<h2>
Shade
</h2>
<input type="radio" name="shade" class="main-inputs" data-position="4" value="ccel" onchange="makeImage(this)"/>Ccel<br>
<input type="radio" name="shade" class="main-inputs" data-position="4" value="ccel2" onchange="makeImage(this)"/>Ccel2<br>
<input type="radio" name="shade" class="main-inputs" data-position="4" value="ccel3" onchange="makeImage(this)"/>Ccel3<br>
<input type="radio" name="shade" class="main-inputs" data-position="4" value="ccel4" onchange="makeImage(this)"/>Ccel4<br>
</div>
<div style="width: 50%; float: Right;">
OutPut: <img id="final-output-src" src="Please select Options" /><br><span id="final-output">Please select Options</span>
</div>
<script>
var path = [];
function makeImage(element)
{
var imagePath = "";
path[element.getAttribute('data-position')] = element.value;
imagePath = finalImagePath();
document.getElementById("final-output-src").src = imagePath;
document.getElementById("final-output").innerHTML = imagePath;
};
function finalImagePath() {
var imageSrc = "https://www.example.com/images/calculator/";
var selections = "";
for(var i=1 ; i<=path.length ; i++) {
if(typeof path[i] != 'undefined' && path[i] != '') {
if(selections == "") {
selections = selections + path[i];
} else {
selections = selections + "+" + path[i];
}
}
}
if(selections != "") {
selections = selections + ".png";
imageSrc = imageSrc + selections;
}
return imageSrc;
}
</script>
Okay here is a solution to generate the image url:
const partials = document.querySelectorAll('#partials input');
const fullBody = document.getElementById('fullbody');
const baseUrl = 'some-root-url.com/';
const fileType = '.png';
let imageUrl = baseUrl + 'some-default-url' + fileType;
// Add Event Listeners
fullBody.addEventListener('change', function(){
let checked = document.querySelectorAll('#partials input:checked');
// deselect each partial
for(let i = 0; i < checked.length; i++){
checked[i].checked = false;
}
// Set the imageUrl var to the fullbody
imageUrl = baseUrl + this.value + fileType;
// see the imageUrl!
console.log(imageUrl);
});
for(let i = 0; i < partials.length; i++){
partials[i].addEventListener('change', function(){
// uncheck fullBody if checked
fullBody.checked = false;
// init the imageUrl
imageUrl = baseUrl;
// loop through each checked option and add the value to the imageUrl
let checked = document.querySelectorAll('#partials input:checked');
for(let i = 0; i < checked.length; i++){
imageUrl += checked[i].value;
}
// add the file type
imageUrl += fileType;
// see the imageUrl!
console.log(imageUrl)
});
}
And here's the corresponding HTML
<div id="partials">
<label for="base">Base</label><input name="base" type="checkbox" value="base" /><br />
<label for="line">Line</label><input name="line" type="checkbox" value="line" /><br />
<label for="color">Color</label><input name="color" type="checkbox" value="color" /><br />
<label for="Shading">Shading</label><input name="shading" type="checkbox" value="shading" />
</div>
<label for="fullbody">Full Body</label><input name="fullbody" id="fullbody" type="checkbox" value="fullbody" />
And a JSFiddle to demo
One tip for you as well, you want to use checkboxes not radio, as radio are designed for single choices not multiselect.
Hope that helps!
I am trying to make a dog race.
Basically what I want is to check what radio the user checked,
compare it to a random number between 1 - 5 and see if he won.
My question is... How do I compare them?
This is my code so far.
function chooser(){
var theDogs = ["dog1","dog2","dog3","dog4","dog5"],
rand = theDogs[Math.floor(Math.random() * theDogs.length)];
document.getElementById("winner").innerHTML = rand;
if(pick == rand)
{document.getElementById("winner").innerHTML =("win!");}
else {
document.getElementById("winner").innerHTML =("loose");
}
}
HTML:
<form id="pick" action="rand">
<input type="radio" name="dog" id="dog1">Dog1<br>
<input type="radio" name="dog" id="dog2">Dog2<br>
<input type="radio" name="dog" id="dog3">Dog3<br>
<input type="radio" name="dog" id="dog4">Dog4<br>
<input type="radio" name="dog" id="dog5">Dog5<br>
</form>
<br>
<br>
<input type="submit" value="Gamble" onclick="chooser();">
<br>
<p id="winner"> </p>
A jQuery and Native JavaScript Approach. Take your pick.
$("#submitjq").click(function() {
var theDogs = ["dog1","dog2","dog3","dog4","dog5"],
rand = theDogs[Math.floor(Math.random() * theDogs.length)];
var pick = $("input[type=radio][name='dog']:checked").val();
if(pick == rand)
{
$("#winner").html("jQuery: Won!");
}
else {
$("#winner").html("jQuery: Lost!");
}
});
document.getElementById('submitjs').onclick = function () {
var theDogs = ["dog1","dog2","dog3","dog4","dog5"],
rand = theDogs[Math.floor(Math.random() * theDogs.length)];
var pick = document.pick.dog.value;
console.log(pick);
if(pick == rand)
{
document.getElementById("winner").innerHTML = "JavaScript: Won!" ;
}
else {
document.getElementById("winner").innerHTML = "JavaScript: Lost!" ;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="pick" name="pick" action="rand">
<input type="radio" name="dog" value="dog1">Dog1<br>
<input type="radio" name="dog" value="dog2">Dog2<br>
<input type="radio" name="dog" value="dog3">Dog3<br>
<input type="radio" name="dog" value="dog4">Dog4<br>
<input type="radio" name="dog" value="dog5">Dog5<br>
</form>
<br>
<br>
<input type="submit" id="submitjs" value="Gamble Native JavaScript" />
<input type="submit" id="submitjq" value="Gamble jQuery" />
<br>
<p id="winner"> </p>
You need to give each radio button a value, and then getElementsByName, iterating through to find the one that's checked. See similar thread...