function Quiz() { this.AddQuestion = Quiz_AddQuestion; this.RandomizeQuestions = Quiz_RandomizeQuestions; this.HasAllGuesses = Quiz_HasAllGuesses; this.Evaluate = Quiz_EvaluateQuestions; this.Render = Quiz_Render; this.AddScore = Quiz_AddScore; this.GetPossiblePoints = Quiz_GetPossiblePoints; this.GetAwardedPoints = Quiz_GetAwardedPoints; this.GetPercentage = Quiz_GetPercentage; this.SetQuestionNumberStyle = Quiz_SetQuestionNumberStyle; this.SetQuestionNumberCssClass = Quiz_SetQuestionNumberCssClass; this.SetRequireAllGuesses = Quiz_SetRequireAllGuesses; this.SetNeedAllGuessesHTML = Quiz_SetNeedAllGuessesHTML; this.SetNeedAllGuessesCssClass = Quiz_SetNeedAllGuessesCssClass; this.SetScoreByPercentage = Quiz_SetScoreByPercentage; this.SetScoreCssClass = Quiz_SetScoreCssClass; // internal use this._questions = new Array(); this._scores = new Array(); this._nPossiblePoints = 0; this._rAwardedPoints = 0; this._nAwardedPercentage = 0; this._sQuestionNumberStyle = "1"; this._sQuestionNumberCssClass = ""; this._bRequireAllGuesses = false; this._sNeedAllGuessesHTML = ""; this._sNeedAllGuessesCssClass = ""; this._bByPercentage = false; this._sScoreCssClass = ""; } function Quiz_AddQuestion(oQuestion) { this._questions.push(oQuestion); } function Quiz_RandomizeQuestions() { var aRandom = Quiz_GetRandomArray(this._questions.length); for (var n = 0; n < aRandom.length; n++) this._questions[n]._nNumber = aRandom[n]; } function Quiz_GetRandomArray(nLength) { var n; var aUnusedNumbers = new Array(); for (n = 0; n < nLength; n++) aUnusedNumbers[n] = n + 1; var aSelectedNumbers = new Array(); while (aSelectedNumbers.length < nLength) { var bNumberUsedAlready; do { n = Math.floor(Math.random() * nLength); bNumberUsedAlready = (aUnusedNumbers[n] == 0); } while (bNumberUsedAlready) aSelectedNumbers.push(aUnusedNumbers[n]); aUnusedNumbers[n] = 0; } return aSelectedNumbers; } function Quiz_HasAllGuesses() { var cHasGuesses = 0; for (var nQuestion = 0; nQuestion < this._questions.length; nQuestion++) cHasGuesses += this._questions[nQuestion].HasGuess() ? 1 : 0; return (cHasGuesses == this._questions.length); } function Quiz_EvaluateQuestions() { Quiz_ConcealAllEvaluations(this); if (this._bRequireAllGuesses) { var elmNeedAllGuesses = document.getElementById("_quiz_divNeedAllGuesses"); if (! this.HasAllGuesses()) { elmNeedAllGuesses.style.display = "block"; return false; } else elmNeedAllGuesses.style.display = "none"; } this.GetPossiblePoints(); this._rAwardedPoints = 0; for (var nQuestion = 0; nQuestion < this._questions.length; nQuestion++) { var oQuestion = this._questions[nQuestion]; oQuestion.Evaluate(); this._rAwardedPoints += oQuestion.GetAwardedPoints(); Quiz_RevealEvaluation(oQuestion); } this._nAwardedPercentage = Math.floor((this._rAwardedPoints * 100) / this._nPossiblePoints); var oAwardedScore = null; for (var nScore = 0; nScore < this._scores.length; nScore++) { var oScore = this._scores[nScore]; if (this._bByPercentage) { if ((this._nAwardedPercentage >= oScore._rMinScore) && ((oAwardedScore == null) || (oScore._rMinScore > oAwardedScore._rMinScore))) oAwardedScore = oScore; } else { if ((this._rAwardedPoints >= oScore._rMinScore) && ((oAwardedScore == null) || (oScore._rMinScore > oAwardedScore._rMinScore))) oAwardedScore = oScore; } } if (oAwardedScore != null) { var elmScore = document.getElementById("_quiz_divScorebox"); if (oAwardedScore._sScoreCssClass.length > 0) elmScore.className = oAwardedScore._sScoreCssClass; elmScore.innerHTML = oAwardedScore._sScoreHTML; elmScore.style.display = "block"; } return true; } function Quiz_ConcealAllEvaluations(oQuiz) { var elmScore = document.getElementById("_quiz_divScorebox"); elmScore.style.display = "none"; for (var nQuestion = 0; nQuestion < oQuiz._questions.length; nQuestion++) { var oQuestion = oQuiz._questions[nQuestion]; var sQuestionID = "_quiz_Question_" + oQuestion._nNumber.toString(); var elmQuestionEvalCorrect = document.getElementById(sQuestionID + "_Correct"); var elmQuestionEvalIncorrect = document.getElementById(sQuestionID + "_Incorrect"); if (elmQuestionEvalCorrect != null) elmQuestionEvalCorrect.style.display = "none"; if (elmQuestionEvalIncorrect != null) elmQuestionEvalIncorrect.style.display = "none"; } } function Quiz_RevealEvaluation(oQuestion) { var sQuestionID = "_quiz_Question_" + oQuestion._nNumber.toString(); var elmQuestionEvalCorrect = document.getElementById(sQuestionID + "_Correct"); var elmQuestionEvalIncorrect = document.getElementById(sQuestionID + "_Incorrect"); if (oQuestion.GetAwardedPoints() > 0) { if (oQuestion._sQuestionType == "MS" && !oQuestion._bAllOrNothing) { if (oQuestion._bAnsweredAll) { elmQuestionEvalCorrect.style.display = "block"; elmQuestionEvalIncorrect.style.display = "none"; } else { elmQuestionEvalCorrect.style.display = "none"; elmQuestionEvalIncorrect.style.display = "block"; } } else { elmQuestionEvalCorrect.style.display = "block"; elmQuestionEvalIncorrect.style.display = "none"; } } if (oQuestion.GetAwardedPoints() == 0) { elmQuestionEvalCorrect.style.display = "none"; elmQuestionEvalIncorrect.style.display = "block"; } } function Quiz_Render() { Quiz_RenderQuestions(this); Quiz_RenderNeedAllGuesses(this); Quiz_RenderScoreBox(this); } function Quiz_RenderQuestions(oQuiz) { var aSortedQuestions = new Array(); for (var nQuestion = 0; nQuestion < oQuiz._questions.length; nQuestion++) { var oQuestion = oQuiz._questions[nQuestion]; if (oQuestion._nNumber == 0) oQuestion._nNumber = nQuestion + 1; else if(oQuestion._nNumber > oQuiz._questions.length) throw "You must renumber your questions from 1 to the number of questions you have."; else if(aSortedQuestions[oQuestion._nNumber - 1] != null) throw "You have already used the number " + oQuestion._nNumber + " in a question."; aSortedQuestions[oQuestion._nNumber - 1] = oQuestion; } for (var nQuestion = 0; nQuestion < aSortedQuestions.length; nQuestion++) Quiz_RenderQuestion(oQuiz, aSortedQuestions[nQuestion]); } function Quiz_RenderQuestion(oQuiz, oQuestion) { document.write(" 0) document.write(" class=\"" + oQuestion._sQuestionCssClass + "\""); document.write(">"); var sNumber = Quiz_GetFormattedNumber(oQuestion._nNumber, oQuiz._sQuestionNumberStyle); document.write(" 0) document.write(" class=\"" + oQuiz._sQuestionNumberCssClass + "\""); document.write(">"); document.write(sNumber); document.write(""); document.write(""); document.write(oQuestion._sQuestionHTML); document.write(""); Quiz_RenderAnswers(oQuiz, oQuestion); document.write(""); Quiz_RenderEvaluation(oQuiz, oQuestion); } function Quiz_RenderAnswers(oQuiz, oQuestion) { var aSortedAnswers = new Array(); for (var nAnswer = 0; nAnswer < oQuestion._answers.length; nAnswer++) { var oAnswer = oQuestion._answers[nAnswer]; if (oAnswer._nNumber == 0) oAnswer._nNumber = nAnswer + 1; else if(oAnswer._nNumber > oQuestion._answers.length) throw "You must renumber your answers from 1 to the number of answers you have in question '" + oQuestion._nNumber + "."; else if(aSortedAnswers[oAnswer._nNumber - 1] != null) { throw "You have already used the number " + oAnswer._nNumber + " in an answer."; } aSortedAnswers[oAnswer._nNumber - 1] = oAnswer; } for (var nAnswer = 0; nAnswer < aSortedAnswers.length; nAnswer++) Quiz_RenderAnswer(oQuiz, oQuestion, aSortedAnswers[nAnswer]); } function Quiz_RenderAnswer(oQuiz, oQuestion, oAnswer) { document.write(" 0) document.write(" class=\"" + oAnswer._sAnswerCssClass + "\""); document.write(">"); var sNumber = Quiz_GetFormattedNumber(oAnswer._nNumber, oQuestion._sAnswerNumberStyle); document.write(" 0) document.write(" class=\"" + oQuestion._sAnswerNumberCssClass + "\""); document.write(">"); document.write(sNumber); document.write(""); document.write(""); var sName = "_quiz_Question_" + oQuestion._nNumber; var sID = sName + "_Answer_" + oAnswer._nNumber; if (oQuestion._sQuestionType == "TF" || oQuestion._sQuestionType == "MC" || oQuestion._sQuestionType == "none") { document.write(""); document.write(" "); document.write(""); document.write(oAnswer._sAnswerHTML); document.write(""); } else if(oQuestion._sQuestionType == "MS") { document.write(""); document.write(" "); document.write(""); document.write(oAnswer._sAnswerHTML); document.write(""); } document.write(""); document.write(""); } function Quiz_RenderEvaluation(oQuiz, oQuestion) { document.write(" 0) document.write(" class=\"" + oQuestion._sCorrectCssClass + "\""); document.write(" style=\"display:none;\""); document.write(">"); document.write(oQuestion._sCorrectHTML); document.write(""); document.write(" 0) document.write(" class=\"" + oQuestion._sIncorrectCssClass + "\""); document.write(" style=\"display:none;\""); document.write(">"); document.write(oQuestion._sIncorrectHTML); document.write(""); } function Quiz_RenderNeedAllGuesses(oQuiz) { document.write(" 0) document.write(" class=\"" + oQuiz._sNeedAllGuessesCssClass + "\""); document.write(" style=\"display:none;\""); document.write(">"); document.write(oQuiz._sNeedAllGuessesHTML); document.write(""); } function Quiz_RenderScoreBox(oQuiz) { document.write(" 0) document.write(" class=\"" + oQuiz._sScoreCssClass + "\""); document.write(" style=\"display:none;\""); document.write(">"); document.write(""); } function Quiz_GetFormattedNumber(nNumber, sStyle) { if ("1" == sStyle) return nNumber.toString() + ":"; else if("A" == sStyle) { var sA = "A"; var cRepeats = Math.floor((nNumber - 1) / 26) + 1; var sChar = String.fromCharCode(sA.charCodeAt(0) + (nNumber - 1)); var sNumber = ""; while (cRepeats-- > 0) sNumber = sNumber + sChar; return sNumber + ":"; } else if("a" == sStyle) { var sA = "a"; var cRepeats = Math.floor((nNumber - 1) / 26) + 1; var sChar = String.fromCharCode(sA.charCodeAt(0) + (nNumber - 1)); var sNumber = ""; while (cRepeats-- > 0) sNumber = sNumber + sChar; return sNumber + ":"; } else if("." == sStyle) return "•"; else if("" == sStyle) return ""; else return ""; } function Quiz_AddScore(oScore) { this._scores.push(oScore); } function Quiz_GetPossiblePoints() { var oQuestion = null; var aQuestions = this._questions; if (this._nPossiblePoints == 0) for (var nQuestion = 0; nQuestion < this._questions.length; nQuestion++) { var oQuestion = this._questions[nQuestion]; this._nPossiblePoints += oQuestion.GetPossiblePoints(); } return this._nPossiblePoints; } function Quiz_GetAwardedPoints() { return this._rAwardedPoints; } function Quiz_GetPercentage() { return this._nAwardedPercentage; } function Quiz_SetQuestionNumberStyle(sStyle) { this._sQuestionNumberStyle = sStyle; } function Quiz_SetQuestionNumberCssClass(sCssClass) { this._sQuestionNumberCssClass = sCssClass; } function Quiz_SetRequireAllGuesses(bRequireAll) { this._bRequireAllGuesses = bRequireAll; } function Quiz_SetNeedAllGuessesHTML(sHTML) { this._sNeedAllGuessesHTML = sHTML; } function Quiz_SetNeedAllGuessesCssClass(sCssClass) { this._sNeedAllGuessesCssClass = sCssClass; } function Quiz_SetScoreByPercentage(bByPercentage) { this._bByPercentage = bByPercentage; } function Question() { this.AddAnswer = Quiz_AddAnswer; this.RandomizeAnswers = Quiz_RandomizeAnswers; this.Evaluate = Quiz_EvaluateAnswers; this.HasGuess = Quiz_HasGuess; this.GetPossiblePoints = Quiz_GetQuestionPossiblePoints; this.GetAwardedPoints = Quiz_GetQuestionAwardedPoints; this.SetPossiblePoints = Quiz_SetQuestionPossiblePoints; this.SetQuestionHTML = Quiz_SetQuestionHTML; this.SetQuestionCssClass = Quiz_SetQuestionCssClass; this.SetCorrectGuessHTML = Quiz_SetCorrectGuessHTML; this.SetCorrectGuessCssClass = Quiz_SetCorrectGuessCssClass; this.SetIncorrectGuessHTML = Quiz_SetIncorrectGuessHTML; this.SetIncorrectGuessCssClass = Quiz_SetIncorrectGuessCssClass; this.SetQuestionType = Quiz_SetQuestionType; this.SetQuestionNumber = Quiz_SetQuestionNumber; this.SetRequireAllOrNothing = Quiz_SetAllOrNothing; this.SetAnswerNumberStyle = Quiz_SetAnswerNumberStyle; this.SetAnswerNumberCssClass = Quiz_SetAnswerNumberCssClass; //internal use this._answers = new Array(); this._sQuestionHTML = ""; this._sQuestionCssClass = ""; this._sCorrectHTML = ""; this._sCorrectCssClass = ""; this._sIncorrectHTML = ""; this._sIncorrectCssClass = ""; this._sQuestionType = "none"; this._nNumber = 0; this._nPossiblePoints = 0; this._rAwardedPoints = 0; this,_bAnsweredAll = false; this._bAllOrNothing = false; this._sAnswerNumberStyle = "A"; this._sAnswerNumberCssClass = ""; } function Quiz_AddAnswer(oAnswer) { if (this._sQuestionType == "TF" && this._answers.length > 2) throw "True/False questions may have only two possible answers." this._answers.push(oAnswer); } function Quiz_RandomizeAnswers() { var aRandom = Quiz_GetRandomArray(this._answers.length); for (var n = 0; n < aRandom.length; n++) this._answers[n]._nNumber = aRandom[n]; } function Quiz_EvaluateAnswers() { this._rAwardedPoints = 0; var sQuestionID = "_quiz_Question_" + this._nNumber.toString(); var sAnswerIDPrefix = sQuestionID + "_Answer_"; var elmAnswer = null; if (this._sQuestionType != "MS") // use for TF and MC questions { for (var nAnswer = 0; nAnswer < this._answers.length; nAnswer++) { var oAnswer = this._answers[nAnswer]; if (oAnswer._bCorrect == true) { elmAnswer = document.getElementById(sAnswerIDPrefix + oAnswer._nNumber.toString()); break; } } if (elmAnswer != null) { if (elmAnswer.checked == true) this._rAwardedPoints = this._nPossiblePoints; } else { throw "No answers were identified as correct for question " + sQuestionID + " when the quiz was created."; } } else // MS question { var nCorrectAnswersChecked = 0; var nCorrectAnswersUnchecked = 0; var nPossibleCorrectAnswers = 0; var nIncorrectAnswersChecked = 0; var nPossiblePoints = 0; var nPointsAccumulated = 0 for (var nAnswer = 0; nAnswer < this._answers.length; nAnswer++) { var oAnswer = this._answers[nAnswer]; elmAnswer = document.getElementById(sAnswerIDPrefix + oAnswer._nNumber.toString()); if (oAnswer._bCorrect == true) { nPossiblePoints += oAnswer._nPoints; nPossibleCorrectAnswers++; if (elmAnswer.checked == true) { nCorrectAnswersChecked++; nPointsAccumulated += oAnswer._nPoints; } else nCorrectAnswersUnchecked++; } else { if (elmAnswer.checked == true) nIncorrectAnswersChecked++ } } if (nPossibleCorrectAnswers == 0) throw "No answers were identified as correct for question " + sQuestionID + " when the quiz was created."; if (nPossiblePoints == 0) nPossiblePoints = 1; if (this._nPossiblePoints == 0) this._nPossiblePoints = nPossiblePoints; if (nIncorrectAnswersChecked > 0) this._rAwardedPoints = 0; else { if (this._bAllOrNothing == true) { if (nCorrectAnswersChecked == nPossibleCorrectAnswers) this._rAwardedPoints = this._nPossiblePoints; else this._rAwardedPoints = 0; this._bAnsweredAll = (this._rAwardedPoints > 0); } else { this._bAnsweredAll = (nCorrectAnswersUnchecked == 0); this._rAwardedPoints = (nPointsAccumulated / nPossiblePoints) * this._nPossiblePoints; } } } } function Quiz_HasGuess() { var bHasGuess = false; var sQuestionID = "_quiz_Question_" + this._nNumber.toString(); var sAnswerIDPrefix = sQuestionID + "_Answer_"; for (var nAnswer = 0; nAnswer < this._answers.length; nAnswer++) { var sAnswerID = sAnswerIDPrefix + (nAnswer + 1).toString(); var elmAnswerInput = document.getElementById(sAnswerID); if (elmAnswerInput != null) { if (elmAnswerInput.checked == true) { bHasGuess = true; break; } } } return bHasGuess; } function Quiz_SetQuestionHTML(sHTML) { this._sQuestionHTML = sHTML; } function Quiz_SetQuestionCssClass(sCssClass) { this._sQuestionCssClass = sCssClass; } function Quiz_SetCorrectGuessHTML(sHTML) { this._sCorrectHTML = sHTML; } function Quiz_SetCorrectGuessCssClass(sCssClass) { this._sCorrectCssClass = sCssClass; } function Quiz_SetIncorrectGuessHTML(sHTML) { this._sIncorrectHTML = sHTML; } function Quiz_SetIncorrectGuessCssClass(sCssClass) { this._sIncorrectCssClass = sCssClass; } function Quiz_SetQuestionType(sType) { var sT = sType.toUpperCase(); if (sT == "TF" || sT == "MC" || sT == "MS") if (sT == "TF" && this._answers.length > 2) throw "True/False questions may have only two possible answers." else this._sQuestionType = sType; else throw "Question type not supported" } function Quiz_SetQuestionNumber(nNumber) { this._nNumber = nNumber; } function Quiz_SetQuestionPossiblePoints(nPoints) { this._nPossiblePoints = nPoints; } function Quiz_GetQuestionPossiblePoints() { if (this._nPossiblePoints == 0) { for (var nAnswer = 0; nAnswer < this._answers.length; nAnswer++) { var oAnswer = this._answers[nAnswer]; if (oAnswer._bCorrect == true) { // for Multiple Selection questions: // add all possible correct answers to get the possible points // for all other question types // get the points of the correct answer with the most points (even though there should only be one correct answer) this._nPossiblePoints = (this._sQuestionType == "MS" ? this._nPossiblePoints + oAnswer._nPoints : Math.max(this._nPossiblePoints, oAnswer._nPoints)); } } } return this._nPossiblePoints; } function Quiz_GetQuestionAwardedPoints() { return this._rAwardedPoints; } function Quiz_SetAllOrNothing(bAllOrNothing) { this._bAllOrNothing = bAllOrNothing; } function Quiz_SetAnswerNumberStyle(sStyle) { this._sAnswerNumberStyle = sStyle; } function Quiz_SetAnswerNumberCssClass(sCssClass) { this._sAnswerNumberCssClass = sCssClass; } function Answer() { this.SetAnswerHTML = Quiz_SetAnswerHTML; this.SetAnswerCssClass = Quiz_SetAnswerCssClass; this.SetPointsForCorrectGuess = Quiz_SetPointsForCorrectGuess; this.SetAnswerNumber = Quiz_SetAnswerNumber; this.SetCorrect = Quiz_SetCorrect; //internal use this._SAnswerHTML = ""; this._sAnswerCssClass = ""; this._nPoints = 1; this._nNumber = 0; this._bCorrect = false; } function Quiz_SetAnswerHTML(sHTML) { this._sAnswerHTML = sHTML; } function Quiz_SetAnswerCssClass(sCssClass) { this._sAnswerCssClass = sCssClass; } function Quiz_SetPointsForCorrectGuess(nPoints) { this._nPoints = nPoints; } function Quiz_SetAnswerNumber(nNumber) { this._nNumber = nNumber; } function Quiz_SetCorrect(bCorrect) { this._bCorrect = bCorrect; } function Score() { this.SetScoreHTML = Quiz_SetScoreHTML; this.SetScoreCssClass = Quiz_SetScoreCssClass; this.SetMinScore = Quiz_SetMinScore; //internal use this._sScoreHTML = ""; this._sScoreCssClass = ""; this._rMinScore = 0; } function Quiz_SetScoreHTML(sHTML) { this._sScoreHTML = sHTML; } function Quiz_SetScoreCssClass(sCssClass) { this._sScoreCssClass = sCssClass; } function Quiz_SetMinScore(rPercentageOrPoints) { this._rMinScore = rPercentageOrPoints; }