DEV Community

Hawa Bah
Hawa Bah

Posted on

My first project using JavaScript

This summer I joined the BlackCodher Bootcamp, which is an initiative of Coding Black Females and Niyo enterprise. The programme has the aim to empower black females with the skills and knowledge to start a career in Tech. I’m so far, really happy with all the resources and guidance we have been provided! As part of the course, we also get to build some projects. In this post, I will explain how I created a quiz using the skills I acquired.

Feel free to play with the demo, or check the code posted in GitHub.

I chose to make the quiz about capitals cities, because, who doesn’t like to travel? It was built with HTML, CSS, JavaScript and jQuery. Here are the steps that you can follow.

1. Store the questions in an array of objects.

To start, in a Javascript file, I created an array of objects. Each object included a set of properties: a question, some options, and a correct answer. In my case, I also added an image related to the question, so that I could use it later to style the quiz. Make sure to export and import those variables that you will use in a different file. The following code only contains two questions, but feel free to add as many as you wish!

const questions = [
    {
        qstn: ' What is the capital of Spain ?',
        options: ['Barcelona', 'San Marino', 'Madrid', 'Buenos Aires'],
        correct: 'Madrid',
        bgImage: "images/Madrid.jpg",
        country: 'Spain'
    },
    {
        qstn: ' What is the capital of Greece ?',
        options: ['Thessaloniki', 'Santorini', 'Mykonos', 'Athens'],
        correct: 'Athens',
        bgImage: "images/Athens.jpg",
        country: 'Greece'
    }]
Enter fullscreen mode Exit fullscreen mode

2. Create an HTML file.

In the body of the HTML file, I firstly, created a <section> which includes the title of the quiz and some instructions. This is the first part the user will see, so a "Start" button has also been added before closing the section. As you can see from the code below, I have also added a "Restart" and "Check all Answers" button.
Moreover, I included an empty <div> container, this is because a function will be created in JavaScript to display the content of the quiz. Make sure to assign an id or a class to the elements, this way, it will be easier to select or access the element.

 <body>
        <section class="home-container">
            <h1 class ="pageTitle">The Capital-City quiz</h1>
            <div class="home-sub">
                <p>How good are you in Geography? <br>Find out by playing this fun and educational game.</p>
                <p>INSTRUCTIONS:</p>
                <ol>
                    <li>Press the button Start to see the first question. </li>
                    <li>Select your answer, only one option is allowed.</li>
                    <li>You can click submit to check if you clicked the right answer. Then, click next to view the following question.</li>
                </ol>
                <p>Good Luck!</p>
                <button type="submit" id="btnsubmit">Check All Answers</button>
                <button id="start">Start</button>
                <button id="restart"><a href="./index.html">Restart Game</a></button>
                <br>
                <br>
            </div>            
        </section>
        <div id="quizDiv" ></div>
</body>
Enter fullscreen mode Exit fullscreen mode

3. Build the quiz with JavaScript.

3.1. Declaring the function

In a JavaScript file, I created a function buildQuiz() which would construct the quiz. To do this, I used the array questions created in step 1 as a parameter of the function. Inside buildQuiz(), I have also used a method to get each of the elements I have previously created in the HTML file. In this case, I used the ID's which were assigned to the empty <div> and the button "Check All Answers".

function buildQuiz(questions){
    const quizDiv = document.getElementById('quizDiv');
    const btnsubmit = document.getElementById('btnsubmit');
   };
Enter fullscreen mode Exit fullscreen mode

3.2. Mapping each question

Inside buildQuiz(), I used the map method to create a <div> for each object of the array. This <div> would contain a question as a title, and a form to show the possible answers. For this project, I made a radio type form, but you could choose another type. Below the form, I also included a submit and next div. Don’t forget to append every element you have created in JavaScript!

    questions.map((question) => {
        const questionDiv = document.createElement('div');
        questionDiv.className = 'questionDiv';
        questionDiv.id = 'questionDiv' + question.correct;      

        const qstnTitle = document.createElement('h2');
        qstnTitle.textContent = question.qstn;
        qstnTitle.className = 'qstn';

        const optionsForm = document.createElement('form');
        optionsForm.className = 'optionsForm';

        const submitNextDiv = document.createElement('div');
        submitNextDiv.className = 'submitNextDiv';

        const submitDiv = document.createElement('div');
        submitDiv.addEventListener('click', respondClick)
        submitDiv.className = 'submitDiv';
        submitDiv.textContent = 'Submit';

        const nextDiv = document.createElement('div');
        nextDiv.className = 'nextDiv';
        nextDiv.id = 'nextDiv';
        nextDiv.textContent = 'Next';

        submitNextDiv.appendChild(submitDiv);
        submitNextDiv.appendChild(nextDiv);
        questionDiv.appendChild(qstnTitle);
        questionDiv.appendChild(optionsForm);
        questionDiv.appendChild(submitNextDiv);
        quizDiv.appendChild(questionDiv);

        btnsubmit.addEventListener('click', respondClick);
   });
