Vanilla Javascript Trivia Game

Help, Tutorials and Script related to Vanilla Javascript (NO jQuery!)
User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Vanilla Javascript Trivia Game

Post by Strider64 »

I have been developing this trivia game for the last 4-5 years now and I started off developing the game in jQuery only to convert it into Vanilla Javascript. The reason is pretty simple as I wanted people to be able to use the javascript without using a library in other words I want it to be easy transferable. I still has a little bit more to go, but it is a fully functional javascript game. Over the next couple of weeks I'm going to be writing a tutorial on how develop your own trivia game and post it right here on this board. The reason I have locked this thread is that I have gotten help in writing this game and watch some video tutorials on how to code certain sections of the game. I don't want some "Know-It-All" come here and critiquing this tutorial as I find it very annoying, plus I doing this tutorial to help people at NO CHARGE. The game is fully functional and you can see it action here https://www.miniaturephotographer.com/game.php.

I also have a Github Repository for the more advance programmer and it can be found here -> https://github.com/Strider64/trivia-gam ... -1-22-2020

I'm going to do this tutorial in code sections in hopes that is will be easier to follow, so let me get started. The first part is going to deal with the HTML part of the trivia game as I feel this is the foundation and without a good foundation the game will get off to a rocky start. Don't get me wrong as you develop a trivia game you will be making changes to the HTML/CSS, but the changes shouldn't be drastic as long as you are not making drastic changes in how the game functions. I called the file game.php :

Code: Select all

<?php
require_once '../private/initialize.php';
$_SESSION['api_key'] = bin2hex(random_bytes(32)); // 64 characters long
?>
<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
        <title>Trivia</title>
        <link rel="shortcut icon" href="favicon.ico" >
        <script type="text/javascript"src="assets/js/game.js" defer></script>
        <link href="https://fonts.googleapis.com/css?family=Teko:400,700&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="assets/css/reset.css">
        <link rel="stylesheet" href="assets/css/game.css">
    </head>
    <body>
        <div id="page">
            <header>
                <a class="logo" title="Miniature Photographer Logo" href="index.php"><span>Miniature Photographer Logo</span></a>
                <div class="intro">
                    <h1>The Miniature Photographer</h1>
                    <a class="btn menuExit" title="My LinkedIn Page" href="https://www.linkedin.com/in/johnpepp/">LinkedIn Page</a>
                </div>
            </header>
            <section class="main">
                <form id="gameCat" action="game.php" method="post">
                    <select id="selectCat" class="select-css" name="category" tabindex="1">
                        <option value="photography">Photography</option>
                        <option value="movie">Movie</option>
                        <option value="space">Space</option>
                    </select>
                </form>
                <div id="gameTitle">
                    <h2 class="gameTitle">Trivia Game</h2>
                </div>
                <div class="triviaContainer" data-key="<?php echo $_SESSION['api_key']; ?>" data-records=" ">             
                    <div id="mainGame">
                        <div id="headerStyle" data-user="">
                            <h2>Time Left: <span id="clock"></span></h2>
                        </div>
                        <div id="triviaSection" data-correct="">
                            <div id="questionBox">
                                <h2 id="question">What is the Question?</h2>
                            </div>
                            <div id="buttonContainer"></div>
                        </div>
                        <div id="playerStats">
                            <h2 id="score">Score 0 Points</h2>
                            <h2 id="percent">100%</h2>
                        </div>
                        <div id="nextStyle">
                            <button id="next" class="nextBtn">Next</button>
                        </div>
                    </div>
                </div>
            </section> <!-- End of Section -->
            <?php include '../private/includes/navigation.inc.php'; ?>
            <footer>
                &copy; The Miniature Photographer
                <div class="content">
                    <a class="menuExit" title="Facebook Miniature Photographer" href="https://www.facebook.com/Pepster64/">Facebook Miniature Photographer Page</a>
                    <!--        <a title="Terms of Service" href="#">Terms of Service</a>-->
                </div>
            </footer>
        </div>
    </body>
</html>
This is the heart and sole of the HTML that I have come up over the years. The only portion that I do totally dynamically is the answer portion as I find that portion is the only area that gets changed a lot. Some coders say that you should do all of the quiz portion dynamically, but in my opinion that is a nuisance as any changes that you want to make to the design of HTML has to be done in javascript. Speaking of design the CSS portion I'm going to assume that you know it pretty well, but later on when I get this tutorial almost done I will add the CSS into this tutorial. Though you can always go to my website to see how I styled the quiz in the meantime. You also should know HTML pretty good as well before doing this tutorial as it make it easier to follow.

On to the next portion of this tutorial...

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Here is the javascript portion of the Trivia Quiz. This trivia game was originally written in Adobe Flash using Actionscript and it was pretty good. I even made a hangman version of the game and I might eventually do that with this version. Then I converted it over to javascript, but I was using the jQuery library. That too worked very good, but I didn't like the portability of the game and you have to use a library in order for the game to work. So, I decided to convert it over to vanilla javascript as it is easy to transfer from one website to another. Heck, if you really wanted to I'm sure you could simply transfer it the game over to your website and the only thing you really would have to know is PHP in order to get the backend of the game to run. Though you could also tweak my code to run it solely in javascript, but the gameplay wouldn't be as fun in my opinion. After some trials and tribulations I finally converted the game over to vanilla javascript. One piece of advice and that would be to learn vanilla javascript really good if you are even considering programming in jQuery as I found it kind of tough understanding vanilla javascript. I am still learning something new everyday with javascript, but I guess if you don't learn something new everyday then you really are not learning. That is why I haven't attempted to write a tutorial on this game until now as I wasn't comfortable coding in vanilla javascript. One last thing before I start and that is I might not uses the technical language (jargon) of the coding process 100 percent, but you should still be able to understand what I am writing. If you even know the correct way of wording it then feel free to send a private email to me and I will correct it. So here I start.

I first will give you the who script, but I will break the code down after I do. I find it easier for a person learning how to write this game to visualize and understand the coding process seeing the whole script even though he/she might not understand the code.

I named the javascript file - game.js (such an original name :D )

Code: Select all

/*
 *  Trivia Game Version 4.55 beta using FETCH/JSON
 *  by John Pepp
 *  Started: January 14, 2020
 *  Revised: April 8, 2020 @ 10:00 PM
 */

'use strict';

/* Convert RGBa to HEX  */
const rgba2hex = (orig) => {
    var a,
            rgb = orig.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i),
            alpha = (rgb && rgb[4] || "").trim(),
            hex = rgb ?
            (rgb[1] | 1 << 8).toString(16).slice(1) +
            (rgb[2] | 1 << 8).toString(16).slice(1) +
            (rgb[3] | 1 << 8).toString(16).slice(1) : orig;

    if (alpha !== "") {
        a = alpha;
    } else {
        a = "01";
    }
    // multiply before convert to HEX
    a = ((a * 255) | 1 << 8).toString(16).slice(1);
    hex = hex + a;

    return hex;
};

const myColor = (colorcode) => {
    var hexColor = rgba2hex(colorcode);
    return '#' + hexColor;
};

/*
 * Constants & Variables Initialization Section.
 */
const myGreen = myColor("rgba(29, 100, 31, 0.70)"); /* Green with 70% transparency */
const myRed = myColor("rgba(84, 0, 30, 0.70)"); /* Red with 70% transparency */

const quizUrl = 'qdatabase.php?'; // PHP database script 
const d = document; // Shorten docoment function::

const photographyBtn = d.querySelector('#photography');

const gameTitle = d.querySelector('.gameTitle');
const buttonContainer = d.querySelector('#buttonContainer');
const question = d.querySelector('#question');
const next = d.querySelector('#next');
const points = 100;
const scoreText = d.querySelector('#score');
const percent = d.querySelector('#percent');
const dSec = 20; // Countdown Clock for questions:

var gameIndex = 0,
        gameData = null, // Array of Objects (id, questions and answers):
        timer = null,
        score = 0,
        total = 0,
        answeredRight = 0,
        answeredWrong = 0,
        choose = d.querySelector('#selectCat');

var responseAns = {};

const buttons = d.querySelectorAll(".answerButton");
const mainGame = d.querySelector('#mainGame');


/*
 * Start and Stop Functions for Countdown Timer For Triva Game
 */
const startTimer = (dSec) => {
    var seconds = dSec;
    const userAnswer = 5, correct = 1;
    const newClock = d.querySelector('#clock');

    newClock.style['color'] = 'white';
    newClock.textContent = ((seconds < 10) ? `0${seconds}` : seconds);
    const countdown = () => {
        if (seconds === 0) {
            clearTimeout(timer);
            newClock.style['color'] = myRed;
            newClock.textContent = "00";

            scoringFcn(userAnswer, correct);
            highlightFCN(userAnswer, correct);
            calcPercent(answeredRight, total);
            disableListeners();
            next.addEventListener('click', removeQuiz, false);
        } else {
            newClock.textContent = ((seconds < 10) ? `0${seconds}` : seconds);
            seconds--;
        }
    };




    timer = setInterval(countdown, 1000);

};

