JS function resets after completion - javascript

I have a small form designed to calculate a score based on the answers given. Everything works, the variables are shown in the variables and also shown in the html for a split second. However, after a split second, the function resets and the resulting var is also removed. In trying to understand, I think it has to do with the scope of the var or form behavior? Here is a snippet:
</head>
<body>
<form id="calculateChangeForm" name="calculateChangeForm">
<p><strong>1. To what extend does the change impact the organization?</strong></p>
<input id="q1a1" name="q1" type="radio" value="2"> <label for="q1a1">A specific department or a working group</label><br><input id="q1a2" name="q1" type="radio" value="6"> <label for="q1a2">One department </label><br><input id="q1a3" name="q1" type="radio" value="7"> <label for="q1a3">Several departments</label><br><input id="q1a4" name="q1" type="radio" value="8"> <label for="q1a4">Whole organization</label><br><input id="q1a5" name="q1" type="radio" value="8"> <label for="q1a5">Cross entities</label><br><input id="q1a6" name="q1" type="radio" value="9"> <label for="q1a6">Regional Impact</label><br><input id="q1a7" name="q1" type="radio" value="10"> <label for="q1a7">Group Impact</label><hr class="mb-5 mt-5">
<p><strong>2. How many employees are impacted? </strong></p>
<input id="q2a1" name="q2" type="radio" value="1"> <label for="q2a1"> < 10 </label><br><input id="q2a2" name="q2" type="radio" value="4"> <label for="q2a2">10 - 50 </label><br><input id="q2a3" name="q2" type="radio" value="7"> <label for="q2a3">51 - 100</label><br><input id="q2a4" name="q2" type="radio" value="8"> <label for="q2a4">101 - 200</label><br><input id="q2a5" name="q2" type="radio" value="9"> <label for="q2a5">201 - 500</label><br><input id="q2a6" name="q2" type="radio" value="10"> <label for="q2a6"> > 500 </label><br><br><button id="calculateChangeButton" class="button">Submit</button>
<script> document.getElementById("calculateChangeButton").onclick = function() {calculateChange();}; </script>
</form><hr class="mb-5 mt-5"></div>
<p>Your score is: <span id="changeScore"></span></p>
<script>
var changescore = 0;
function calculateChange(){
var val1 = 0;
for( i = 0; i < document.calculateChangeForm.q1.length; i++ ){
if( document.calculateChangeForm.q1[i].checked == true ){
val1 = document.calculateChangeForm.q1[i].value;
alert("The value of Question 1 answer is: " + val1);
}
}
var val2 = 0;
for( i = 0; i < document.calculateChangeForm.q2.length; i++ ){
if( document.calculateChangeForm.q2[i].checked == true ){
val2 = document.calculateChangeForm.q2[i].value;
alert("The value of Question 2 answer is: " + val2);
}
}
var changescore = parseInt(val1) + parseInt(val2);
alert("The total score: " + changescore);
document.getElementById("changeScore").innerHTML = changescore;
}
</script>
</body>
Thank you,

After input from user t348575, it was clear that the button should be changed to a an input type="button" in order to stop the form from being submitted:

Related

How to display/indicate the right and wrong answers at the end of javascript quiz

