Trivia Game Ajax Edition

This version of the trivia game uses AJAX queries to get questions and keeps the score locally until the user leaves the page. This version does not manage sessions or update the user’s score on the server.

index.php

This loads the Front Controller and passes it the appropriate command from the GET variable.

<?php
spl_autoload_register(function ($classname) {
    include "classes/$classname.php";
});

// Start the session
session_start();

// Use GET requests
$request = "question_page";
if (isset($_GET["command"])) {
    $request = $_GET["command"];
}


// Create a new Trivia object
$trivia = new Trivia($request);

// Call the controller to determine what to do
$trivia->run();

TriviaController.php

The Front Controller. If the user queries get_question, it will return a JSON object with the question information.

<?php

class Trivia {

    private $db;

    private $command;
    
    public function __construct($request) {
        $this->db = new Database();
        $this->command = $request;
    }

    public function run() {
        switch ($this->command) {
            case "get_question":
                $this->getQuestion();
                break;
            case "question_page":
            default:
                $this->questionPage();
                break;
        }
    }

    public function questionPage() {
        // Now we will show the template by default, but with NO data
        // That will be loaded by AJAX
        include("templates/question.php");
    }

    public function getQuestion() {
        $data = $this->db->query("select * from question order by rand() limit 1;");
        if (!isset($data[0])) {
            die("No questions in the database");
        }
        $question = $data[0];
        
        // Return JSON only
        header("Content-type: application/json");
        echo json_encode($question, JSON_PRETTY_PRINT);
    }
}

question.php

The template that includes our JavaScript and AJAX calls

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Trivia Game AJAX</title>

        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous"> 
    </head>

    <body>


        <div class="container" style="margin-top: 15px;">
            <div class="row col-xs-8">
                <h1>CS4640 Television Trivia Game - AJAX Edition</h1>
                <h3>Score: <span id="score">0</span></h3>
            </div>
            <div class="row">
                <div class="col-xs-8 mx-auto">
                <form>
                    <div class="h-100 p-5 bg-light border rounded-3">
                    <h2>Question</h2>
                    <p id="question_text"></p>
                    </div>
                    <div class="h-10 p-5 mb-3">
                        <input type="text" class="form-control" id="answer" name="answer" placeholder="Type your answer here">
                    </div>
                    <div class="text-center">                
                    <button class="btn btn-primary" onclick="checkAnswer(); return false;">Submit</button>
                    </div>
                    
                    <div id="message"></div>
                </form>
                </div>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
        
        <script>
        var question = null;
        var score = 0;
        
        function getQuestion() {
            // instantiate the object
            var ajax = new XMLHttpRequest();
            // open the request
            ajax.open("GET", "?command=get_question", true);
            // ask for a specific response
            ajax.responseType = "json";
            // send the request
            ajax.send(null);
            
            // What happens if the load succeeds
            ajax.addEventListener("load", function() {
                // set question
                if (this.status == 200) { // worked 
                    question = this.response;
                    displayQuestion();
                }
            });
            
            // What happens on error
            ajax.addEventListener("error", function() {
                document.getElementById("message").innerHTML = 
                    "<div class='alert alert-danger'>An Error Occurred</div>";
            });
        }
        
        // Method to display a question
        function displayQuestion() {
            // Why innerHTML and not textContent?
            document.getElementById("question_text").innerHTML = question.question;
        }
        
        // Check an answer
        function checkAnswer() {
            answer = document.getElementById("answer").value;
            document.getElementById("answer").value = "";
            if (question.answer == answer) {
                // If correct, update score, display message, and new question
                score += question.points;
                document.getElementById("score").textContent = score;
                document.getElementById("message").innerHTML = 
                            "<div class='alert alert-success'>Correct!</div>";
                setTimeout(function() { // Give the user 5 seconds to read the message
                    getQuestion();
                    document.getElementById("message").textContent = "";
                    }, 5000); // milliseconds -- this is 5 seconds
            } else if (answer == "HINT") {
                // If they ask for a HINT then show them the answer
                document.getElementById("message").innerHTML = "<div class='alert alert-info'>Hint: " +
                    question.answer + "</div>";
            } else {
                // If they get it wrong, let them know
                document.getElementById("message").innerHTML = "<div class='alert alert-danger'>" 
                    + answer + " is not correct</div>";
            }
        }
        
        // Need to add the initial question load
        getQuestion();
        
        </script>
    </body>
</html>