const stopTimer = () => {
    clearInterval(timer);
};

/* Highlight correct or wrong answers */
const highlightFCN = (userAnswer, correct) => {
    const highlights = d.querySelectorAll('.answerButton');
    highlights.forEach(answer => {

        /*
         * Highlight Answers Function
         */

        /*
         * User answered correctly
         */
        if (userAnswer === correct && userAnswer === parseInt(answer.getAttribute('data-correct'))) {
            answer.style["background-color"] = myGreen;
        }

        /*
         * User ansered incorrectly
         */
        if (userAnswer !== correct && userAnswer === parseInt(answer.getAttribute('data-correct'))) {
            answer.style['background-color'] = myRed;
        }
        if (userAnswer !== correct && correct === parseInt(answer.getAttribute('data-correct'))) {
            answer.style['background-color'] = myGreen;
        }

        /*
         * User let timer run out
         */
        if (userAnswer === 5) {
            answer.style['background-color'] = myRed;
        }
    });
};

/* Disable Listeners, so users can't click on answer buttons */
const disableListeners = () => {
    const myButtons = d.querySelectorAll('.answerButton');
    myButtons.forEach(answer => {
        answer.removeEventListener('click', clickHandler, false);
    });
};

/* Calculate Percent */
const calcPercent = (correct, total) => {
    var average = (correct / total) * 100;
    percent.textContent = average.toFixed(0) + "%";
};

/* Figure out Score */
const scoringFcn = (userAnswer, correct) => {
    if (userAnswer === correct) {
        score += points;
        answeredRight++;
        scoreText.textContent = `Score ${score} Points`;
    } else {
        score = score - (points / 2);
        answeredWrong++;
        scoreText.textContent = `Score ${score} Points`;
    }
    total++;
};

/*
 * Throw error response if something is wrong: 
 */
const handleErrors = (response) => {
    if (!response.ok) {
        throw (response.status + ' : ' + response.statusText);
    }
    return response.json();
};

/* Success function utilizing FETCH */
const checkUISuccess = function (parsedData) {
    var correct = parseInt(parsedData.correct);
    var userAnswer = parseInt(d.querySelector('#headerStyle').getAttribute('data-user'));
    scoringFcn(userAnswer, correct);
    calcPercent(answeredRight, total);
    highlightFCN(userAnswer, correct);

    disableListeners();
    next.addEventListener('click', removeQuiz, false);
};

/* If Database Table fails to load then hard code the correct answers */
const checkUIError = function (error) {

    switch (gameData[gameIndex].id) {
        case 1:
            var correct = gameData[gameIndex].correct;
            break;
        case 55:
            var correct = gameData[gameIndex].correct;
            break;
        case 9:
            var correct = gameData[gameIndex].correct;
    }
    var userAnswer = parseInt(d.querySelector('#headerStyle').getAttribute('data-user'));
    scoringFcn(userAnswer, correct);
    calcPercent(answeredRight, total);
    highlightFCN(userAnswer, correct);

    disableListeners();
    next.addEventListener('click', removeQuiz, false);

};

/* create FETCH request */
const checkRequest = function (url, succeed, fail) {
        fetch(url, {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(responseAns)

        })
                .then((response) => handleErrors(response))
                .then((data) => succeed(data))
                .catch((error) => fail(error));
};

/* User has made selection */
const clickHandler = (e) => {
    const userAnswer = parseInt(e.target.getAttribute('data-correct'));
    responseAns.id = parseInt(gameData[gameIndex].id); // { id: integer } 
    const checkUrl = "check.php";
    stopTimer();
    checkRequest(checkUrl, checkUISuccess, checkUIError);
    d.querySelector('#headerStyle').setAttribute('data-user', userAnswer);
};

/* Remove answers from Screen */
const removeAnswers = () => {
    let element = d.querySelector('#buttonContainer');
    while (element.firstChild) {
        element.removeChild(element.firstChild);
    }
};

/* Reset the Game */
const resetGame = () => {
    removeAnswers();
    stopTimer();
    score = 0;
    total = 0;
    answeredRight = 0;
    answeredWrong = 0;
    gameIndex = 0;
    gameData = null;
    scoreText.textContent = 'Score 0 Points';
    percent.textContent = '100';
};

/* Remove Question & Answers */
const removeQuiz = () => {
    removeAnswers(); // Call removeAnswers FCN:
    next.removeEventListener('click', removeQuiz, false);
    gameIndex++;

    if (gameIndex < parseInt(gameData.length)) {
        createQuiz(gameData[gameIndex]); // Recreate the Quiz Display:
    } else {
        question.textContent = 'Game Over';
    }
};

/* Populate Question, Create Answer Buttons */
const createQuiz = (gameData) => {

    /*
     * The Element interface's scrollIntoView() method scrolls the element's
     * parent container such that the element on which 
     * scrollIntoView() is called is visible to the user
     */
    d.getElementById('mainGame').scrollIntoView();

    startTimer(dSec);

    question.textContent = gameData.question;

    /*
     * Create Buttons then insert answers into buttons that were
     * create. 
     */
    gameData.answers.forEach((value, index) => {
        /*
         * Don't Show Answers that have a Blank Field
         */
        if (value !== "") {
            var gameButton = buttonContainer.appendChild(d.createElement('button'));
            gameButton.id = 'answer' + (index + 1);
            gameButton.className = 'answerButton';
            gameButton.setAttribute('data-correct', (index + 1));
            gameButton.addEventListener('click', clickHandler, false);
            gameButton.appendChild(d.createTextNode(value));
        }
    });
};

/* Success function utilizing FETCH */
const quizUISuccess = (parsedData) => {
    console.log('Data', parsedData);
    mainGame.style.display = 'block';
    //gameData = parsedData.sort(() => Math.random() - .5); // randomize questions:
    gameData = parsedData;
    createQuiz(gameData[gameIndex]);

};

/* If Database Table fails to load then answer a few hard coded Q&A */
const quizUIError = (error) => {
    console.log("Database Table did not load", error);

    gameData = [
        {
            id: 1,
            question: "What actor from the movie \"Dead Poets Society\" plays Dr. James Wilson on the TV show ",
            correct: 2,
            category: "movie",
            answers: ["Ethan Hawke", "Robert Sean Leonard", "James Waterston"]

        },
        {
            id: 55,
            question: "Who has won the most Oscars for Best Actress?",
            correct: 2,
            category: "movie",
            answers: ["Meryl Streep", "Katharine Hepburn", "Audrey Hepburn", "Jane Fonda"]
        },
        {
            id: 9,
            question: "Who played Jor-El in \"Superman (1978)\"?",
            correct: 4,
            category: "movie",
            answers: ["Glenn Ford", "Ned Beatty", "Christopher Reed", "Marlon Brando"]
        }
    ];

    /* Display HTML Game Display and create Quiz */
    mainGame.style.display = 'block';

    createQuiz(gameData[gameIndex]);
};

/* create FETCH request */
const createRequest = (url, succeed, fail) => {
    fetch(url)
            .then((response) => handleErrors(response))
            .then((data) => succeed(data))
            .catch((error) => fail(error));
};

/*
 * Start Game by Category
 */
const selectCat = function (category) {
    var api_key = d.querySelector('.triviaContainer').getAttribute('data-key');
    //var api_key = '42857078e4de89da3d432bd4456faf56c4a6c58f6378332f6f2b0d6ff107f9d9';
    const requestUrl = `${quizUrl}category=${category}&api_key=${api_key}`;

    createRequest(requestUrl, quizUISuccess, quizUIError);

};


const capitalize = (s) => {
    if (typeof s !== 'string')
        return '';
    return s.charAt(0).toUpperCase() + s.slice(1);
};

const selection = (e) => {
    e.preventDefault(); // Prevent the select HTML tag from firing:
    var category = e.target.value; // Grab the user's selection:
    d.querySelector('.gameTitle').textContent = `${capitalize(category)} Trivia`; // Assign the h2 HTML tag the title of the category:
    d.querySelector('.triviaContainer').style.display = "block"; // Turn on the selection category (I don't think it's really need?):
    resetGame(); // reset the game
    selectCat(category); // call the select function with the category that was selected:
    console.log(e.target.value); // console debugging tool: 
};

choose.addEventListener('change', selection, false);

d.querySelector('.gameTitle').textContent = "Photography";
selectCat('photography');
I'm going to take a break from this tutorial and get back to writing later on. If you should happen to use the whole javascript code as is then all I ask from you is to give me the proper credit, but I hope you follow this tutorial in hopes that you developing your own version to the game.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Let us continue this tutorial....

