How do I repeat my program again in JS based on the user choice?

Tags: , ,



Ok I have a made a a little quiz using html, css, and JS. What I want to do is at the end of the quiz I would like to ask the user a choice whether they would like to re do the quiz again. I think I have to use a “while” loop but am not so sure. Ok I have added the html and the JS. I think it be easy to understand. I have added the eventlistener but it’s not running properly and I don’t know how to fix it. It gives me error message saying “addEventListener not a function”.

function Quiz(questions) {
    this.score = 0;
    this.questions = questions;
    this.questionIndex = 0;
}

Quiz.prototype.getQuestionIndex = function() {
    return this.questions[this.questionIndex];
}

Quiz.prototype.guess = function(answer) {
    if(this.getQuestionIndex().isCorrectAnswer(answer)) {
        this.score++;
    }

    this.questionIndex++;
}

Quiz.prototype.isEnded = function() {
    return this.questionIndex === this.questions.length;
}


function Question(text, choices, answer) {
    this.text = text;
    this.choices = choices;
    this.answer = answer;
}

Question.prototype.isCorrectAnswer = function(choice) {
    return this.answer === choice;
}


function populate() {
    if(quiz.isEnded()) {
        showScores();
    }
    else {
        // show question
        var element = document.getElementById("question");
        element.innerHTML = quiz.getQuestionIndex().text;

        // show options
        var choices = quiz.getQuestionIndex().choices;
        for(var i = 0; i < choices.length; i++) {
            var element = document.getElementById("choice" + i);
            element.innerHTML = choices[i];
            guess("btn" + i, choices[i]);
        }

        showProgress();
    }
};

function guess(id, guess) {
    var button = document.getElementById(id);
    button.onclick = function() {
        quiz.guess(guess);
        populate();
    }
};


function showProgress() {
    var currentQuestionNumber = quiz.questionIndex + 1;
    var element = document.getElementById("progress");
    element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};

function shuffle_questions(questions) {
    var currentIndex = questions.length, temporaryValue, randomIndex;

    while (0 !== currentIndex) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        temporaryValue = questions[currentIndex];
        questions[currentIndex] = questions[randomIndex];
        questions[randomIndex] = temporaryValue;
    }

    return questions;
}

function restart() {
    document.getElementById("quiz").innerHTML = ''; // Clear out the "game over"
    questions = shuffle_questions(questions); // Left as an exercise for the reader; see https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
    quiz = new Quiz(questions); // Rebuild the quiz object
    populate();
  
    return false; // So the link doesn't try to go anywhere
  }

function showScores() {
    var gameOverHTML = "<h1>Result</h1>";
    gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2>";
    // message if they would like to try again, should I use console.log?
    gameOverHTML.addEventListener("click", restart) //not done yet
    var element = document.getElementById("quiz");
    element.innerHTML = gameOverHTML;
};

// create questions here
var questions = [
    new Question("Which nation won FIFA 2018 World Cup?", ["Peru", "France","Germany", "USA"], "France"),
    new Question("Which nation hosted FIFA 2018 World Cup?", ["Sweden", "Russia", "Iran", "South Korea"], "Russia"),
    new Question("Which nation has won the most World Cups?", ["Argentina", "Peru","Brazil", "France"], "Brazil"),
    new Question("Where was FIFA 2014 World Cup hosted?", ["Ecuador", "Brazil", "France", "All"], "Brazil"),
    new Question("Which nation won the first FIFA World Cup", ["Brazil", "Uruguay", "Italy", "Australia"], "Uruguay")
];

// create quiz
var quiz = new Quiz(questions);

// display quiz
populate();
<!DOCTYPE html>

<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Quiz</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="grid">
        <div id="quiz">
            <h1>FIFA World Cup Quiz</h1>
            <hr style="margin-bottom: 20px">

            <p id="question"></p>

            <div class="buttons">
                <button id="btn0"><span id="choice0"></span></button>
                <button id="btn1"><span id="choice1"></span></button>
                <button id="btn2"><span id="choice2"></span></button>
                <button id="btn3"><span id="choice3"></span></button>
            </div>

            <hr style="margin-top: 50px">
            <footer>
                <p id="progress">Question x of y</p>
            </footer>
        </div>
    </div>


<script src="question.js"></script>

</body>
</html>

Answer

I’ve added a <div id="results"> (hidden by default) which will be used to show the results. When the game ends, the showScores() function shows this <div> and hides the <div id="quiz">.

