In this chapter we'll be making two changes to the trivia quiz. First, we'll allow the user to select how long she has to complete the quiz and second, the user gets to choose how many questions she wants to answer.
Converting the quiz to a timer-based one only requires that we change two pages, namely QuizPage.htm and GlobalFunctions.htm.
Our first change in QuizPage.htm will be to the form at the start of the quiz, because we need to allow the user to select her time limit and number of questions. Then we'll change the cmdStartQuiz_onclick() function so that when it calls the resetQuiz() function in the GlobalFunctions.htm page, it also passes (as parameters) the time limit and number of questions that the user has selected.
Now we go on to the GlobalFunctions.htm page itself, where we need to alter the resetQuiz() function so that, if necessary, it starts a timer based on the time limit selected. Then new functions dealing with the time limit need to be created: one puts a message in the scroll bar notifying the user how much time she has left; the other deals with the situation when the time limit is up.
We'll start by making the changes to QuizPage.htm, so open this in your text editor.
The first change we'll make is to the form, which currently just contains a button.
<form name="frmQuiz"> <p> Number of Questions <br> <select name=cboNoQuestions size=1> <option value=3>3 <option value=5>5 </select> </p> <p> Time Limit <br> <select name=cboTimeLimit size=1> <option value=-1>No Time Limit <option value=60>1 Minute <option value=180>3 Minutes <option value=300>5 Minutes </select> </p> <input name=cmdStartQuiz type=button value="Start Quiz" onclick="return cmdStartQuiz_onclick()"> </form>
We've added two new controls; both are drop-down list boxes created using the <select> tag. In the first list box, we enable the user to choose how many questions she wants to answer, and in the second the time limit within which she must answer the questions.
Next we need to alter the cmdStartQuiz_onclick() function defined at the top of the page.
<script language=JavaScript> function cmdStartQuiz_onclick() { var cboNoQuestions = document.frmQuiz.cboNoQuestions; var noQuestions = cboNoQuestions.options[cboNoQuestions.selectedIndex].value; var cboTimeLimit = document.frmQuiz.cboTimeLimit; var timeLimit = cboTimeLimit.options[cboTimeLimit.selectedIndex].value; window.top.fraTopFrame.fraGlobalFunctions.resetQuiz(noQuestions,timeLimit); window.location.href = "AskQuestion.htm"; } </script>
This function is connected to the cmdStartQuiz button's onclick event and is how the user kicks off the quiz. Previously we just called the resetQuiz() function in the global module and then loaded the AskQuestion.htm page. Now we need to get the values the user has selected in the select elements for the number of questions and time limit. As we'll see in a minute, the resetQuiz() function has been changed and now takes two parameters, namely the number of questions to be answered and a time limit.
At the start of the cmdStartQuiz_onclick() function, we first set a variable cboNoQuestions to reference the cboNoQuestions control in the form (where the user chooses how many questions she wants to answer). We can then use that reference instead of the more long-winded full reference via the document and form. The benefit of doing this is to keep the lines shorter and more readable.
On the second line we get the value of the selected option in the select control for the number of questions and store this value in the noQuestions variable.
In the following two lines we do exactly the same thing again, except this time it's the time limit control and value that we need to deal with.
Finally in the last new line of the function, we reset the quiz, this time passing the number of questions to be answered (noQuestions) and time limit (timeLimit).
That completes all the changes for the page QuizPage.htm, so you can resave the page in your text editor and close it.
Let's now turn our attention to the GlobalFunctions.htm page and start by looking at the changes we need to make to the resetQuiz() function, as shown in the following:
function resetQuiz(numberOfQuestions, SelectedTimeLimit) { timeLeft = SelectedTimeLimit; totalQuestionsToAsk = numberOfQuestions; var indexCounter; currentQNumber = -1; questionsAsked = new Array(); for (indexCounter = 0; indexCounter < questions.length;indexCounter++) { questionsAsked[indexCounter] = false; } numberOfQuestionsAsked = 0; numberOfQuestionsCorrect = 0; if (timeLeft == -1) { window.status = "No Time Limit"; } else { quizTimerId = window.setInterval("updateTimeLeft()",1000); } }
The first change is to our function's definition. Previously it took no parameters, now it takes two: the number of questions to be answered and the time limit within which the quiz must be completed.
Our next change is to set two new global variables, timeLeft and totalQuestionsToAsk, to the values passed to the function. We'll see later that these global variables are used elsewhere to determine if enough questions have been asked and to check to see if the time limit has been reached.
The final change to this function is the setting of the timer that will monitor how much time is left. One of the options open to the user is no time limit at all, which is represented by the value -1. If the time limit is -1, we just put a message in the status bar of the browser window using the window object's status property. Note that on Netscape browsers the "No Time Limit" text in the status bar gets overwritten by "Document:Done" when the frames change. If, however, it's not -1, we start a timer, using setInterval(), which will call the function updateTimeLeft() every second.
The updateTimeLeft() function is a new function, so let's create that now. Add it to the script block underneath all the other function definitions.
function updateTimeLeft() { timeLeft--; if (timeLeft == 0) { alert("Time's Up"); numberOfQuestionsAsked = totalQuestionsToAsk; window.top.fraQuizPage.location.href = "AskQuestion.htm"; } else { var minutes = Math.floor(timeLeft / 60); var seconds = timeLeft - (60 * minutes); if (minutes < 10) minutes = "0" + minutes; if (seconds < 10) seconds = "0" + seconds; window.status = "Time left is " + minutes + ":" + seconds; } }
This function does three things: it decrements the time left, it stops the quiz if the time left has reached zero, and finally it notifies the user of the time remaining by putting a message in the browser's status bar.
As we saw earlier, when the quiz is reset using the resetQuiz() function, the global variable timeLeft is set to the amount of time, in seconds, that the user has to complete the quiz. The updateTimeLeft() function is called every second, and in the first line
timeLeft--;
we decrement the number of seconds left by 1.
In the following if statement we check to see if timeLeft is zero. If it is, then it means no seconds are left, and we end the quiz by setting the global variable numberOfQuestionsAsked to the same value as the number of questions the user wanted to answer, which is stored in global variable totalQuestionsToAsk. Then, when we navigate the page to AskQuestion.htm, that page will think that all the questions to be asked have been asked and will end the quiz rather than asking another question.
If there is still time left, the else part of the if statement executes and updates the status bar with the number of minutes and seconds left.
We need to split timeLeft, which is in seconds, into minutes and seconds. First we get the number of minutes using the following line:
var minutes = Math.floor(timeLeft / 60);
This returns just the whole number part of the seconds when divided by 60, which is the minutes we need. We get the seconds in this line
var seconds = timeLeft - (60 * minutes);
which is just timeLeft (the total seconds) minus the number of seconds represented by the minutes value. So if timeLeft is 61, then
minutes = 61 / 60 = 1.01667
which is 1 as a whole number, and
seconds = 61 – (60 * 1) = 1
We want to display this as a string in the status bar in the format minutes:seconds, which is 01:01 in this case. However, just concatenating minutes and seconds will leave us with something like 1:1 when the value of either is less than 10. Currently minutes can't go above 5, so we could just add the 0 anyway, but by using an if statement, we are future-proofing it for the situation where we allow the user a time limit over 9 minutes.
To fix this problem we add an extra zero when the values are less than 10.
if (minutes < 10) minutes = "0" + minutes; if (seconds < 10) seconds = "0" + seconds;
Finally, we change the value displayed in the window's status bar.
window.status = "Time left is " + minutes + ":" + seconds;
In the two preceding functions, we have been using some new globally defined variables we have not yet defined, so let's do that now.
var timeLeft =-1; var totalQuestionsToAsk = 0; var quizTimerId = 0;
Place these at the top of the script block.
Finally we've got just two small changes to make to the function getQuestion(), and that completes the trivia quiz for this chapter.
The first change is to the if statement at the top of the function.
if (totalQuestionsToAsk != numberOfQuestionsAsked)
{
var questionNumber = Math.floor(Math.random() * questions.length);
Previously we asked another question as long as we had not used up all the questions available. Now we ask another question as long as the totalQuestionsToAsk variable does not equal the number of questions actually asked. The global variable totalQuestionsToAsk had its value determined by the user when she selected the number of questions she wanted to answer from the drop-down list. We passed this value to the resetQuiz() function, which did the actual setting of the variable's value.
The second change is to code in the else statement when the quiz is actually ended and we write out the summary of how the user did. Remember we set a timer going that keeps track of how much time is left before the quiz must end. Well, now that the quiz has ended we need to stop that timer, which we do by using the clearInterval() method, passing the timer ID that we stored in the global variable quizTimerId, which we set when the timer was started. However, we mustn't try to stop the timer if no timer was set because the user did not select a time limit.
currentQNumber = questionNumber; questionsAsked[questionNumber] = true; } else { if (timeLeft != -1) { clearInterval(quizTimerId); } questionHTML = "<h3>Quiz Complete</h3>"; questionHTML = questionHTML + "You got " + numberOfQuestionsCorrect;
Well, that's all the changes made, so resave GlobalFunctions.htm. You can start the quiz by loading TriviaQuiz.htm into your browser.
Hopefully you should see a page like that shown in Figure 9-11.
If you choose a time limit and then click the Start Quiz button, you'll be presented with the first, randomly selected question, and the timer, which is displayed in the status bar at the bottom of the page, will start counting down.
That completes all the changes to the trivia quiz for this chapter. We'll be returning to the trivia quiz in Chapter 11 to see how we can store information on the user's computer so that we can provide a table of previous results.