I will first start off with the selection of the categories, so I will repost the HTML portion that deals with that right now.

Code: Select all

                <form id="gameCat" action="game.php" method="post">
                    <select id="selectCat" class="select-css" name="category" tabindex="1">
                        <option value="photography">Photography</option>
                        <option value="movie">Movie</option>
                        <option value="space">Space</option>
                    </select>
                </form>
                <div id="gameTitle">
                    <h2 class="gameTitle">Trivia Game</h2>
                </div>
and here is the vanilla javascript:

Code: Select all

    var choose = d.querySelector('#selectCat');

    const capitalize = (s) => {
        if (typeof s !== 'string')
            return '';
        return s.charAt(0).toUpperCase() + s.slice(1);
    };

    const selection = (e) => {
        e.preventDefault();
        var category = e.target.value;
        d.querySelector('.gameTitle').textContent = `${capitalize(category)} Trivia`;
        //document.querySelector('#gameCat').style.display= "none";
        d.querySelector('.triviaContainer').style.display = "block";
        resetGame();
        selectCat(category);
        [quote]console.log(e.target.value)[/quote];
    };

    choose.addEventListener('change', selection, false);
First we assign the choose variable the HTML select tag, so we can add an event listener to it ( choose.addEventListener('change', selection, false) ). This way when the player (user) selects a category the proper quiz category will be loaded/displayed, so when the user selects a category the addEventListener is triggered. The = () => is basically another way of writing function() though there are minor differences between the two. I used const to initialize the function as it will stay constant until the user changes another category. The e.preventDefault() prevents the DOM from firing the HTML form from firing as we want to control the HTML select tag in javascript. Next the value of the select tag is assigned to the variable category by doing

Code: Select all

var category = e.target.vaule
because it is an (e)vent that was triggered when the category that was selected. The code

Code: Select all

d.querySelector('.gameTitle').textContent = `${capitalize(category)} Trivia`
displays the category in the HTML h2 tag. Please ignore the capitalize function as I was just fooling around and just capitalize the Category names in the HTML. A Special Note: that is a backwards tick ` not a single quote ' and doing `${capitalize(category)} Trivia` is the same as doing capitalize(category) + ' Trivia' which I might do in other portions of the code as it just the old way of doing it. Ignore the commented line of code for now as I will eventually get back to it later in the tutorial.The

Code: Select all

d.querySelector('.triviaContainer').style.display = "block"
unhides the game itself in order for the player to actually see the quiz. Next resetGame() is a call to a function that we will write later on and yes does what it looks like. The

Code: Select all

selectCat(category)
is another call to a function that I will be covering next. Finally

Code: Select all

console.log(e.target.value)
is used for debugging and console.log is a javascript function that shows the values of variables and other useful information about the javascript code in real time usage.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

I put this at the top of the javascript file

Code: Select all

'use strict';
as it forces me to write strict code meaning I have to declare my variables.

The global variables and global constants that the trivia game uses.

Code: Select all

/* Convert RGBa to HEX  */
const rgba2hex = (orig) => {
    var a,
            rgb = orig.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i),
            alpha = (rgb && rgb[4] || "").trim(),
            hex = rgb ?
            (rgb[1] | 1 << 8).toString(16).slice(1) +
            (rgb[2] | 1 << 8).toString(16).slice(1) +
            (rgb[3] | 1 << 8).toString(16).slice(1) : orig;

    if (alpha !== "") {
        a = alpha;
    } else {
        a = "01";
    }
    // multiply before convert to HEX
    a = ((a * 255) | 1 << 8).toString(16).slice(1);
    hex = hex + a;

    return hex;
};

const myColor = (colorcode) => {
    var hexColor = rgba2hex(colorcode);
    return '#' + hexColor;
};

/*
 * Constants & Variables Initialization Section.
 */
const myGreen = myColor("rgba(29, 100, 31, 0.70)"); /* Green with 70% transparency */
const myRed = myColor("rgba(84, 0, 30, 0.70)"); /* Red with 70% transparency */

const quizUrl = 'qdatabase.php?'; // PHP database script 
const d = document; // Shorten docoment function::

const photographyBtn = d.querySelector('#photography');

const gameTitle = d.querySelector('.gameTitle');
const buttonContainer = d.querySelector('#buttonContainer');
const question = d.querySelector('#question');
const next = d.querySelector('#next');
const points = 100;
const scoreText = d.querySelector('#score');
const percent = d.querySelector('#percent');
const dSec = 20; // Countdown Clock for questions:

var gameIndex = 0,
        gameData = null, // Array of Objects (id, questions and answers):
        timer = null,
        score = 0,
        total = 0,
        answeredRight = 0,
        answeredWrong = 0,
        choose = d.querySelector('#selectCat');

const buttons = d.querySelectorAll(".answerButton");
const mainGame = d.querySelector('#mainGame');
The constants are basically selecting the HTML Tags and the variables change values on a regular basis.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

const capitalize = (s) => {
    if (typeof s !== 'string')
        return '';
    return s.charAt(0).toUpperCase() + s.slice(1);
};

const selection = (e) => {
    e.preventDefault(); // Prevent the select HTML tag from firing:
    var category = e.target.value; // Grab the user's selection:
    d.querySelector('.gameTitle').textContent = `${capitalize(category)} Trivia`; // Assign the h2 HTML tag the title of the category:
    d.querySelector('.triviaContainer').style.display = "block"; // Turn on the selection category (I don't think it's really need?):
    resetGame(); // reset the game
    selectCat(category); // call the select function with the category that was selected:
    console.log(e.target.value); // console debugging tool: 
};

choose.addEventListener('change', selection, false);

d.querySelector('.gameTitle').textContent = "Photography";
selectCat('photography');
The game title "Photography" is assigned to the h2 HTML Tag (.gameTitle class) and then the selectCat function is called with the photography category.
The select HTML tag is assigned an add event listener choose.addEventListener('change', selection, false), so when the users changes the category the const selection = (e) => function is called to change the category and to call the selectCat(category). It also calls the resetGame() function, but I will explain that later on in the tutorial as it will make better sense at that time.

Code: Select all

/*
 * Start Game by Category
 */
const selectCat = function (category) {
    var api_key = d.querySelector('.triviaContainer').getAttribute('data-key');
    //var api_key = '42857078e4de89da3d432bd4456faf56c4a6c58f6378332f6f2b0d6ff107f9d9';
    const requestUrl = `${quizUrl}category=${category}&api_key=${api_key}`;

    createRequest(requestUrl, quizUISuccess, quizUIError);

};
The createRequest(requestUrl, quizUISuccess, quizUIError); function is called that fetches the data from the database table. The requestUrl constant is the url that is sent to the FETCH.
The variable api_key is really NOT needed as that it what I use on my own website, so just delete &api_key=${api_key} from const requestUrl = `${quizUrl}category=${category}&api_key=${api_key}`.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Here are the javascript functions to FETCH the questions & answers from a MySQL Database Table using PHP and JSON.

Code: Select all

    /*
     * Throw error response if something is wrong: 
     */
    const handleErrors = (response) => {
        if (!response.ok) {
            throw (response.status + ' : ' + response.statusText);
        }
        return response.json();
    };
This above function handErrors is towards the top of the scrpt.

Code: Select all

    /* Success function utilizing FETCH */
    const quizUISuccess = (parsedData) => {

        mainGame.style.display = 'block';
        //gameData = parsedData.sort(() => Math.random() - .5);
        gameData = parsedData;
        createQuiz(gameData[gameIndex]);

    };

    /* If Database Table fails to load then answer a few hard coded Q&A */
    const quizUIError = (error) => {
        console.log("Database Table did not load", error);

        gameData = [
            {
                id: 1,
                question: "What actor from the movie \"Dead Poets Society\" plays Dr. James Wilson on the TV show ",
                correct: 2,
                category: "movie",
                answers: ["Ethan Hawke", "Robert Sean Leonard", "James Waterston"]

            },
            {
                id: 55,
                question: "Who has won the most Oscars for Best Actress?",
                correct: 2,
                category: "movie",
                answers: ["Meryl Streep", "Katharine Hepburn", "Audrey Hepburn", "Jane Fonda"]
            },
            {
                id: 9,
                question: "Who played Jor-El in \"Superman (1978)\"?",
                correct: 4,
                category: "movie",
                answers: ["Glenn Ford", "Ned Beatty", "Christopher Reed", "Marlon Brando"]
            }
        ];

        /* Display HTML Game Display and create Quiz */
        mainGame.style.display = 'block';

        createQuiz(gameData[gameIndex]);
    };

    /* create FETCH request */
    const createRequest = (url, succeed, fail) => {
        fetch(url)
                .then((response) => handleErrors(response))
                .then((data) => succeed(data))
                .catch((error) => fail(error));
    };
After the createRequest function is to try retrieve the q&a data by trying to FETCH the q&a data from the url that was supplied via the php file. That would be qdatabase.php?category=category using the $_GET method in PHP file called qdatabase.php. It first checks to see if there are any errors loading the database table and throws an error status if there was by calling the handleErrors(response) function. If there is a response of no errors then succeed function is called whatever that function's name that was named when the createRequest = (url, succeed, fail) => function was called. Lastly if there was an error loading the database table then we have to do something about and that what we do withe the fail(error) function that was named when the createRequest functions was called. The names of the functions that were called were createRequest(requestUrl, quizUISuccess, quizUIError). I will explain the quizUISuccess in the next post and the quizUIError later on in this tutorial.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

    /* Success function utilizing FETCH */
    const quizUISuccess = (parsedData) => {

        mainGame.style.display = 'block';
        //gameData = parsedData.sort(() => Math.random() - .5);
        gameData = parsedData;
        createQuiz(gameData[gameIndex]);

    };
OK, I will try to explain the quizUISuccess function as best as I can. This function packs a powerful punch with it being so short and it utilizes a PHP script in order to retrieve the database table (Q&A data). If you want to make it even harder to cheat then uncomment //gameData = parsedData.sort(() => Math.random() - .5) as this will randomize the questions. The data is retrieved from the following PHP script :

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

I have decided to simplify things and make the php file (qdatabase.php) easier to understand and self-contained. What I mean is you don't have to have multiple php files and don't have to deal with Classes.

I think I have commented the code pretty well, so I feel there really isn't a need to go into an in-depth discussion on the lines of code. Here's the file ->

Code: Select all

<?php

require_once '../private/initialize.php';

/*
 * Database Connection 
 */
$db_options = array(
    /* important! use actual prepared statements (default: emulate prepared statements) */
    PDO::ATTR_EMULATE_PREPARES => false
    /* throw exceptions on errors (default: stay silent) */
    , PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    /* fetch associative arrays (default: mixed arrays)    */
    , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$pdo = new PDO('mysql:host=' . DATABASE_HOST . ';dbname=' . DATABASE_NAME . ';charset=utf8', DATABASE_USERNAME, DATABASE_PASSWORD, $db_options);

/*
 * Read Questions & Answers in from the Database Table Named 'trivia_questions'
 */

function readData($category, $pdo) {

    $query = "SELECT id, question, answer1, answer2, answer3, answer4, category FROM trivia_questions WHERE category=:category";
    $stmt = $pdo->prepare($query);


    $stmt->execute([':category' => $category]);

    $result = $stmt->fetchALL(PDO::FETCH_ASSOC);

    return $result;
}

/* Makes it so we don't have to decode the json coming from JQuery */
header('Content-type: application/json');

/*
 * Get Category from the FETCH statment from javascript
 */
$category = htmlspecialchars($_GET['category']);
$api_key = htmlspecialchars($_GET['api_key']); // Not Need if you are not using:

if (isset($api_key) && $api_key === $_SESSION['api_key'] && isset($category)) { // Take out the $api_key if not using:
    /*
     * Call the readData Function
     */
    $data = readData($category, $pdo);

    $mData = []; // Temporary Array Placeholder:
    $answers = []; // Answer Columns from Table Array:
    $finished = []; // Finished Results:
    $index = 0; // Index for answers array:
    $indexArray = 0; // Index for database table array:

    /*
     * Put database table in proper array format in order that
     * JSON will work properly.
     */
    foreach ($data as $qdata) {

        foreach ($qdata as $key => $value) {

            switch ($key) {

                case 'answer1':
                    $answers['answers'][$index] = $value;
                    break;
                case 'answer2':
                    $answers['answers'][$index + 1] = $value;
                    break;
                case 'answer3':
                    $answers['answers'][$index + 2] = $value;
                    break;
                case 'answer4':
                    $answers['answers'][$index + 3] = $value;
                    break;
            }
        } // foreach inner

        /*
         * No Longer needed, but it wouldn't hurt if not unset
         */
        unset($qdata['answer1']);
        unset($qdata['answer2']);
        unset($qdata['answer3']);
        unset($qdata['answer4']);

        $finished = array_merge($qdata, $answers);
        $mData[$indexArray] = $finished;
        $indexArray++;
    }

    output($mData); // Send properly formatted array back to javascript:
}

/*
 * Throw error if something is wrong
 */

function errorOutput($output, $code = 500) {
    http_response_code($code);
    echo json_encode($output);
}

///*
// * If everything validates OK then send success message to Ajax / JavaScript
// */

/*
 * After converting data array to JSON send back to javascript using
 * this function.
 */
function output($output) {
    http_response_code(200);
    echo json_encode($output);
}
This retrieves the Questions and Answers data from the trivia_questions table and I will be showing on how the db table is setup in MySQL in the next post.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

I am going to assume (dangerous word) that you know how to setup a database table, so I just show you how the trivia_questions table is setup in MySQL.

Code: Select all

-- phpMyAdmin SQL Dump
-- version 4.9.5
-- https://www.phpmyadmin.net/
--
-- Host: db2555.perfora.net
-- Generation Time: Apr 07, 2020 at 01:35 PM
-- Server version: 5.5.60-0+deb7u1-log
-- PHP Version: 7.0.33-0+deb9u7

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

--
-- Database: `db336894285`
--

-- --------------------------------------------------------

--
-- Table structure for table `trivia_questions`
--

CREATE TABLE `trivia_questions` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL DEFAULT '1',
  `hidden` varchar(15) COLLATE latin1_german2_ci NOT NULL DEFAULT 'no',
  `question` text COLLATE latin1_german2_ci NOT NULL,
  `answer1` char(100) COLLATE latin1_german2_ci NOT NULL,
  `answer2` char(100) COLLATE latin1_german2_ci NOT NULL,
  `answer3` char(100) COLLATE latin1_german2_ci NOT NULL,
  `answer4` char(100) COLLATE latin1_german2_ci NOT NULL,
  `correct` int(1) NOT NULL,
  `category` varchar(60) COLLATE latin1_german2_ci NOT NULL,
  `play_date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;

