Hi, I`d like to add something like “you got 8 answers correct out of 10” to this code:
`
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Quiz with radio buttons</title>
<style>
label{ display: block; }
input[type=submit]{ margin-top: 15px; }
</style>
</head>
<body>
<form>
<div class="question">
<p><strong>Q1</strong>: Mary is English. She was born in London</p>
<label><input type="radio" name="one" value="a">Mary was born in England</label>
<label><input type="radio" name="one" value="b">Mary, who is English, was born in London</label>
<label><input type="radio" name="one" value="c">English Mary was born in London</label>
<label><input type="radio" name="one" value="d">London Mary is English born</label>
</div>
<div class="question">
<p><strong>Q2</strong>: Mary is English. She was born in London</p>
<label><input type="radio" name="two" value="a">Mary was born in England</label>
<label><input type="radio" name="two" value="b">Mary, who is English, was born in London</label>
<label><input type="radio" name="two" value="c">English Mary was born in London</label>
<label><input type="radio" name="two" value="d">London Mary is English born</label>
</div>
<input type="submit" />
<input type="reset" value="Start again" />
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function clearAnswerImages(){
$("img").each(function(){
$(this).remove();
})
}
function mark(el, status){
var images = {
correct: "http://www.littletherese.com/tick.jpg",
incorrect: "http://www.littletherese.com/x.jpg",
unanswered: "http://assets.altperks.com/shared/images/clickable/questionmark-15x15.gif",
},
img = new Image();
img.src = images[status];
el.append(img);
}
$("form").on("submit", function(e){
e.preventDefault();
clearAnswerImages();
$questions = $(".question");
$questions.each(function(){
var answer = $(this).find("input:checked"),
key = answer.attr("name"),
val = answer.attr("value");
if(answer.length === 0){
mark($(this).find("p"), "unanswered");
} else if (answers[key] !== val){
mark(answer.parent(), "incorrect"); // I changed this line
} else {
mark(answer.parent(), "correct");
}
});
});
$("input[type=reset]").on("click", function(){
$("input:checked").each(function(){
$(this).prop("checked", false);
});
clearAnswerImages();
});
var answers = {
"one": "b",
"two": "b"
}
</script>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Quiz with radio buttons</title>
<style>
label{ display: block; }
input[type=submit]{ margin-top: 15px; }
#score{
padding: 5px;
margin: 15px 0 0 0;
}
</style>
</head>
<body>
<form>
<div class="question">
<p><strong>Q1</strong>: Mary is English. She was born in London</p>
<label><input type="radio" name="one" value="a">Mary was born in England</label>
<label><input type="radio" name="one" value="b">Mary, who is English, was born in London</label>
<label><input type="radio" name="one" value="c">English Mary was born in London</label>
<label><input type="radio" name="one" value="d">London Mary is English born</label>
</div>
<div class="question">
<p><strong>Q2</strong>: Mary is English. She was born in London</p>
<label><input type="radio" name="two" value="a">Mary was born in England</label>
<label><input type="radio" name="two" value="b">Mary, who is English, was born in London</label>
<label><input type="radio" name="two" value="c">English Mary was born in London</label>
<label><input type="radio" name="two" value="d">London Mary is English born</label>
</div>
<input type="submit" />
<input type="reset" value="Start again" />
</form>
<div id="score"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function clearAnswerImages(){
$("img").each(function(){
$(this).remove();
})
}
function mark(el, status){
var images = {
correct: "http://www.littletherese.com/tick.jpg",
incorrect: "http://www.littletherese.com/x.jpg",
unanswered: "http://assets.altperks.com/shared/images/clickable/questionmark-15x15.gif",
},
img = new Image();
img.src = images[status];
img.className = status;
el.append(img);
}
function displayScore(){
var numQuestions = $(".question").length,
questionsCorrect = $("img.correct").length;
$("#score").html("You got " + questionsCorrect + " out of " + numQuestions)
}
$("form").on("submit", function(e){
e.preventDefault();
clearAnswerImages();
$questions = $(".question");
$questions.each(function(){
var answer = $(this).find("input:checked"),
key = answer.attr("name"),
val = answer.attr("value");
if(answer.length === 0){
mark($(this).find("p"), "unanswered");
} else if (answers[key] !== val){
mark(answer.parent(), "incorrect"); // I changed this line
} else {
mark(answer.parent(), "correct");
}
});
displayScore()
});
$("input[type=reset]").on("click", function(){
$("input:checked").each(function(){
$(this).prop("checked", false);
});
clearAnswerImages();
});
var answers = {
"one": "b",
"two": "b"
}
</script>
</body>
</html>
Ok, I got it working with the last line of the code below:
$("input[type=reset]").on("click", function(){
$("input:checked").each(function(){
$(this).prop("checked", false);
$('#score').empty(); //I inserted this line
});
I ran the complete javascript code through JSHint and got a few “missing semi-colons”
one of which was after a curly brace }; I thought there shouldn’t be semi-colons after a curly brace?
I also got some “undefined variables”, but I think this isn’t a problem?
Regarding the missing semi-colons: they are all valid (i.e. JSHint is correct).
The one after the curly brace is a variable declaration and is necessary.
Regarding the undefined variables:
$ - you can ignore or alternatively add this at the top of the script file:
/*global $:false */
This declares to JSHint that $ is a global variable, and the false indicates that it should not be overridden.
The missing var before $questions was a mistake. Good catch.
Sorry, I don’t know how to fix that “missing var before $questions”. Now, after updating the code, JSHint gives me 2 errors:
One undefined variable
47 $questions
48 $questions
JSHint code:
/*global $:false */
function clearAnswerImages(){
$("img").each(function(){
$(this).remove();
});
}
function mark(el, status){
var images = {
correct: "http://www.littletherese.com/tick.jpg",
incorrect: "http://www.littletherese.com/x.jpg",
unanswered: "http://assets.altperks.com/shared/images/clickable/questionmark-15x15.gif",
},
img = new Image();
img.src = images[status];
img.className = status;
el.append(img);
}
function displayScore(){
var numQuestions = $(".question").length,
questionsCorrect = $("img.correct").length;
$("#score").html("You got " + questionsCorrect + " out of " + numQuestions);
}
$("form").on("submit", function(e){
e.preventDefault();
clearAnswerImages();
$questions = $(".question");
$questions.each(function(){
var answer = $(this).find("input:checked"),
key = answer.attr("name"),
val = answer.attr("value");
if(answer.length === 0){
mark($(this).find("p"), "unanswered");
} else if (answers[key] !== val){
mark(answer.parent(), "incorrect"); // I changed this line
} else {
mark(answer.parent(), "correct");
}
});
displayScore();
});
$("input[type=reset]").on("click", function(){
$("input:checked").each(function(){
$(this).prop("checked", false);
$('#score').empty(); //I inserted this line
});
clearAnswerImages();
});
var answers = {
"one": "b",
"two": "b"
};
Done! The code is clean now in JsHint. I notice that the reset button clears answers and “score”, *but in the case that “submit” is pressed, without having answered any questions, the result is “You got 0 correct out of 10”, and in this case, pressing “reset” doesn’t clear the score message. I can understand the logic of it (I think…), but I’m wondering how reset could clear the “0 correct” message as well.
This is the clean code.
<script>
/*global $:false */
function clearAnswerImages(){
$("img").each(function(){
$(this).remove();
});
}
function mark(el, status){
var images = {
correct: "http://www.littletherese.com/tick.jpg",
incorrect: "http://www.littletherese.com/x.jpg",
unanswered: "",
},
img = new Image();
img.src = images[status];
img.className = status;
el.append(img);
}
function displayScore(){
var numQuestions = $(".question").length,
questionsCorrect = $("img.correct").length;
$("#score").html("You got " + questionsCorrect + " out of " + numQuestions);
}
$("form").on("submit", function(e){
e.preventDefault();
clearAnswerImages();
var $questions = $(".question");
$questions.each(function(){
var answer = $(this).find("input:checked"),
key = answer.attr("name"),
val = answer.attr("value");
if(answer.length === 0){
mark($(this).find("p"), "unanswered");
} else if (answers[key] !== val){
mark(answer.parent(), "incorrect"); // I changed this line
} else {
mark(answer.parent(), "correct");
}
});
displayScore();
});
$("input[type=reset]").on("click", function(){
$("input:checked").each(function(){
$(this).prop("checked", false);
$('#score').empty(); //I inserted this line
});
clearAnswerImages();
});
var answers = {
"one": "b",
"two": "c",
"three": "a",
"four": "c",
"five": "b",
"six": "c",
"seven": "a",
"eight": "a",
"nine": "b",
"ten": "c",
};
</script>
function clearAnswerImages(){
$("img").each(function(){
$(this).remove();
});
}
could simply be
function clearAnswerImages(){
$("img").remove();
}
Use each() only if your each-thingies are boxes or something holding many other child-thingies and you need multiple variables set for every each-thingie-box so that you can run multiple listeners/functions/cookoffs/whatever. Remember that in jQuery if you say $(‘some thing’) you’re always getting an object with a list of thingies (even if it’s a list of one), so any jQuery function you tack on to that $(‘thingie’) will automatically be done to each thingie in your list of thingies.