March 11, 2020 javascript

How to Make a Simple JavaScript Quiz

JavaScript Quiz

In this tutorial, we will develop a simple JavaScript quiz. The system pulls stored array data of English words and their definitions.

It then dynamically creates vocabulary questions for every word, followed by multiple-choice.

Upon completion of the quiz, the user can submit to see the feedback and the score he or she gets.

The index.html file has only a few lines of codes because we create everything dynamically using JavaScript.

As a side note, I obtained the vocabulary data from a dictionary API using the JavaScript Fetch API.

We begin by creating a new array with a call back parameter called ‘words’ and stores them in a variable. The file that holds the array of words and definitions is located in a separate file but linked to the main index.html file.

Here is how I created a new array using the map() method,

As I said ‘wordDefinations’ is the name of an array variable holding a list of words and definitions and stored in another file but linked to the main index file.

 

 const wordList = wordDefinations.map(function(words) {
  return {
    word: words[0].trim(),
    defination: words[1]
  };
}); 

Again using ‘the ‘wordList’ variable, we can have two array variable- one for the base word and another for the definition.

const definations = wordList.map(x => x.defination);
const words = wordList.map(x => x.word); 

Now let us create our form elements:

const myForm = document.getElementById("my-form"); 

We can also create a div to hold each question and related multiple choices

const mydiv = document.getElementById("mydiv"); 

Next, using the length of the wordlist to determine the number of questions, we are ready to create the quiz.

Each question is assigned a number starting ‘1’, hence the need for the ‘count’ variable.
The part of JavaScript snippets responsible for the creation of form elements is shown below:

let count = 1;
const correctAnswer = [];

for (let w of wordList) {
  let myDiv = document.createElement('div');
  myDiv.className = 'my-div';
  let p = document.createElement('p');
  p.className = 'word';
  let myWord = w.word;

  p.textContent = `${count}. ${myWord}`;

  let correctDefination = w.defination;
  correctAnswer.push([count.toString(), correctDefination]);
  let myChoices = generateChoices(correctDefination);
  myDiv.appendChild(p);
  for (let i = 0; i < myChoices.length; i++) {
    let radio = document.createElement('input');
    let br = document.createElement('br');

    let label = document.createElement('label');
    let span = document.createElement('span');

    radio.type = 'radio';
    radio.name = myWord;
    radio.value = myChoices[i];
    radio.className = 'radio';

    label.appendChild(radio);

    span.appendChild(document.createTextNode(myChoices[i]));
    label.appendChild(span);
    myDiv.appendChild(label);
    myDiv.appendChild(br);
  }
  count++;
  myForm.appendChild(myDiv);
} 

When you iterate the wordList array, the definition array-item you get is the correct definition for the particular word, that is why we call it ‘correctDefinition’.

So in the case of ‘for (let w of wordList)’ ‘w’ represents the base word and its definition.
We can declare a variable for the definition like this:

let correctDefination = w.defination; 

and for the base word:

 let myWord = w.word; 

I think the creation of form elements is not complicated but let’s focus on the generateChoices function,

function generateChoices(def) {
  //This method returns 4 choices
  let filteredDefination = definations.filter(e => e !== def); // filter out correct defination
  let choices = shuffle(filteredDefination).slice(0, 3); //then, shuffle and take 3 random wrong definations
  choices.push(def); // add correct answer to the wrong answers above
  shuffle(choices); //shuffle them again
  return choices;
} 

The above function has one parameter, and it takes the correct meaning of each word from the array, which is being iterated.

We then shuffle the list and take out three wrong word-definitions.

 let choices = shuffle(filteredDefination).slice(0, 3); 

After that, we can add the correct definition to the list,

 choices.push(def);  

Before we generate wrong answers from the list of word definitions, we need to filter out the correct definition first; otherwise, we might have duplicate value. So we use the filter() method to remove any occurrence of the exact meaning of the particular word as shown below.

  let filteredDefination = definations.filter(e => e !== def);  

After that, it shuffles and picks three definitions. We can be sure the correct definition is not part of these three definitions since we filtered it out.

After that, we add the correct definition to the list of the wrong answers so that now every multiple choice has one correct answer and three wrong answers.

But before presenting them to the user, we shuffle them one more time since we just added the ‘correct definition’ to the list. If we don’t rearrange, the correct answer will always appear as the last item of the multiple choices.
Please note I am using the Fisher–Yates’ shuffle algorithm.

  function shuffle(a) {
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }

  return a;
}  

Sample quiz

javascript quiz

And sample result or feedback

JavaScript quiz feedback

You can get the project files in my GitHub repository.

Leave a Reply

Your email address will not be published. Required fields are marked *