When the user clicks the Restart button, the handler hides the <div id="results"> and shows the <div id="quiz"> so the game can be played.

This can be improved by adding/removing classes rather than directly manipulating the CSS (style.display property). But that’s left as an exercise for the reader.

You can also find this code here: https://jsfiddle.net/kjLbea61/

function Quiz(questions) {
    this.score = 0;
    this.questions = questions;
    this.questionIndex = 0;
}

Quiz.prototype.getQuestionIndex = function() {
    return this.questions[this.questionIndex];
}

Quiz.prototype.guess = function(answer) {
    if(this.getQuestionIndex().isCorrectAnswer(answer)) {
        this.score++;
    }

    this.questionIndex++;
}

Quiz.prototype.isEnded = function() {
    return this.questionIndex === this.questions.length;
}


function Question(text, choices, answer) {
    this.text = text;
    this.choices = choices;
    this.answer = answer;
}

Question.prototype.isCorrectAnswer = function(choice) {
    return this.answer === choice;
}


function populate() {
    if(quiz.isEnded()) {
        showScores();
    }
    else {
        // show question
        var element = document.getElementById("question");
        element.innerHTML = quiz.getQuestionIndex().text;

        // show options
        var choices = quiz.getQuestionIndex().choices;
        for(var i = 0; i < choices.length; i++) {
            var element = document.getElementById("choice" + i);
            element.innerHTML = choices[i];
            guess("btn" + i, choices[i]);
        }

        showProgress();
    }
};

function guess(id, guess) {
    var button = document.getElementById(id);
    button.onclick = function() {
        quiz.guess(guess);
        populate();
    }
};


function showProgress() {
    var currentQuestionNumber = quiz.questionIndex + 1;
    var element = document.getElementById("progress");
    element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};

function shuffle_questions(questions) {
    var currentIndex = questions.length, temporaryValue, randomIndex;

    while (0 !== currentIndex) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        temporaryValue = questions[currentIndex];
        questions[currentIndex] = questions[randomIndex];
        questions[randomIndex] = temporaryValue;
    }

    return questions;
}

function restart() {
    questions = shuffle_questions(questions); // Left as an exercise for the reader; see https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
    quiz = new Quiz(questions); // Rebuild the quiz object
    populate();
    
    document.getElementById('quiz').style.display = 'block'; // show quiz
    document.getElementById('results').style.display = 'none'; // hide results
  }

function showScores() {
    document.getElementById('quiz').style.display = 'none'; // hide quiz
    document.getElementById('results').style.display = 'block'; // show results

    document.getElementById('score').innerHTML = quiz.score; // Put score in results
};

// create questions here
var questions = [
    new Question("Which nation won FIFA 2018 World Cup?", ["Peru", "France","Germany", "USA"], "France"),
    new Question("Which nation hosted FIFA 2018 World Cup?", ["Sweden", "Russia", "Iran", "South Korea"], "Russia"),
    new Question("Which nation has won the most World Cups?", ["Argentina", "Peru","Brazil", "France"], "Brazil"),
    new Question("Where was FIFA 2014 World Cup hosted?", ["Ecuador", "Brazil", "France", "All"], "Brazil"),
    new Question("Which nation won the first FIFA World Cup", ["Brazil", "Uruguay", "Italy", "Australia"], "Uruguay")
];

document.getElementById('restart').addEventListener('click', restart);

// create quiz
var quiz = new Quiz(questions);

// display quiz
populate();
<!DOCTYPE html>

<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Quiz</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="grid">
        <div id="quiz">
            <h1>FIFA World Cup Quiz</h1>
            <hr style="margin-bottom: 20px">

            <p id="question"></p>

            <div class="buttons">
                <button id="btn0"><span id="choice0"></span></button>
                <button id="btn1"><span id="choice1"></span></button>
                <button id="btn2"><span id="choice2"></span></button>
                <button id="btn3"><span id="choice3"></span></button>
            </div>

            <hr style="margin-top: 50px">
            <footer>
                <p id="progress">Question x of y</p>
            </footer>
        </div>
        <div id="results" style="display: none">
          <h1>
            Results
          </h1>
          <h2>
            Your scores: <span id="score"></span>
          </h2>
          <button id="restart">
            Restart
          </button>
        </div>
        
    </div>


<!--
<script src="question.js"></script>
-->

</body>
</html>


Source: stackoverflow