as the title suggests I need help with how to display the right and wrong answers at the end of my javascript quiz. I've tried various ways and none seem to work. I've tried highlighting, writing next to and displaying underneath the score however nothing I try seems to work. Any guidance is greatly appreciated thanks x
var total_seconds = 30 * 1;
var c_minutes = parseInt(total_seconds / 60);
var c_seconds = parseInt(total_seconds % 60);
var timer;
function CheckTime() {
document.getElementById("quiz-time-left").innerHTML =
"Time Left: " + c_minutes + " minutes " + c_seconds + " seconds ";
if (total_seconds <= 0) {
score();
} else {
total_seconds = total_seconds - 1;
c_minutes = parseInt(total_seconds / 60);
c_seconds = parseInt(total_seconds % 60);
timer = setTimeout(CheckTime, 1000);
}
}
timer = setTimeout(CheckTime, 1000);
function highlightAnswerWithClass(question, answer, className) {
var answers = document.forms.form[question];
for (var index = 0; index < answers.length; index++) {
if (answers[index].value === answer) {
answers[index].classList.add(className);
}
}
}
function score() {
// stop timer
clearInterval(timer);
//Referencing the value of the questions
var q1 = document.forms.form.q1.value;
var q2 = document.forms.form.q2.value;
var q3 = document.forms.form.q3.value;
var q4 = document.forms.form.q4.value;
var q5 = document.forms.form.q5.value;
var q6 = document.forms.form.q6.value;
// disable form
var elements = document.getElementById("questions").elements;
for (var i = 0, len = elements.length; i < len; ++i) {
elements[i].disabled = true;
}
//Array for the questions
var questions = [q1, q2, q3, q4, q5, q6];
//Answers for each question
var answers = ["b", "b", "b", "b", "b", "b"];
//variable to keep track of the points
var points = 0;
var total = 6;
//max score
//Making use of a for loop to iterate over the questions and answers arrays
for (var i = 0; i < total; i++) {
if (questions[i] == answers[i]) {
points = points + 2; //Increment the score by 2 for every correct answer given
alert(points);
highlightAnswerWithClass(i + 2, questions[i], "correct");
} else {
points = points - 1;
alert(points);
highlightAnswerWithClass(i + 2, questions[i], "incorrect");
highlightAnswerWithClass(i + 2, answers[i], "correct");
}
}
//CSS for questions
if (points >= 4) {
document.body.style.backgroundColor = "rgba(0,255,0,0.2)";
} else {
document.body.style.backgroundColor = "rgba(255,0,0,0.1)";
}
var q = document.getElementById("p");
q.style.fontSize = "40px";
q.style.textAlign = "center";
q.innerHTML =
"You got " +
points +
" out of " +
total +
"<br />" +
"you used " +
(29 - Math.floor(total_seconds)) +
" seconds";
return false;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body bgcolor="lightblue">
<div id="quiz-time-left"></div>
<form name="form" id="questions" onsubmit="return false;">
<h3>1. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q1" value="a" />a. 1<br />
<input type="radio" name="q1" value="b" />b. 2<br />
<input type="radio" name="q1" value="c" />c. 3<br />
<input type="radio" name="q1" value="d" />d. 4<br />
<h3>2. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q2" value="a" />a. 1<br />
<input type="radio" name="q2" value="b" />b. 2<br />
<input type="radio" name="q2" value="c" />c. 3<br />
<input type="radio" name="q2" value="d" />d. 4<br />
<h3>3. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q3" value="a" />a. 1<br />
<input type="radio" name="q3" value="b" />b. 2<br />
<input type="radio" name="q3" value="c" />c. 3<br />
<input type="radio" name="q3" value="d" />d. 4<br />
<h3>4. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q4" value="a" />a. 1<br />
<input type="radio" name="q4" value="b" />b. 2<br />
<input type="radio" name="q4" value="c" />c. 3<br />
<input type="radio" name="q4" value="d" />d. 4<br />
<h3>5. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q5" value="a" />a. 1<br />
<input type="radio" name="q5" value="b" />b. 2<br />
<input type="radio" name="q5" value="c" />c. 3<br />
<input type="radio" name="q5" value="d" />d. 4<br />
<h3>6. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q6" value="a" />a. 1<br />
<input type="radio" name="q6" value="b" />b. 2<br />
<input type="radio" name="q6" value="c" />c. 3<br />
<input type="radio" name="q6" value="d" />d. 4<br />
<br />
<input type="submit" id="sendA" value="Submit" onclick="score();" />
<br />
<p id="p"></p>
</form>
</body>
</html>
You should wrap value to label value, and use nextSiblingto set color for label.
I updated for high light all correct answer.
answers[index].nextSibling.style.backgroundColor = "red";
var total_seconds = 30 * 1;
var c_minutes = parseInt(total_seconds / 60);
var c_seconds = parseInt(total_seconds % 60);
var timer;
function CheckTime() {
document.getElementById("quiz-time-left").innerHTML =
"Time Left: " + c_minutes + " minutes " + c_seconds + " seconds ";
if (total_seconds <= 0) {
score();
} else {
total_seconds = total_seconds - 1;
c_minutes = parseInt(total_seconds / 60);
c_seconds = parseInt(total_seconds % 60);
timer = setTimeout(CheckTime, 1000);
}
}
timer = setTimeout(CheckTime, 1000);
function highlightAnswerWithClass(question, answer, className) {
var answers = document.forms.form['q'+question];
if(answers == undefined) return;
for (var index = 0; index < answers.length; index++) {
if (answers[index] != null && answers[index].value === answer) {
answers[index].classList.add(className);
if(answers[index].nextSibling.style != undefined) answers[index].nextSibling.style.backgroundColor = "red";
}
}
}
function score() {
// stop timer
clearInterval(timer);
//Referencing the value of the questions
var q1 = document.forms.form.q1.value;
var q2 = document.forms.form.q2.value;
var q3 = document.forms.form.q3.value;
var q4 = document.forms.form.q4.value;
var q5 = document.forms.form.q5.value;
var q6 = document.forms.form.q6.value;
// disable form
var elements = document.getElementById("questions").elements;
for (var i = 0, len = elements.length; i < len; ++i) {
elements[i].disabled = true;
}
//Array for the questions
var questions = [q1, q2, q3, q4, q5, q6];
//Answers for each question
var answers = ["b", "b", "b", "b", "b", "b"];
//variable to keep track of the points
var points = 0;
var total = 6;
//max score
//Making use of a for loop to iterate over the questions and answers arrays
for (var i = 0; i < total; i++) {
if (questions[i] == answers[i]) {
points = points + 2; //Increment the score by 2 for every correct answer given
//alert(points);
highlightAnswerWithClass(i + 1, questions[i], "correct");
} else {
points = points - 1;
//alert(points);
highlightAnswerWithClass(i + 1, questions[i], "incorrect");
highlightAnswerWithClass(i + 1, answers[i], "correct");
}
}
//CSS for questions
if (points >= 4) {
document.body.style.backgroundColor = "rgba(0,255,0,0.2)";
} else {
document.body.style.backgroundColor = "rgba(255,0,0,0.1)";
}
var q = document.getElementById("p");
q.style.fontSize = "40px";
q.style.textAlign = "center";
q.innerHTML =
"You got " +
points +
" out of " +
total +
"<br />" +
"you used " +
(29 - Math.floor(total_seconds)) +
" seconds";
return false;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.correct{
border: 1px solid red;
background-color:red;
}
</style>
</head>
<body bgcolor="lightblue">
<div id="quiz-time-left"></div>
<form name="form" id="questions" onsubmit="return false;">
<h3>1. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q1" value="a" />a. 1<br />
<input type="radio" name="q1" value="b" /><label>b. 2</label><br />
<input type="radio" name="q1" value="c" />c. 3<br />
<input type="radio" name="q1" value="d" />d. 4<br />
<h3>2. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q2" value="a" />a. 1<br />
<input type="radio" name="q2" value="b" /><label>b. 2</label><br />
<input type="radio" name="q2" value="c" />c. 3<br />
<input type="radio" name="q2" value="d" />d. 4<br />
<h3>3. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q3" value="a" />a. 1<br />
<input type="radio" name="q3" value="b" /><label>b. 2</label><br />
<input type="radio" name="q3" value="c" />c. 3<br />
<input type="radio" name="q3" value="d" />d. 4<br />
<h3>4. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q4" value="a" />a. 1<br />
<input type="radio" name="q4" value="b" /><label>b. 2</label><br />
<input type="radio" name="q4" value="c" />c. 3<br />
<input type="radio" name="q4" value="d" />d. 4<br />
<h3>5. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q5" value="a" />a. 1<br />
<input type="radio" name="q5" value="b" /><label>b. 2</label><br />
<input type="radio" name="q5" value="c" />c. 3<br />
<input type="radio" name="q5" value="d" />d. 4<br />
<h3>6. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q6" value="a" />a. 1<br />
<input type="radio" name="q6" value="b" /><label>b. 2</label><br />
<input type="radio" name="q6" value="c" />c. 3<br />
<input type="radio" name="q6" value="d" />d. 4<br />
<br />
<input type="submit" id="sendA" value="Submit" onclick="score();" />
<br />
<p id="p"></p>
</form>
</body>
</html>
Ok, so I ran the snippet and here is the error in the console:
Error: {
"message": "Uncaught ReferenceError: Invalid left-hand side expression in prefix operation",
"filename": "https://stacksnippets.net/js",
"lineno": 132,
"colno": 25
}
The error was in line 132 and column 25.
So I think you should check your code before asking stack overflow and you shouldn't just paste your entire code here. Take out the part you think has a problem and then ask us.
Here I took out the code I believe has an error.
Good Luck!
if (points >= 4) {
document.body.style.backgroundColor = "rgba(0,255,0,0.2)";
} else {
document.body.style.backgroundColor = "rgba(255,0,0,0.1)";
}
Your indexing in answers in highlightAnswerWithClass is not correct. answers is an array of all the inputs in the form, it's not grouped by question. Since there are 4 possible answers to each question, the indexes of the answers for a particular question are question*4 through question*4+3.
I'm not sure why you were adding 2 to the question number when calling that function.
I changed your HTML to put a span around the text of each answer. Then I use CSS to change the background of the color.
var total_seconds = 30 * 1;
var c_minutes = parseInt(total_seconds / 60);
var c_seconds = parseInt(total_seconds % 60);
var timer;
function CheckTime() {
document.getElementById("quiz-time-left").innerHTML =
"Time Left: " + c_minutes + " minutes " + c_seconds + " seconds ";
if (total_seconds <= 0) {
score();
} else {
total_seconds = total_seconds - 1;
c_minutes = parseInt(total_seconds / 60);
c_seconds = parseInt(total_seconds % 60);
timer = setTimeout(CheckTime, 1000);
}
}
timer = setTimeout(CheckTime, 1000);
function highlightAnswerWithClass(question, answer, className) {
var answers = document.forms.form;
for (var index = question*4; index < question*4 + 4; index++) {
if (answers[index].value === answer) {
answers[index].classList.add(className);
}
}
}
function score() {
// stop timer
clearInterval(timer);
//Referencing the value of the questions
var q1 = document.forms.form.q1.value;
var q2 = document.forms.form.q2.value;
var q3 = document.forms.form.q3.value;
var q4 = document.forms.form.q4.value;
var q5 = document.forms.form.q5.value;
var q6 = document.forms.form.q6.value;
// disable form
var elements = document.getElementById("questions").elements;
for (var i = 0, len = elements.length; i < len; ++i) {
elements[i].disabled = true;
}
//Array for the questions
var questions = [q1, q2, q3, q4, q5, q6];
//Answers for each question
var answers = ["b", "b", "b", "b", "b", "b"];
//variable to keep track of the points
var points = 0;
var total = 6;
//max score
//Making use of a for loop to iterate over the questions and answers arrays
for (var i = 0; i < total; i++) {
if (questions[i] == answers[i]) {
points = points + 2; //Increment the score by 2 for every correct answer given
highlightAnswerWithClass(i, questions[i], "correct");
} else {
points = points - 1;
highlightAnswerWithClass(i, questions[i], "incorrect");
highlightAnswerWithClass(i, answers[i], "correct");
}
}
//CSS for questions
if (points >= 4) {
document.body.style.backgroundColor = "rgba(0,255,0,0.2)";
} else {
document.body.style.backgroundColor = "rgba(255,0,0,0.1)";
}
var q = document.getElementById("p");
q.style.fontSize = "40px";
q.style.textAlign = "center";
q.innerHTML =
"You got " +
points +
" out of " +
total +
"<br />" +
"you used " +
(29 - Math.floor(total_seconds)) +
" seconds";
return false;
}
.correct + span {
background-color: green;
}
.incorrect + span {
background-color: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body bgcolor="lightblue">
<div id="quiz-time-left"></div>
<form name="form" id="questions" onsubmit="return false;">
<h3>1. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q1" value="a" /><span>a. 1</span><br />
<input type="radio" name="q1" value="b" /><span>b. 2</span><br />
<input type="radio" name="q1" value="c" /><span>c. 3</span><br />
<input type="radio" name="q1" value="d" /><span>d. 4</span><br />
<h3>2. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q2" value="a" /><span>a. 1</span><br />
<input type="radio" name="q2" value="b" /><span>b. 2</span><br />
<input type="radio" name="q2" value="c" /><span>c. 3</span><br />
<input type="radio" name="q2" value="d" /><span>d. 4</span><br />
<h3>3. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q3" value="a" /><span>a. 1</span><br />
<input type="radio" name="q3" value="b" /><span>b. 2</span><br />
<input type="radio" name="q3" value="c" /><span>c. 3</span><br />
<input type="radio" name="q3" value="d" /><span>d. 4</span><br />
<h3>4. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q4" value="a" /><span>a. 1</span><br />
<input type="radio" name="q4" value="b" /><span>b. 2</span><br />
<input type="radio" name="q4" value="c" /><span>c. 3</span><br />
<input type="radio" name="q4" value="d" /><span>d. 4</span><br />
<h3>5. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q5" value="a" /><span>a. 1</span><br />
<input type="radio" name="q5" value="b" /><span>b. 2</span><br />
<input type="radio" name="q5" value="c" /><span>c. 3</span><br />
<input type="radio" name="q5" value="d" /><span>d. 4</span><br />
<h3>6. How many yellow cards equal a red card in football?</h3>
<input type="radio" name="q6" value="a" /><span>a. 1</span><br />
<input type="radio" name="q6" value="b" /><span>b. 2</span><br />
<input type="radio" name="q6" value="c" /><span>c. 3</span><br />
<input type="radio" name="q6" value="d" /><span>d. 4</span><br />
<span> </span><br />
<input type="submit" id="sendA" value="Submit" onclick="score();" />
<br />
<p id="p"></p>
</form>
</body>
</html>

change label text of all radio button in quiz as red and green

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>

How to be simpler in this JavaScript?

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
}, {});

How Do I count the selected checkbox in AngularJS?

/**
* #Summary: checkAllConnectedUser function, to create album
* #param: index, productObj
* #return: callback(response)
* #Description:
*/
$scope.shardBuyerKeyIdArray = [];
$scope.countBuyer = 0;
$scope.checkAllSharedBuyer = function(isChecked) {
if (isChecked) {
if ($scope.selectAll) {
$scope.selectAll = false;
} else {
$scope.selectAll = true;
}
angular.forEach($scope.selectedSharedBuyerObjectList, function(selectedBuyer) {
selectedBuyer.select = $scope.selectAll;
//IF ID WILL BE EXIST IN THE ARRAY NOT PSUH THE KEYID
if ($scope.shardBuyerKeyIdArray.indexOf(selectedBuyer.userTypeDto.keyId) == -1) {
$scope.shardBuyerKeyIdArray.push(selectedBuyer.userTypeDto.keyId);
$scope.countBuyer++;
}
});
} else {
$scope.selectAll = false;
//USED FOR UNCHECK ALL THE DATA ONE- BY-ONE
angular.forEach($scope.selectedSharedBuyerObjectList, function(selectedBuyer) {
selectedBuyer.select = $scope.selectAll;
var index = $scope.shardBuyerKeyIdArray.indexOf(selectedBuyer.userTypeDto.keyId);
$scope.shardBuyerKeyIdArray.splice(index, 1);
$scope.countBuyer--;
});
}
}
<div class="checkbox w3-margin" ng-if="selectedSharedBuyerObjectList.length > 0">
<span class="w3-right" ng-if="countBuyer">
<h5>You are selecting {{countBuyer}} buyers!</h5>
</span>
<label>
<input type="checkbox" ng-model="selectAll" ng-click="checkAllSharedBuyer(selectAll)"/>Check All
</label>
</div>
<div id="sharedRow" class="checkbox" ng-repeat="selectedBuyer in cmnBuyer = (selectedSharedBuyerObjectList | filter : userSearchInProduct
| filter : filterUser)">
<label>
<input type="checkbox" ng-model="selectedBuyer.select"
ng-change="selectedSharedBuyer($index, selectedBuyer.select, selectedBuyer.userTypeDto.keyId)"/>
{{selectedBuyer.personName}}
</label>
</div>
I have two list in which i have to count the select all checkbox length as well as single checkbox count my problem if the user un-check the ALL checkbox Checkbox count will be return -- what's the problem in my code?
$(function(){
var count = 0;
$('#sharedRow ').find('input[type=checkbox]').on('change',function(){
$('#msg').text('You are selecting '+$('#sharedRow ').find('input[type=checkbox]:checked').length+' buyers!')
})
$('#chkAll').on('change', function () {
if ($(this).is(':checked')) {
$('#sharedRow ').find('input[type=checkbox]').prop('checked', true);
$('#msg').text('You are selecting '+$('#sharedRow ').find('input[type=checkbox]:checked').length+' buyers!')
}
else {
$('#sharedRow ').find('input[type=checkbox]').prop('checked', false);
$('#msg').text('You are selecting '+$('#sharedRow ').find('input[type=checkbox]:checked').length+' buyers!')
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="checkbox w3-margin">
<span class="w3-right">
<h5 id="msg" >You are selecting 0 buyers!</h5>
</span>
<label>
<input id="chkAll" type="checkbox" />Check All
</label>
</div>
<div id="sharedRow" class="checkbox">
<label>
<input type="checkbox" value="1 Buyers" />1 Buyers
</label>
<label>
<input type="checkbox" value="2 Buyers" />2 Buyers
</label>
<label>
<input type="checkbox" value="3 Buyers" />3 Buyers
</label>
<label>
<input type="checkbox" value="4 Buyers" />4 Buyers
</label>
<label>
<input type="checkbox" value="5 Buyers" />5 Buyers
</label>
<label>
<input type="checkbox" value="6 Buyers" />6 Buyers
</label>
<label>
<input type="checkbox" value="7 Buyers" />7 Buyers
</label>
<label>
<input type="checkbox" value="8 Buyers" />8 Buyers
</label>
</div>
try this one. is it ok? if not then tell me what's wrong.
if you have a group of checkbox then you can find all selected checkbox.
$('div').find('input[type=checkbox]:checked').length;
If you only need the number
var count = $scope.selectedSharedBuyerObjectList.reduce(function(sum, item) {
return (item.select) ? sum + 1 : sum;
}, 0);
If you need the filtered array
var selected = $scope.selectedSharedBuyerObjectList.filter(function(item) {
return item.select;
});
var count = selected.length;
Or do it using plain old loop
var count = 0;
for (i = 0; i < $scope.selectedSharedBuyerObjectList.length; i++) {
if ($scope.selectedSharedBuyerObjectList.select) count++;
}

Sum split values from HTML form, use as data for Google scatter chart

I am creating an online quiz and want be able to plot the score on a chart.
I am attempting to add all the comma separated values in the checked radio buttons of a form in such a way that the result is also a comma separated value, however I am unsure how to do this.
Example:
2,2 + -2,2 + 1,-1 = 1,3
I then want to insert the resulting number into the Google Visualisation API to draw a chart on the same page, preferably updated as each radio button is checked.
Sample form code:
<form>
<input type="radio" name="q1" class="option" value="2,-2" />
<input type="radio" name="q1" class="option" value="1,-1" />
<input type="radio" name="q1" class="option" value="0,0" />
<input type="radio" name="q1" class="option" value="-1,1" />
<input type="radio" name="q1" class="option" value="-2,2" />
<input type="radio" name="q2" class="option" value="2,-2" />
<input type="radio" name="q2" class="option" value="1,-1" />
<input type="radio" name="q2" class="option" value="0,0" />
<input type="radio" name="q2" class="option" value="-1,1" />
<input type="radio" name="q2" class="option" value="-2,2" />
</form>
Google Visualisation API:
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['',''],
[0,0]
]);
var options = {
hAxis: {minValue: -94, maxValue: 94, gridlines: {count:0}},
vAxis: {minValue: -94, maxValue: 94, gridlines: {count:0}},
legend: 'none',
colors: ['#000000'],
width: 500,
height: 500
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
I have been looking for a way to accomplish this however so far none of the solutions I have found are suitable. Any help would be appreciated, thank you.
I made this Fiddle example to show you how to sum comma separated values dinamically. Once you get the values you can plot the result with Google Visualization API.
$(document).ready(function(){
var radios = $('input[type=radio]');
var evalResult = function(){
var sum1 = 0;
var sum2 = 0;
var q1 = $("input[type=radio][name=q1]:checked").val();
var q2 = $("input[type=radio][name=q2]:checked").val();
var values_q1 = q1.split(',');
var values_q2 = q2.split(',');
sum1 = parseInt(values_q1[0]) + parseInt(values_q1[0]);
sum2 = parseInt(values_q1[1]) + parseInt(values_q2[1]);
$(".expression").html(q1+" + "+ q2 + " = "+ sum1 + ","+sum2);
}
evalResult();
radios.change(evalResult);
});
EDIT
You can generalize the procedure over n questions.
$(document).ready(function(){
var radios = $('input[type=radio]');
var evalResult = function(){
var numQuestions = 80;
var sum1 = 0;
var sum2 = 0;
var expr_str = '';
for(var i = 1; i <= numQuestions; i++){
var q = $("input[type=radio][name=q"+i+"]:checked").val();
var value = q.split(',');
sum_1 += parseInt(value[0]);
sum_2 += parseInt(value[1]);
expr_str += (i <= numQuestions) ? q + " + " : q + " = ";
}
$(".expression").html(expr_str);
}
evalResult();
radios.change(evalResult);
});
I think following code should do the job
var totalVal = $(':checked')
.map(function() { return $(this).val(); })
.toArray()
.reduce(function(sum, val) {
var splitVal = val.split(',');
sum[0] = sum[0] + parseInt(splitVal[0], 10);
sum[1] = sum[1] + parseInt(splitVal[1], 10);
return sum;
}, [0, 0]);
console.log(totalVal)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<form>
<input checked type="radio" name="q1" class="option" value="2,-2" />
<input type="radio" name="q1" class="option" value="1,-1" />
<input type="radio" name="q1" class="option" value="0,0" />
<input type="radio" name="q1" class="option" value="-1,1" />
<input type="radio" name="q1" class="option" value="-2,2" />
<input type="radio" name="q2" class="option" value="2,-2" />
<input checked type="radio" name="q2" class="option" value="1,-1" />
<input type="radio" name="q2" class="option" value="0,0" />
<input type="radio" name="q2" class="option" value="-1,1" />
<input type="radio" name="q2" class="option" value="-2,2" />
</form>

Categories

Resources