How can I print the contents of all fields on submission in this JS quiz?

Viewed 51

I've made a JS/HTML quiz, and I want all the words entered in the text fields to be displayed at the bottom of the page on submission.

The error is in the showResults function, which isn't working the way I intend it to. I'm a beginner at using the querySelector but what I want to do is use the variable answerContainers to store only the .answers part of quizContainer, and then the toSearch variable to store only the values of submitted answers from answerContainers. Finally, I want to print the contents of toSearch to the screen in string form.

Here's my code:

var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');

var myQuestions = ["1. What is your dream destination?",
"2. If you could have one wish right now, what would it be?",
"3. What are your career goals?",
"4. Name an artist whose music you enjoy.",
"5. What are your hobbies?",
"6. Name a few public figures you admire.",
"7. Who is your favourite actor?",
"8. Which family member do you love the most?",
"9. If you could have any animal as your pet, what would it be?",
"10. Name a movie you’ve been planning to watch but haven’t yet had the time.",
"11. What kind of weather do you like the most?",
"12. Name a book or movie that you’ve always loved."];

function showQuestions(myQuestions, quizContainer){
    var output = [];
    for(var j = 0; j <= 11; j++)
    {
        var answer = '<label>'
              + '<input type="text" name=""+j+"" id=""+j+"">'
            + '</label>';
        output.push(
          '<div class="question">' + myQuestions[j] +'</div>'
          + '<div class="answers">' + answer + '</div>'
        );
    }
    quizContainer.innerHTML = output.join("");
    
}

function showResults(questions, quizContainer, resultsContainer){
  var answerContainers = quizContainer.querySelectorAll('.answers');

  var toSearch = [];
  
  for(var i=0; i <= 11; i++){
    toSearch.push(answerContainers[i].querySelector('input[name=""+i+""]')).value;
  }
  resultsContainer.innerHTML = toSearch.toString();

  
}
<!DOCTYPE html>
<html>
<head>
    <h2>Interests Questionnaire</h2>
    <h4>Answer in 1-5 words each.</h4>
    <br>
<link rel="stylesheet" href="test.css">
</head>
<body>
<div id="quiz"></div>
<div id="results"></div>
<script src = "test.js"></script> 
<script> showQuestions(myQuestions, quizContainer); </script>
<input type="button" value = "Submit" id = "submit" onclick = "showResults(myQuestions, quizContainer, resultsContainer)">
</body>
</html>

In its current form, the code gives the error "JavaScript error: TypeError: quizContainer is null on line 52". What am I doing wrong and how can I fix it?

2 Answers

There are a few problems here:

  • You have h2, br tags in the <head> of your page. Don't do that. Those kind of tags belong in the <body> tag of the page.

  • That error is telling you that quizContainer is null - if you look at the line of your code that is declaring quiz container, it is attempting to grab an element by ID - specifically 'quiz'. It can't find it. Possibly because you don't have a <body> tag.

Also - in your showResults function, you have a loop. Outside of that loop, is this line:

userAnswer =(answerContainers[i].querySelector('input[name=question'+i+']:checked')||{}).value;

You are trying to access the answerContainers array with the variable i outside of the loop where i is defined.

There were a few errors in your code - a misplaced parens, that sort of thing. I found/fixed the ones that were preventing success and got the answers to display in a string. You should be able to take it from here.

List of errors:

(1) toSearch.append() is not correct - use toSearch.push()
(2) You cannot have name or id attributes that begin with a number.
(3) This line was incorrect in a few places: toSearch.append(answerContainers[i].querySelector('input[name=""+i+""]')).value;
should be:
toSearch.push(answerContainers[i].querySelector('input[name="a'+i+'"]').value);

var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');

var myQuestions = ["1. What is your dream destination?",
"2. If you could have one wish right now, what would it be?",
"12. Name a book or movie that you’ve always loved."];

function showQuestions(myQuestions, quizContainer){
    var output = [];
    for(let j=0; j <= myQuestions.length-1; j++){
        var answer = `
            <label>
               <input type="text" name="a${j}" id="a${j}">
            </label>`;
        output.push(
          `<div class="question">${myQuestions[j]}</div>
          <div class="answers">${answer}</div>`
        );
    }
    quizContainer.innerHTML = output.join("");
    
}

function showResults(myQuestions, quizContainer, resultsContainer){
  var answerContainers = quizContainer.querySelectorAll('.answers');
//  console.log(answerContainers);

  var toSearch = [];
  
  for(var i=0; i <= myQuestions.length-1; i++){
  //console.log(answerContainers[i].querySelector('input[name="a'+i+'"]').value);
     toSearch.push(answerContainers[i].querySelector('input[name="a'+i+'"]').value);
     var x = 0;
  }
  resultsContainer.innerHTML = JSON.stringify(toSearch);

  //userAnswer = (answerContainers[i].querySelector('input[name=question'+i+']:checked')||{}).value;
}

showQuestions(myQuestions, quizContainer);
    <h2>Interests Questionnaire</h2>
    <h4>Answer in 1-5 words each.</h4>
    <br>
<div id="quiz"></div>
<div id="results"></div>
<input type="button" value = "Submit" id = "submit" onclick = "showResults(myQuestions, quizContainer, resultsContainer)">

Related