Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

get current li element and add "active" class and set an attribute Value to every choices of a single Question with JS

Hello everyone! I'm trying to improve or change the Quiz Project with OOP JavaScript. The Quiz Project was a simple quiz with multiple choices and at the end it showed the correct answers, which was the score. Now I want to change it and :

  • display the progress of current question with bullets and add 'active' class to current question and answered questions.
  • set to every choice of a question a Value attribute, so that at the end I can show the scores like that: if at the end points are : between 5-8 show this img if points are at the end : between 9-12 show other img and so on...... here you can see better my code: https://codepen.io/Alanes/pen/vjjpwR?editors=0011

5 Answers

Steven Parker
Steven Parker
230,274 Points

Hi Olivia, you had some nice ideas for improving the quiz project.

You can establish the classes for the progress tracking as the elements are being dynamically generated:

        for (i = 0; i < quiz.questions.length; i++) {
            progressHTML += '<li class="pagination' +
              (quiz.currentQuestionIndex == i ? " active" : "") + 
              '" id="' + [i] + '"></li>';    
        }

Then for the score, the points don't seem to be currently accumulated. One way to implement this would be to pass them down to the "guess" method instead of the answer (which isn't used):

Quiz.prototype.guess = function(points) {  // use points instead of answer
    this.score += points;                  // update the score
    this.currentQuestionIndex++;
};

Next, in "displayChoices", the reference needed correction and then the points can be passed along:

        var points = quiz.getCurrentQuestion().points;  // get the points for this question
//...
            this.guessHandler("guess" + i, points[i]);  // pass the points to the handler

And finally, when establishing the handler:

    guessHandler: function(id, points) {  // use points instead of answer
        var button = document.getElementById(id);
        button.onclick = function() {
            quiz.guess(points);           // pass along points instead of answer

Hi Steven! Thank you very much for the help and quickly answer!

Hi Steven, I have another question , if I create a reset button in:

displayScore: function() {
   var resetbtn = '<button id="reset_btn">play again</button>'; // reset button

   var gRed = `<h1>Answer 1</h1> <p>${resetbtn}</p>`;
   var gBlue = `<h1>Answer 2</h1> <p>${resetbtn}</p>`;

         if(quiz.score >= 2 && quiz.score <= 4){
            gameOverHTML = gRed;
        }else if(quiz.score >= 4 && quiz.score <= 8){
            gameOverHTML = gBlue;
        }
.....continue code...
}

//And at the end I just get the created Reset Button and give it an EventListener. Like that:

//Display Quiz
QuizUI.displayNext();

var resetButton = document.getElementById('reset_btn');
resetButton.addEventListener('click', function(){
    QuizUI.displayNext();
});     

I get always the error : Uncaught TypeError: Cannot read property 'addEventListener' of null I think, I'm placed the eventListener of reset button in a wrong sequence in the code....? Right?

Steven Parker
Steven Parker
230,274 Points

That's right, it's a sequence issue. The code to set the listener is running right after the first question is displayed, but the reset button is not added to the page until later.

You could move the code to add the listener to where the button is created. But it will also take a bit more programming in the handler function to re-establish the HTML components that the QuizUI relies on.

I moved the code EventListener where I created the button and I still getting this Error:

quiz.js:101 Uncaught TypeError: Cannot read property 'addEventListener' of null

And I can see that I have to change something here:

guessHandler: function(id, points) { 
        var button = document.getElementById(id);
        button.onclick = function() {
             quiz.guess(points); 
            QuizUI.displayNext();
}

But I don't know how, that's why I tried to do this too:

var resetButton = document.getElementById('reset_btn');
        resetButton.addEventListener('click', function(e) {
                location.reload();
        }, false); 

so that the reset Button just reload the page on click on it. But still I have the Error: quiz.js:101 Uncaught TypeError: Cannot read property 'addEventListener' of null

no change...

Steven Parker
Steven Parker
230,274 Points

You were still a bit too early. Where you moved the code, the "gameOverHTML" string is still being built. The button does not get created on the page until this line:

        this.populateIdWithHTML("quiz", gameOverHTML);

Also, it looks like codepen blocks the function you're calling in the handler.

many Thanks Steven!