Dominic Johnson
Dominic Johnson

Reputation: 43

How to have images in a JavaScript quiz?

I'm working on a basic JavaScript quiz for my younger anime-loving siblings. I want to be able to have a different picture available for each question. How and Where could insert images for the questions? Notes about the quiz only one question are shown at a time. For the sake of publishing, I took out all the questions, aside from the first one. Code below:

var pos = 0,
  test, test_status, question, choice, choices, chA, chB, chC, chD, correct = 0;

var questions = [{ //1
    question: "What is Dazai's power from Bungo Stray Dogs?",
    a: "No Longer Human",
    b: "For the Tainted Sorrow",
    c: "Rashomon",
    d: "Unbreakable",
    answer: "A"
  }
];

function get(x) {
  return document.getElementById(x);
}

function renderQuestion() {
  test = get("test");
  if (pos >= questions.length) {
    test.innerHTML = "<h2>You got " + correct + " of " + questions.length + " questions correct</h2>";
    get("test_status").innerHTML = "Test completed";

    pos = 0;
    correct = 0;

    return false;
  }
  get("test_status").innerHTML = "Question " + (pos + 1) + " of " + questions.length;

  question = questions[pos].question;
  chA = questions[pos].a;
  chB = questions[pos].b;
  chC = questions[pos].c;
  chD = questions[pos].d;

  test.innerHTML = "<h3>" + question + "</h3>";


  test.innerHTML += "<label> <input type='radio' name='choices' value='A'> " + chA + "</label><be>";
  test.innerHTML += "<label> <input type='radio' name='choices' value='B'> " + chB + "</label><be>";
  test.innerHTML += "<label> <input type='radio' name='choices' value='C'> " + chC + "</label><be>";
  test.innerHTML += "<label> <input type='radio' name='choices' value='D'> " + chD + "</label><br><be>";
  test.innerHTML += "<button onclick='checkAnswer()'>Submit Answer</button>";
}

function checkAnswer() {

  choices = document.getElementsByName("choices");
  for (var i = 0; i < choices.length; i++) {
    if (choices[i].checked) {
      choice = choices[i].value;
    }
  }

  if (choice == questions[pos].answer) {
    correct++;
  }
  pos++;

  renderQuestion();
}

window.addEventListener("load", renderQuestion);

Upvotes: 2

Views: 2057

Answers (2)

zcoop98
zcoop98

Reputation: 3087

It's relatively simple, you're already creating other DOM elements by concatenating them to the end of an element's innerHTML; what you're looking to do is no different.

Just add another property to your question objects, and add the respective <img> tag where desired in your concatenation statements:

var pos = 0,
  test, test_status, question, choice, choices, chA, chB, chC, chD, correct = 0;

var questions = [{ //1
    question: "What is Dazai's power from Bungo Stray Dogs?",
    a: "No Longer Human",
    b: "For the Tainted Sorrow",
    c: "Rashomon",
    d: "Unbreakable",
    answer: "A",
    //Add property to hold image source uri, either local or online
    img: "https://blog.qwant.com/wp-content/uploads/sites/3/2016/01/test.jpg"
  }];

function get(x) {
  return document.getElementById(x);
}

function renderQuestion() {
  test = get("test");
  if (pos >= questions.length) {
    test.innerHTML = "<h2>You got " + correct + " of " + questions.length + " questions correct</h2>";
    get("test_status").innerHTML = "Test completed";

    pos = 0;
    correct = 0;

    return false;
  }
  get("test_status").innerHTML = "Question " + (pos + 1) + " of " + questions.length;

  question = questions[pos].question;
  chA = questions[pos].a;
  chB = questions[pos].b;
  chC = questions[pos].c;
  chD = questions[pos].d;
  //Add local var to hold uri
  img = questions[pos].img;

  test.innerHTML = "<h3>" + question + "</h3>";
  
  //Add <img> element to DOM with source
  test.innerHTML += "<img src=\"" + img + "\" width=\"200\" height=\"200\"><br>";

  test.innerHTML += "<label> <input type='radio' name='choices' value='A'> " + chA + "</label><be>";
  test.innerHTML += "<label> <input type='radio' name='choices' value='B'> " + chB + "</label><be>";
  test.innerHTML += "<label> <input type='radio' name='choices' value='C'> " + chC + "</label><be>";
  test.innerHTML += "<label> <input type='radio' name='choices' value='D'> " + chD + "</label><br><be>";
  test.innerHTML += "<button onclick='checkAnswer()'>Submit Answer</button>";
}

function checkAnswer() {
  choices = document.getElementsByName("choices");
  for (var i = 0; i < choices.length; i++) {
    if (choices[i].checked) {
      choice = choices[i].value;
    }
  }

  if (choice == questions[pos].answer) {
    correct++;
  }

  pos++;

  renderQuestion();
}

window.addEventListener("load", renderQuestion);
<div id="test_status"></div>
<div id="test"></div>

If you're feeling fancy, you could even add a width and height property to your question objects with the url to add dynamically to the <img> tag.


As an aside, you may very well benefit from looking into a templating library for projects like this, even small ones. Libraries like Vue make things much easier, and cleaner, than concatenating to the innerHTML of a DOM element.

Upvotes: 2

andrralv
andrralv

Reputation: 860

In your questions collection, just add a url attribute that contains the urls of the images you uploaded somewhere, either online, or locally, using unix notation.

ex: url: "./images/question1.jpg"

then

test.innerHTML += "<img src=" + questions[index].url + " />;" to add it to the DOM. (Index is the index of the collection item you want to render, probably using that for loop you have or a map function.)

Upvotes: 0

Related Questions