I struggled my way through the first quiz and here are the results. Since I have some experience in jQuery I really wanted to use only vanilla JavaScript. I know the code is pretty choppy and there is most likely a lot of room for improvement.
How can I make this code more succinct? What are some better practices that i can implement?
Here is a jsfiddle.
HTML:
<div id="wrapper">
<div id="quiz">
<h1>How well do you know Matt</h1>
</div>
<input type='submit' id='myBtn' value='' />
</div>
JavaScript:
var allQuestions = [
{
question: "What is Matt favorite color?",
choices: ["Blue", "Black", "Yellow", "Blank", "Clear" ],
correctAnswer: 4
},
{
question: "Who is Matt's Favorite fiction Author?",
choices: ["Brennan Manning", "JD Salinger", "Stephen King", "Jack Kerouac"],
correctAnswer: 3
},
{
question: "What is Matt's favorite food?",
choices: ["Pizza", "Wings", "Mexican", "Rally's"],
correctAnswer: 0
}
];
var submitBtn = document.getElementById('myBtn');
var currentQuestion = 0;
var tally = 0;
var quizForm = document.getElementById('quiz');
var question;
var choices;
var radioButtons = document.getElementsByName('radioOption');
var index = 0;
function firstFunc() {
if (currentQuestion === 0) {
submitBtn.value = "Start Quiz";
}
}
function askQuestion () {
choices = allQuestions[currentQuestion].choices;
question = allQuestions[currentQuestion].question;
if (currentQuestion < allQuestions.length) {
submitBtn.value = "Next";
quizForm.innerHTML = "<h1>" + question + "</h1>";
for (var i = 0; i < choices.length; i++) {
quizForm.innerHTML += "<label><input type='radio' name='radioOption' value='" + choices[i] + "'/>" + choices[i] + "</label>";
}
if (currentQuestion == allQuestions.length - 1) {
submitBtn.value = "Submit";
} else if (currentQuestion > allQuestions.length - 1) {
calcQuiz();
}
}
}
function lookForChecked() {
if (radioButtons.length > 1) {
var checked = false;
for (var i = 0; i < radioButtons.length; i++) {
var selection = radioButtons[i];
if (selection.checked) {
var index = [i];
if (i === allQuestions[currentQuestion].correctAnswer) {
tally++;
}
if (currentQuestion < allQuestions.length -1) {
currentQuestion++;
} else {
console.log('you have ended the quiz');
calcQuiz();
return false;
}
break;
}
}
if ($('input[name="radioOption"]:checked').length < 1) {
alert('Please Make a Selection');
}
}
askQuestion();
}
function calcQuiz() {
quizForm.innerHTML = "<h1>You have finished the quiz</h1><p class='total'>You scored a total of " + tally + " out of " + allQuestions.length + "</h1>";
submitBtn.remove();
}
window.onload = firstFunc();
submitBtn.addEventListener('click', lookForChecked);
1 Answer 1
Design
You could remake this using Object-Oriented-Programming. For example, you could make a Question
object, like this.
function Question(description, choices, correctChoiceIndex) {
this.description = description;
this.choices = choices;
this.correctChoiceIndex = correctChoiceIndex;
}
You could then extend it with some methods, like askQuestion
. For example, you could do something like this (Using prompt
and alert
because I'm on mobile.)
Question.prototype.askQuestion = function() {
return prompt("Choices:\n" + this.choices.join("\n"));
}
You could then supply an additional method, checkAnswer
, to see if the user got the answer correct.
Question.prototype.checkAnswer = function() {
if(parseInt(this.askQuestion(), 10) === this.correctChoiceIndex) {
alert("You got the question right!");
}
else {
alert("Sorry, wrong answer.");
}
}
Nitpicks
Some of your naming is not great. For example, firstFunc
is an awful name for a function. It doesn't describe the purpose of the function in any way.
Preferably, names for variables/functions/classes should exhibit the following characteristics:
- Describe the variable/function/class in detail.
- Not have unnecessary abbreviations.
- Not be too short.
- Not be too long. (Unless you're programming in objective-c.)
Most of your variable names exhibit these characteristics, I just saw a few, like submitBtn
that could be expanded to something like submitButton
.
Moving on, I saw this line I your code:
var index = [i];
It isn't used anywhere in it's scope, and even if it was used, it would serve no purpose at this point.
Finally, when using the increment, ++
, and decrement, --
operators, remember the differences between how they're placed.
-
\$\begingroup\$ Definitely the most exciting part of programming to me is designing Objects to connect and form a solution. \$\endgroup\$insidesin– insidesin2015年07月31日 15:37:46 +00:00Commented Jul 31, 2015 at 15:37
askQuestion()
isn't invoked on page load. So the first question and its options aren't displayed \$\endgroup\$lookForChecked
is invoked. In this case you don't need to checkradioButtons.length
inlookForChecked()
. \$\endgroup\$