--
-- Dumping data for table `trivia_questions`
--

INSERT INTO `trivia_questions` (`id`, `user_id`, `hidden`, `question`, `answer1`, `answer2`, `answer3`, `answer4`, `correct`, `category`, `play_date`) VALUES
(1, 1, 'no', 'What actor from the movie \"Dead Poets Society\" plays Dr. James Wilson on the TV show \"House\"?', 'Ethan Hawke', 'Dylan Kussman', 'Robert Sean Leonard', 'James Waterston', 3, 'movie', '2020-02-07 06:15:14'),
(2, 1, 'no', 'Who played Ferris Bueller in \"Ferris Bueller\'s Day off\"?', 'Tom Hanks', 'Matthew Broderick', 'Alan Ruck', 'Tom Cruise', 2, 'movie', '2020-02-07 06:15:14'),
(3, 1, 'no', 'A coach with a checkered past and a local drunk train a small town high school basketball team to become a top contender for the championship. What is the name of the movie?', 'Heroes', 'Friday Night Lights', 'Blue Chips', 'Hoosiers', 4, 'movie', '2020-02-07 06:15:14'),
(4, 1, 'no', 'What actor provided the voice for Darth Vader for the movie Star Wars(1977)?', 'David Prowse', 'James Earl Jones', 'John Paul Jones', 'Sean Connery', 2, 'movie', '2020-02-07 06:15:14'),
(5, 1, 'no', 'A talented pool hustler has stayed out of the game for years, must go back to his old ways when his little brother gets involved with his enemy, the very man who held him back from greatness. Name this movie?', 'The Color of Money', 'Matchstick Men', 'Poolhall Junkies', 'The Hustler', 3, 'movie', '2020-02-07 06:15:14'),
(6, 1, 'no', 'What actor portrayed Frodo Baggins in the \"Lord of the Rings\" trilogy? ', 'Elijah Wood', 'John Rhys-Davies', 'Ian Mckellen', 'Sean Astin', 1, 'movie', '2020-02-07 06:15:14'),
(7, 1, 'no', 'Who portrayed the Joker in \"The Dark Knight (2008)\"?', 'Christan Bale', 'Aaron Eckhart', 'Michael Caine', 'Heath Ledger', 4, 'movie', '2020-02-07 06:15:14'),
(8, 1, 'no', 'Who was the actor portrayed Gimli in the \"Lord of the Rings\" trilogy?\r', 'Elijah Wood', 'John Rhys-Davis', 'Ian McKellan', 'Sean Astin', 2, 'movie', '2020-02-07 06:15:14'),
(9, 1, 'no', 'Who played Jor-El in \"Superman (1978)\"?\r', 'Glenn Ford', 'Ned Beatty', 'Christopher Reed', 'Marlon Brando', 4, 'movie', '2020-02-07 06:15:14'),
(10, 1, 'no', 'Actor Dustin Huffman was a roommate of what other famous actors?\r\n', 'Robert Duvall and Gene Hackman', 'Robert Duvall and Clint Eastwood', 'Robert Redford and Paul Newman', 'Paul Newman and Clint Eastwood', 1, 'movie', '2020-02-07 06:15:14'),
(11, 1, 'no', 'Who Played George M. Cohan in the movie \"Yankee Doodle Dandy\"?\r', 'James Stewart', 'Fred Astaire', 'James Cagney', 'Gene Kelly', 3, 'movie', '2020-02-07 06:15:14'),
(12, 1, 'no', 'Who were the two main actors in the movie \"Casablanca\"?\r', 'Humphrey Bogart and Audrey Hepburn', 'Humphrey Bogart and Lauren Bacall', 'Humphrey Bogart and Katharine Hepburn', 'Humphrey Bogart and Ingrid Bergman', 4, 'movie', '2020-02-07 06:15:14'),
(13, 1, 'no', 'Who starred in the 1954 version of Sabrina?\r', 'Humphrey Bogart and Audrey Hepburn', 'Harrison Ford and Julia Ormond', 'Humphrey Bogart and Lauren Bacall', 'Humphrey Bogart and Katharine Hepburn', 1, 'movie', '2020-02-07 06:15:14'),
(14, 1, 'no', 'Who starred in the 1995 version of Sabrina?', 'Harrison Ford and Julia Ormond', 'Bill Murray and Julia Ormond', 'Tom Hanks and Julia Ormond', 'Humphrey Bogart and Audrey Hepburn', 1, 'movie', '2020-02-07 06:15:14'),
(15, 1, 'no', 'What was Gary Sinise Character\'s name in \"Forrest Gump\"?\r\n', 'LT. John Taylor', 'LT. Mike Taylor', 'LT. Tony Taylor', 'LT. Dan Taylor', 4, 'movie', '2020-02-07 06:15:14'),
(16, 1, 'no', 'Rand Peltzer is warned by the shop\'s owner that three rules must be obeyed by a Mogwai Owner: 1)Keep it away from bright light, 2) Don\'t get any water on it, 3) and never ever feed it after midnight. What is the name of the movie?\r\n', 'Cujo', 'Gremlins', 'Short Circuit', 'The Thing', 2, 'movie', '2020-02-07 06:15:14'),
(17, 1, 'no', '\"You Maniacs! You blew it up! Ah, damn you! God damn you all to hell! \" What movie did this famous line come from?', 'Planet of the Apes (1968)', 'The Day After Tomorrow', 'The Matrix', 'Soylent Green', 1, 'movie', '2020-02-07 06:15:14'),
(18, 1, 'no', 'What movie did Charlton Heston win an Oscar for Best Actor?', 'Soylent Green', 'Planet of the Apes', 'Ben-Hur', 'The Ten Commandments', 3, 'movie', '2020-02-07 06:15:14'),
(19, 1, 'no', 'Clint Eastwood\'s first Academy Awards came from what movie?', 'Gran Torino', 'Unforgiven', 'Pale Rider', 'Hang \'Em High', 2, 'movie', '2020-02-07 06:15:14'),
(20, 1, 'no', 'Which famous movie actress was known for fruit-laden hats\r', 'Jennifer Lopez', 'Penelope Cruz', 'Carmen Miranda', 'Salma Hayek', 3, 'movie', '2020-02-07 06:15:14'),
(21, 1, 'no', 'Who is William Abbott and Louis Francis Cristillo better known as?\r\n', 'Martin and Lewis', 'Laurel andHardy', 'Abbott and Costello', 'Conwayand Korman', 3, 'movie', '2020-02-07 06:15:14'),
(22, 1, 'no', 'What movie did Dennis Hopper make his debut in?\r', 'Rebel Without a Cause', 'True Grit', 'Speed', 'Easy Rider', 1, 'movie', '2020-02-07 06:15:14'),
(23, 1, 'no', 'Joel had all the normal teenage fantasies...cars, girls, money. Then his parents left for a week, and all his fantasies came true. What is the name of that movie?\r', 'Top Gun', 'Risky Business', 'Hackers', 'The Karate Kid', 2, 'movie', '2020-02-07 06:15:14'),
(24, 1, 'no', 'Who protrayed Mr. Kesuke Miyagi in \"The Karate Kid\"?', 'Pat Morita', 'Raph Macchio', 'George Takei', 'Masi Oka', 1, 'movie', '2020-02-07 06:15:14'),
(25, 1, 'no', 'A young boy is arrested for writing a computer virus and is banned from using a computer until his 18th Birthday. What is the name of the movie?', 'The Net', 'Hackers', 'War Games', 'Code Breakers', 2, 'movie', '2020-02-07 06:15:14'),
(26, 1, 'no', 'What movie did the following come from? \"Ray, people will come Ray. They\'ll come to Iowa for reasons they can\'t even fathom. They\'ll turn up your driveway not knowing for sure why they\'re doing it...\" (Hint: Stars Kevin Costner)\r\n', 'The Natural', 'Field Of Dreams', 'Eight Men Out', 'Pride of the Yankees', 2, 'movie', '2020-02-07 06:15:14'),
(27, 1, 'no', 'Chevy Chase, Rodney Dangerfield, Ted Knight and Bill Murray where all in this great comedy about golf?\r', 'Tin Cup', 'Caddyshack', 'Caddyshack 2', 'The Legend of Bagger Vance', 2, 'movie', '2020-02-07 06:15:14'),
(28, 1, 'no', 'Chuck Nolan is stranded on an island and makes a Wilson volleyball his companion. What is the name of this movie?', 'Castaway', 'The Island', 'Cast Away', 'Stranded', 3, 'movie', '2020-02-07 06:15:14'),
(29, 1, 'no', 'This movie stars Kevin Costener, Rene Russo, Don Johnson, and Cheech Marin and was about a washed up golf pro trying to steal his rival\'s girlfriend. Name the movie?', 'Happy Gilmore', 'Follow the Sun', 'The Legend of Bagger Vance', 'Tin Cup', 4, 'movie', '2020-02-07 06:15:14'),
(30, 1, 'no', 'Follow the Sun was about what real life golf pro?', 'Bobby Jones', 'Ben Hogan', 'Arnold Palmer', 'Jack Nicklaus', 2, 'movie', '2020-02-07 06:15:14'),
(31, 1, 'no', 'What actor was born Marion Robert Morrison?', 'John Wayne', 'Glenn Ford', 'Marlon Brando', 'Clint Eastwood', 1, 'movie', '2020-02-07 06:15:14'),
(32, 1, 'no', 'George Peppard starred with what actress in the movie \"Breakfast at Tiffany\'s (1961)\"?', 'Jane Fonda', 'Katharine Hepburn', 'Audrey Hepburn', 'Claudette Colbert', 3, 'movie', '2020-02-07 06:15:14'),
(33, 1, 'no', 'The President of the United States crashes into Manhattan, now a giant max. security prison and convicted bank robber is sent in for a rescue. ', 'Escape from New York (1981)', 'Nighthawks', 'Hero at Large', 'Fort Apache the Bronx (1981)', 1, 'movie', '2020-02-07 06:15:14'),
(34, 1, 'no', 'An alien (played by Jeff Bridges) takes the form of a young widow\'s husband and kidnaps her so she can drive him from Wisconsin to Arizona. Name the movie?', 'Close Encounters of the Third Kind', 'E.T.: The Extra-Terrestrial', 'Starman', 'Starperson', 3, 'movie', '2020-02-07 06:15:14'),
(35, 1, 'no', 'This movie in 1972 was Directed by Francis Ford Coppola and was about about the mob?', 'Goodfellas', 'Scareface', 'The Godfather', 'The Godfather Part II', 3, 'movie', '2020-02-07 06:15:14'),
(36, 1, 'no', 'Who played Elliot in E.T.: The Extra-Terrestrial?', 'C. Thomas Howell', 'Matt Dillion', 'Henry Thomas', 'Patrick Swayze', 3, 'movie', '2020-02-07 06:15:14'),
(37, 1, 'no', 'Who played Ponyboy Curtis in the movie \"The Outsiders\"?', 'C. Thomas Howell', 'Matt Dillion', 'Henry Thomas', 'Patrick Swayze', 1, 'movie', '2020-02-07 06:15:14'),
(38, 1, 'no', 'What was Patrick Swayze last movie before his untimely death?', 'Power Blue', 'Road House', 'Dirty Dancing', 'Ghost', 1, 'movie', '2020-02-07 06:15:14'),
(39, 1, 'no', 'A troubled teenager is plagued by visions of a large bunny rabbit that manipulates him to commit a series of crimes, after narrowly escaping a bizarre accident?', 'Edward Scissorhands', 'Donnie Darko', 'Donnie Brasco', 'Flatliners', 2, 'movie', '2020-02-07 06:15:14'),
(40, 1, 'no', 'What movie had these great actors/actresses: Kevin Bacon, Lori Singer, John Lithgrow, Dianne West, Chris Penn and Sarah Jessica Parker?', 'Girls Just Want to Have Fun', 'Footloose', 'Night of the Comet', 'Dirty Dancing', 2, 'movie', '2020-02-07 06:15:14'),
(41, 1, 'no', 'Bob Barker has a fight with Adam Sandler in what movie?\r', 'Big Daddy', 'The Waterboy', 'Happy Gilmore', 'Mr. Deeds', 3, 'movie', '2020-02-07 06:15:14'),
(42, 1, 'no', 'A high-school boy follows an up-and-coming rock band for Rolling Stone Magazine. What is the name of the movie?', 'Almost Famous', 'Fool\'s Gold', '200 Cigarettes', 'This is Spinal Tap', 1, 'movie', '2020-02-07 06:15:14'),
(43, 1, 'no', 'Who directed the movie \"Stand by Me\"?', 'Penny Marshall', 'Rob Reiner', 'Ron Howard', 'Stephen King', 2, 'movie', '2020-02-07 06:15:14'),
(44, 1, 'no', '\"Stand By Me\" was based on the novel \"The Body\" which was written by?', 'Rob Reiner', 'Ron Howard', 'Stephen King', 'Abe Kobo', 3, 'movie', '2020-02-07 06:15:14'),
(45, 1, 'no', 'Name the top two stars of \"The Shawshank Redemption\"?', 'Tom Cruise and Morgan Freeman', 'Tim Robbins and Denzel Washington', 'Morgan Freeman and Denzel Washington', 'Tim Robbins and Morgan Freeman', 4, 'movie', '2020-02-07 06:15:14'),
(46, 1, 'no', 'Mortimer Duke and Randolph Duke make a $1.00 bet in what movie?', 'Harry and the Hendersons', 'Trading Places', 'Coming to America', 'Cocoon', 2, 'movie', '2020-02-07 06:15:14'),
(47, 1, 'no', 'Who starred in \"The Long, Long Trailer\"?', 'Katharine Hepburn and Humphrey Bogart', 'Cary Grant and Rosalind Russell', 'Desi Arnaz and Lucille Ball', 'Cary Grant and Lucille Ball', 3, 'movie', '2020-02-07 06:15:14'),
(48, 1, 'no', 'What famous movie shows a shower scene where Marion Crane(Janet Leigh) gets stabbed to death?', 'Psycho', 'Friday the 13th', 'A Nightmare on Elm Street', 'Halloween', 1, 'movie', '2020-02-07 06:15:14'),
(49, 1, 'no', 'Who directed Cocoon?', 'Penny Marshall', 'Rob Reiner', 'Ron Howard', 'Henry Wrinkler', 3, 'movie', '2020-02-07 06:15:14'),
(50, 1, 'no', 'Most of the World\'s population is wiped out on Earth, leaving two Valley Girls to fight the evil types who survive. Name the movie?', 'Armageddon', 'War of the Worlds', 'Deep Impact', 'Night of the Comet', 4, 'movie', '2020-02-07 06:15:14'),
(51, 1, 'no', 'What famous actor played halfback for Florida State University, only to be injured in the first game of the season? (This ended his NFL dream)\r', 'Adam Sandler', 'Burt Reynolds', 'Tom Selleck', 'Clint Eastwood', 2, 'movie', '2020-02-07 06:15:14'),
(52, 1, 'no', 'Cary Grant, Victor McLaglen, Douglas Fairbanks Jr. and Sam Jaffe starred in what movie?\r\n', 'The Longest Day', 'Gunga Din', 'Wizard of Oz', 'Gone With the Wind', 2, 'movie', '2020-02-07 06:15:14'),
(53, 1, 'no', 'Sheb Wooley portrayed Cletus in the movie \"Hoosiers\", but is better known for this novelty song?\r\n', 'Alley-Oop', 'The Purple People Eater', 'Witch Doctor', 'Monster Mash', 2, 'movie', '2020-02-07 06:15:14'),
(54, 1, 'no', 'The Mummy and The Mummy Returns two main stars are?\r', 'Tom Hanks and Rachel Weisz', 'Harrison Ford and Rachel Weisz', 'Tom Hanks and Meg Ryan', 'Brendan Fraser and Rachel Weisz', 4, 'movie', '2020-02-07 06:15:14'),
(55, 1, 'no', 'Who has won the most Oscars for Best Actress?\r', 'Meryl Streep', 'Katharine Hepburn', 'Audrey Hepburn', 'Jane Fonda', 2, 'movie', '2020-02-07 06:15:14'),
(56, 1, 'no', 'Jane Russell appeared as Calamity Jane with Bob Hope in what Movie? ', 'The PaleFace', 'Unforgiven', 'Palerider', 'The Man Who Shot Liberty Valance', 1, 'movie', '2020-02-07 06:15:14'),
(57, 1, 'no', 'Who were the first two astronauts to walk on the moon?', 'Neil Armstrong and Edwin Aldrin, Jr.', 'Michael Collins and Neil Armstrong', 'Edwin  Aldrin, Jr. and Clint Eastwood', 'Alan L. Bean and Charles Conrad, Jr.', 1, 'space', '2020-02-07 06:15:14'),
(58, 1, 'no', 'What was the date that Neil Armstrong walk on the moon?', 'August 28, 1973', 'March 1, 1967', 'July 20, 1969', 'June 20, 1980', 3, 'space', '2020-02-07 06:15:14'),
(59, 1, 'no', 'What does NASA stand for?', 'North American Space Agency', 'National Aeronautics and Space Administration', 'New Age Stuff Administration', 'National Association of Solar Area', 2, 'space', '2020-02-07 06:15:14'),
(60, 1, 'no', 'Where did th Mercury, Gemini and Apollo spacecraft land when they returned to Earth?', 'Roswell, NM', 'Florida', 'Pacific or Atlantic', 'Michigan', 3, 'space', '2020-02-07 06:15:14'),
(61, 1, 'no', 'Who was the first American woman in space?', 'Sally Munster', 'Sally Walk', 'Sally Ride', 'Valentina Vladimirovna Tereshkova', 3, 'space', '2020-02-07 06:15:14'),
(62, 1, 'no', 'Who was the only original Mercury 7 astronaut to walk on the Moon?', 'Alan B. Shepard, Jr.', 'Walter M. Schirra', 'John Glenn', 'Virgil I. \'Gus\' Grissom', 1, 'space', '2020-02-07 06:15:14'),
(63, 1, 'no', 'Who was the first man in space?', 'Alan B. Shepard, Jr.', 'John Glenn', 'Yuri A. Gagarin', 'Neil Alden Armstrong', 3, 'space', '2020-02-07 06:15:14'),
(64, 1, 'no', 'Who was the first American to orbit the Earth?', 'Alan B. Shepard, Jr.', 'John Glenn', 'Yuri A. Gagarin', 'Neil Alden Armstrong', 2, 'space', '2020-02-07 06:15:14'),
(65, 1, 'no', 'Who was the first American in space?', 'Alan B. Shepard, Jr.', 'John Glenn', 'Yuri A. Gagarin', 'Neil Alden Armstrong', 1, 'space', '2020-02-07 06:15:14'),
(66, 1, 'no', 'Who was the second person to walk on the Moon?', 'Alan B. Shepard, Jr.', 'Edwin \'Buzz\' Aldrin, Jr.', 'Neil Armstrong', 'Edward Higgins White II', 2, 'space', '2020-02-07 06:15:14'),
(67, 1, 'no', 'Who was the first person to break the sound barrier in an aircraft?', 'Capt. Charles E. Yeager', 'Neil Armstrong', 'John Glenn', 'Alan L. Nean', 1, 'space', '2020-02-07 06:15:14'),
(68, 1, 'no', 'What Space Shuttle was the first to be launched into space?', 'Challenger', 'Discovery', 'Columbia', 'Atlantis', 3, 'space', '2020-02-07 06:15:14'),
(69, 1, 'no', 'How many people have walked on the moon?', '17', '10', '16', '12', 4, 'space', '2020-02-07 06:15:14'),
(70, 1, 'no', 'What happened to the Space Shuttle Challenger on January 28, 1986?', 'Shuttle was destroyed during re-entry', 'Shuttle exploded after 73 second of flight', 'Shuttle was first launched!', 'Repaired the Hubble Telescope', 2, 'space', '2020-02-07 06:15:14'),
(71, 1, 'no', 'Who was the first American to walk in space?', 'Ed White', 'Alan B. Shepard, Jr.', 'John Glenn', 'Neil Armstrong', 1, 'space', '2020-02-07 06:15:14'),
(72, 1, 'no', 'Who was the first person to walk in space?', 'Aleksei Leonov', 'Ed White', 'Yuri A. Gagarin', 'John Glenn', 1, 'space', '2020-02-07 06:15:14'),
(73, 1, 'no', 'Who so far is America\'a Oldest Astronaut?', 'Scott Carpentar', 'Gordon Cooper', 'John Glenn', 'Alan B. Shepard, Jr.', 3, 'space', '2020-02-07 06:15:14'),
(74, 1, 'no', 'Viking Mission to Mars was composed of how many spacecraft?', '1', '4', '3', '2', 4, 'space', '2020-02-07 06:15:14'),
(75, 1, 'no', 'What were the name of the two rovers of the Mars Exploration Rover Mission (MER)?', 'Enterprise and Columbia', 'Spirit and Opportunity', 'Ghost and Spirit', 'Enterprise and Opportunity', 2, 'space', '2020-02-07 06:15:14'),
(76, 1, 'no', 'Who was supposed to walk on the moon on the Apollo 13 mission to the moon, but didn\'t because of an incident?', 'Jim Lovell and Jack Swigert', 'Jim Lovell and Fred Haise', 'Jack Swigert and Ken Mattingly', 'Jim Lovell and Ken Mattingly', 2, 'space', '2020-02-07 06:15:14'),
(77, 1, 'no', 'What was the first United States space station called?\r', 'MIR', 'Skylab', 'Death Star', 'Moonraker', 2, 'space', '2020-02-07 06:15:14'),
(78, 1, 'no', 'What was the United States first space tragedy?', 'Challenger', 'Columbia', 'Apollo 1', 'Hindenburg', 3, 'space', '2020-02-07 06:15:14'),
(79, 1, 'no', 'What was the first space probe to leave the solar system?', 'Voyager 2', 'Voyager 1', 'Viking 1', 'Mariner 3', 2, 'space', '2020-02-07 06:15:14'),
(80, 1, 'no', 'How many moon landings have there been?', '6', '12', '8', '14', 1, 'space', '2020-02-07 06:15:14'),
(81, 1, 'no', 'Who designed the Saturn V rocket that propelled man to the moon?', 'Albert Einstein', 'John F. Kennedy', 'Wernher von Braun', 'Bill Gates', 3, 'space', '2020-02-07 06:15:14'),
(82, 1, 'no', 'What Apollo mission was the last to land on the moon?', 'Apollo 16', 'Apollo 13', 'Apollo 15', 'Apollo 17', 4, 'space', '2020-02-07 06:15:14'),
(83, 1, 'no', 'What are Saturn\'s rings made of?', 'The rings are made of dust particles.', 'The rings are made of chunks of water ice.', 'The rings are made of milkyways.', 'The rings are made up of gas.', 2, 'space', '2020-02-07 06:15:14'),
(84, 1, 'no', 'What is the name of the next generation United States spacecraft this is going to take humans to Mars?', 'Apollo', 'Mecury', 'Aries', 'Orion', 4, 'space', '2020-02-07 06:15:14'),
(85, 1, 'no', 'How many planets in our solar system?', '7', '8', '9', '6', 2, 'space', '2020-02-07 06:15:14'),
(86, 1, 'no', 'What planet is 3rd from the sun?', 'Venus', 'Mars', 'Earth', 'Saturn', 3, 'space', '2020-02-07 06:15:14'),
(87, 1, 'no', 'What four inner solar system planets fall under the category of terrestrial planets?', 'Saturn, Mars, Jupiter, Uranus', 'Mercury, Venus, Earth, and Mars', 'Earth, Mars, Saturn, Neptune', 'Jupiter, Saturn, Mars, Venus', 2, 'space', '2020-02-07 06:15:14'),
(88, 1, 'no', 'What two planets are considered gas giants (composed mainly of hydrogen and helium)?', 'Jupiter and Saturn', 'Uranus and Neptune', 'Mercury and Mars', 'Venus and Mars', 1, 'space', '2020-02-07 06:15:14'),
(89, 1, 'no', 'What two planets are considered ice giants (containing many elements greater than hydrogen and helium)?', 'Jupiter and Saturn', 'Uranus and Neptune', 'Mercury and Mars', 'Venus and Mars', 2, 'space', '2020-02-07 06:15:14'),
(90, 1, 'no', 'What are the eight planets in our solar system?', 'Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Pluto', 'Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Makemake', 'Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune', 'Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Ceres', 3, 'space', '2020-02-07 06:15:14'),
(91, 1, 'no', 'What planet was demoted from planetary status and is now considered a dwarf planet?', 'Pluto', 'Ceres', 'MakeMake', 'Neptune', 1, 'space', '2020-02-07 06:15:14'),
(92, 1, 'no', 'What is the closet galaxy to our Milky Way? ', 'Draco Dwarf', 'Andromeda', 'Ursa Minor Dwarf', 'Canis Major Dwarf', 2, 'space', '2020-02-07 06:15:14'),
(93, 1, 'no', 'How many moons does Mars have?', '1', '2', '3', '4', 2, 'space', '2020-02-07 06:15:14'),
(94, 1, 'no', 'What are the two moons of Mars called?', 'Phobos and Deimos', 'Dione and Phobos', 'Enceladus and Dione', 'Kari and Dione', 1, 'space', '2020-02-07 06:15:14'),
(95, 1, 'no', 'How does a day last on Mercury?', '24 Hours', 'Approximately as long as 59 days on earth', '1 earth year', '2 days', 2, 'space', '2020-02-07 06:15:14'),
(96, 1, 'no', 'Who is the Astronaut that hit 2 golfballs on the moon?', 'Neil Armstrong', 'Buzz Aldrin', 'Buzz Lightyear', 'Alan B. Shepard', 4, 'space', '2020-02-07 06:15:14'),
(97, 1, 'no', 'What is the giant red spot on Jupiter?', 'A land mass', 'A gigantic storm that has been raging for hundred of years', 'There is no red spot on Jupiter', 'Scientists still haven&#39;t determined what the red spot is', 2, 'space', '2020-02-07 06:15:14'),
(98, 1, 'no', 'What was the first spacecraft to visit the planet Venus?', 'Pioneer Venus', 'Magellan', 'Marineer 2', 'Marineer 1', 3, 'space', '2020-02-07 06:15:14'),
(99, 1, 'no', 'This planet is the sixth planet from the Sun and the second largest in the Solar System, after Jupiter. It is a gas giant with an average radius about nine times that of Earth.', 'Mars', 'Saturn', 'Neptune', 'Venus', 2, 'space', '2020-02-07 06:15:14'),
(100, 1, 'no', 'What is the interplanetary space probe that study the planet Pluto, its moons and the Kuiper belt?', 'Voyager 1', 'New Horizons', 'Voyager 2', 'Marineer 1', 2, 'space', '2020-02-07 06:15:14'),
(101, 1, 'no', 'What was the first U.S. Satellite called?', 'Spuknit 1', 'Spuknit 2', 'Explorer 1', 'Exhibition 1', 3, 'space', '2020-02-07 06:15:14'),
(102, 1, 'no', 'This planet is known as the wandering star and is the 4th brightest object in the sky? (after the Sun, Venus and the Moon) ', 'Neptune', 'Saturn', 'Jupiter', 'Mercury', 3, 'space', '2020-02-07 06:15:14'),
(103, 1, 'no', 'What picture won the Oscar for best picture for 2017?', 'La La Land', 'Moonlight', 'Fences', 'Hidden Figures', 2, 'movie', '2020-02-07 06:15:14'),
(104, 1, 'no', 'Who won the 2017 Oscar for best actor?', 'Denzel Washington - \"Fences\"', 'Ryan Gosling - \"La La Land\"', 'Victor Mortensen - \"Captain Fantastic\"', 'Casey Affleck - \"Manchester by the Sea\"', 4, 'movie', '2020-02-07 06:15:14'),
(105, 1, 'no', 'Who is the Founder and CEO of SpaceX?', 'Jeff Bezos', 'Larry Page', 'Elon Musk', 'Mark Zuckerberg', 3, 'space', '2020-02-07 06:15:14'),
(106, 1, 'no', 'Who were the two main actors that starred in the \"Lethal Weapon\" movies?', 'Damon Wayans & Clayne Crawford', 'Mel Gibson & Danny Glover', 'Tom Hanks & Clint Eastwood', 'Bob Hope & Bing Crosby', 2, 'movie', '2020-02-07 06:15:14'),
(108, 1, 'yes', 'Christopher Reeve played what SuperHero?', 'Spiderman', 'Superman', 'Thor', 'The Flash', 2, 'movie', '2020-02-07 06:15:14'),
(109, 1, 'no', 'In optics is a hole or an opening through which light travels. More specifically, the [blank] and focal length of an optical system determine the cone angle of a bundle of rays that come to a focus in the image plane. An optical system typically has many openings or structures that limit the ray bundles', 'ISO', 'Aperture', 'IBIS', '', 2, 'photography', '2020-02-07 06:17:41'),
(110, 1, 'no', '[Blank] is the length of time when the film or digital sensor inside the camera is exposed to light, also when a camera\'s shutter is open when taking a photograph. The amount of light that reaches the film or image sensor is proportional to the exposure time.', 'ISO', '', '', 'Shutter Speed or Exposure Time', 4, 'photography', '2020-02-07 06:31:19'),
(111, 1, 'no', 'In Digital Photography [blank] measures the sensitivity of the image sensor. The same principles apply as in film photography – the lower the number the less sensitive your camera is to light and the finer the grain.', 'Aperture', 'Shutter Speed or Exposure Time', 'ISO', 'IBIS', 3, 'photography', '2020-02-07 07:11:11'),
(112, 1, 'no', 'The [blank], which is also known as the [blank], is the ratio of the lens focal length to the diameter of the entrance pupil. In simple terms, [blank] is the number that your camera shows you when you change the size of the lens aperture.', 'ISO or Shutter Speed', 'Aperture or ISO', 'f-stop or f-number', 'Shutter Speed or Aperture', 3, 'photography', '2020-02-07 09:02:02'),
(113, 1, 'no', '[blank] was a landscape photographer and environmentalist known for his black-and-white images of the American West. He helped found Group f/64, an association of photographers advocating \"pure\" photography which favored sharp focus and the use of the full tonal range of a photograph. He and Fred Archer developed an exacting system of image-making called the Zone System, a method of achieving a desired final print through a deeply technical understanding of how tonal range is recorded and developed in exposure, negative development, and printing. The resulting clarity and depth of such images characterized his photography.', 'Robert Capa', 'Steve McCurry', 'Ansel Adams', 'David Bailey', 3, 'photography', '2020-02-09 18:04:07'),
(114, 1, 'no', '[Blank] was one of the earliest photographers in American history, best known for his scenes of the Civil War. He studied under inventor Samuel F. B. Morse, who pioneered the daguerreotype technique in America. [Blank] opened his own studio in New York in 1844, and photographed Andrew Jackson, John Quincy Adams, and Abraham Lincoln, among other public figures.', 'Robert Capa', 'Steve McCurry', 'Ansel Adams', 'Matthew Brady', 4, 'photography', '2020-02-09 20:22:41'),
(115, 1, 'no', 'The [Blank] is a method of estimating correct daylight exposures without a light meter. ... As the rule is based on incident light, rather than reflected light as with most camera light meters, very bright or very dark subjects are compensated for.', 'sunny 8 rule', 'sunny 16 rule', 'cloudy 11 rule', 'rule of 3rds', 2, 'photography', '2020-02-09 20:27:22'),
(116, 1, 'no', 'An English transliteration of a Japanese word that means \"haze\" or \"blur.\" [Blank] refers to the out-of-focus areas in a photograph with limited depth of field, particularly around, but not limited to, the highlight areas. [Blank] appears as little circles in the unsharp areas. Depending upon the shape of the opening formed by the blades of the lens\'s aperture, the circles appear either more or less circular.', 'Bracketing', 'Chromatic Aberration', 'Color Depth', 'Bokeh', 4, 'photography', '2020-02-09 22:10:35'),
(117, 1, 'no', 'A [Blank] camera is one that utilizes a mirror system to reflect the light (or latent image) coming through the lens to a visible screen. The image seen in the camera\'s viewfinder is identical to what strikes the camera\'s imaging sensor (or film plane). This system provides the most accurate way to frame and focus. The [Blank] system avoids the parallax problem that plagues most direct view cameras.', 'shutter', 'reflex', 'flux', 'flash', 2, 'photography', '2020-02-09 22:16:15'),
(118, 1, 'no', 'The camera\'s ability to correct color cast or tint under different lighting conditions including daylight, indoor, fluorescent lighting, and electronic flash. Is known as? ', 'Color Calibration', 'Color Space', 'White Balance', 'Dynamic Range', 3, 'photography', '2020-02-09 22:21:05'),
(119, 1, 'no', '[Blank] is an American portrait photographer. She is best known for her engaging portraits—particularly of celebrities—which often feature subjects in intimate settings and poses. ', 'Cindy Sherman', 'Ruth Bernhard', 'Annie Leibovitz', 'Graciela Iturbide', 3, 'photography', '2020-02-09 22:30:33'),
(120, 1, 'no', 'An [Blank] digitally replicates the field of view of the area captured by the camera lens. While once considered a poor replacement for optical viewfinders, newer [Blank]s containing a million-plus pixels and faster refresh times have become quite accurate, in many cases approaching the clarity levels of optical finders. An advantage of [Blank]s is their ability to display exposure data and grids on demand.', 'Electronic Viewfinder (EVF)', 'Rangefinder and Reflex Viewfinders (RRVF)', 'Spot Metering', 'RGB Color Space', 1, 'photography', '2020-02-11 22:53:24'),
(121, 1, 'no', 'Adding to or subtracting from the \"correct\" exposure time indicated by the camera\'s light meter, which results in a final exposure that is either lighter or darker than the recommended [Blank] time. Most cameras allow for [Blank] in 1/2, 1/3, or full-stop increments. Note that the \"correct\" exposure is not necessarily the \"best\" exposure.', 'ISO', 'Focal Length', 'Exposure Compensation', 'Shutter Speed', 3, 'photography', '2020-02-16 10:21:42'),
(122, 1, 'no', 'Literally, the measure of how much of the background and foreground area before and beyond your subject is in focus.', 'ISO', 'Aperture', 'f-stop or f-number', 'Depth of Field', 4, 'photography', '2020-02-16 10:24:50');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `trivia_questions`
--
ALTER TABLE `trivia_questions`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `trivia_questions`
--
ALTER TABLE `trivia_questions`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=123;
COMMIT;
You could actually insert this table into your database table by using SQL. (Ain't I nice? :D )

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Back to the javascript file (game.js) as the data is now retrieved from the php file (qdatabase.php).

Code: Select all

    /* Populate Question, Create Answer Buttons */
    const createQuiz = (gameData) => {

        /*
         * The Element interface's scrollIntoView() method scrolls the element's
         * parent container such that the element on which 
         * scrollIntoView() is called is visible to the user
         */
        d.getElementById('mainGame').scrollIntoView();

        startTimer(dSec);

        question.textContent = gameData.question;

        /*
         * Create Buttons then insert answers into buttons that were
         * create. 
         */
        gameData.answers.forEach((value, index) => {
            /*
             * Don't Show Answers that have a Blank Field
             */
            if (value !== "") {
                var gameButton = buttonContainer.appendChild(d.createElement('button'));
                gameButton.id = 'answer' + (index + 1);
                gameButton.className = 'answerButton';
                gameButton.setAttribute('data-correct', (index + 1));
                gameButton.addEventListener('click', clickHandler, false);
                gameButton.appendChild(d.createTextNode(value));
            }
        });
    };

    /* Success function utilizing FETCH */
    const quizUISuccess = (parsedData) => {

        mainGame.style.display = 'block';
        //gameData = parsedData.sort(() => Math.random() - .5);
        gameData = parsedData;
        createQuiz(gameData[gameIndex]);

    };
Like I already stated the parsedData doesn't need to be parsed as it already is in the JSON format. Next we assign (the value the array of objects) that we retrieved from the parsedData to the global variable gameData. The createQuiz(gameData[gameIndex]) function is called with the gameIndex initialized to 0 (Arrays start at 0 not 1). The const createQuiz = (gameData) => function is where the questions and answers are finally displayed and the timer started by calling the startTimer(dSec) function.

The question.textContent = gameData.question to the <h2 id="question">What is the Question?</h2> h2 HTML tag displays the question to the user.

The answer button is assigned a gameButton.setAttribute('data-correct', (index + 1)) so the user's selection corresponds to a number (1-4) in order to check it against the correct answer. The answers using a forEach loop to add event listeners and append ( gameButton.appendChild(d.createTextNode(value)) ) the answers to their respective <div id="buttonContainer"></div> HTML tags just as long as the answer field in the database isn't empty. This is why the if statement is needed in order to check for a null answer field. This creates it where you can have 1 to 4 answers though only having one answer choice would be pretty stupid. :D This creates the answer buttons that the user can click to select what he/she thinks is the correct answer.

Locked