Enter fullscreen mode Exit fullscreen mode

3.3. Mapping each option

When creating the inputs for each possible answer, which will be appended in the form, I also used the .map() method to access each option of each question. So the following mapping is completed inside the scope of the previous map questions.map((question).

question.options.map((option) =>{
            const optionDiv = document.createElement('div');
            optionDiv.id = 'optionDiv' + option;

            const inputForm = document.createElement('input');
            inputForm.type = 'radio';
            inputForm.name = question.correct;
            inputForm.id = option;

            const inputLabel = document.createElement('label');
            inputLabel.for = option;
            inputLabel.textContent = option;

            optionDiv.appendChild(inputForm);
            optionDiv.appendChild(inputLabel);
            optionsForm.appendChild(optionDiv);
        });
Enter fullscreen mode Exit fullscreen mode

3.4. Adding Event Listeners

As you may have spotted in step 3.2, we have added some event listeners to the "Check all answers" button and to submitDiv. Both of them have the same event handler respondClick(), which defines the code that will run in response of the event. This function is declared in the scope of buildQuiz(), more specifically, inside the first map function.

function respondClick(){
            question.options.map((option) => {
                if(document.getElementById(option).checked && (option == question. correct)) {
                    const feedback = document.createElement('p');
                    feedback.textContent = 'You are right! ' + option + ' is the capital of ' + question.country;
                    questionDiv.appendChild(feedback);
                    //changing the style
                    let optionDiv = document.getElementById('optionDiv' + option);
                    optionDiv.style.color = 'green';
                    questionDiv.style.backgroundImage = " " + "url('" + question.bgImage + "')";
                    questionDiv.style.backgroundBlendMode = 'none';
                }
                if(document.getElementById(option).checked && (option !== question. correct)) {
                    const feedback = document.createElement('p');
                    feedback.textContent = 'Try again! ' + option + ' is not the correct answer...';
                    questionDiv.appendChild(feedback);
                    //changing the style
                    let optionDiv = document.getElementById('optionDiv' + option);
                    optionDiv.style.color = 'red';
                    optionsForm.style.backgroundColor = 'red';
                    questionDiv.style.backgroundImage = "linear-gradient(black, red), " + "url('" + question.bgImage + "')";
                    questionDiv.style.backgroundBlendMode = 'multiply';
                }
            })
        }
Enter fullscreen mode Exit fullscreen mode

Let's look at the above event handler to see how it works. According to the option the user has selected, we want to display one message or another. For this reason, I used if statements.
As for the conditions, we need to check whether the option has been selected and if the option is correct. Since we need to do this for each option of each question, we will need to use the map function once more.
If the conditions are met, we will create a feedback element with a specific text content, and we will append it to the div that contains the question.

3.5. Other event listeners with jQuery

To make the page scroll to the next question when the next div has been clicked, I used jQuery. The following function is inside the scope of the very first map method questions.map((question), because we are creating an event for each of the next div’s of each question. As you can see, I used a combination of .parent() and .next() to find which question I wanted to see once the next div has been clicked. I will refer to this question as the target. Then, I made an animation which would scroll the page down to the target.

  $(".nextDiv").click(function() {
            var next;
            next = $(this).parent().parent().next();
            $('html,body').animate({scrollTop: next.offset().top});  
        })
Enter fullscreen mode Exit fullscreen mode

Similarly, once the "Start" button is clicked, the page scrolls to the first question.

$("#start").click(function() {
        var elmnt = document.getElementById("quizDiv");
        console.log(elmnt);
        elmnt.scrollIntoView();
     })
Enter fullscreen mode Exit fullscreen mode

4. Adding style

To add styling to the elements of the quiz, it can be more comfortable to assign a className to each element, and use it in the CSS. Nevertheless, it is also possible to add it in the same JavaScript file using this format: [elementName].style.[propertyName] = “[value]” . Or if you want to add more than one property you can use: [elementName] .style.cssText= “[propertyName1]: [value1]; [propertyName2]: [value2]”. For instance:

optionsForm.style.cssText = "  display: grid;  
            grid-template-columns: repeat(auto-fit, 186px);  
            grid-gap: 5px; color: white; font-family: 'Anton', sans-serif; 
            justify-content: center; margin: 20px; padding: 5px " ;
Enter fullscreen mode Exit fullscreen mode

So, these were the main steps I followed to build the quiz. It was a great way to improve my skills in Javascript and jQuery. Moreover, the structure gives me the flexibility of adding more questions or possible answers at any time.

If you want to know more about my coding journey, or just want to chat make sure to follow me @HawaCodes on Twitter 💙.

Top comments (0)