// Will render a Question with multiple choices for answers. // Options format: // { // title: "Optional title for question box", // question: "Question text", // answers: [{text: "Answer text", correct: false}, ...], // singleAnswer: true, // or false, will change rendered output slightly. // } // // Events provided: // - h5pQuestionSetFinished: Triggered when a question is finished. (User presses Finish-button) window.H5P = window.H5P || {}; H5P.QuestionSet = function (options) { if ( !(this instanceof H5P.QuestionSet) ) return new H5P.QuestionSet(options); var $ = H5P.jQuery; var texttemplate = '' + '' + '
' + '
<%= title %>
' + ' <% for (var i=0; i' + '
' + '
<%= questions[i].machineName %>
' + '
' + ' <% } %>' + ' ' + '
' + ''; var resulttemplate = '' + '
' + '
<%= greeting %>
' + '
<%= score %>
' + '
<%= resulttext %>
' + '
' + '
' + ''; var that = this; var defaults = { title: "", randomOrder: false, initialQuestion: 0, backgroundImage: "", progressType: 'dots', passPercentage: 50, questions: [], introPage: { showIntroPage: true, title: "Welcome", introduction: "Click start to start.", startButtonText: "Start" }, texts: { prevButton: "Previous", nextButton: "Next", finishButton: "Finish", textualProgress: "Question: @current of @total questions" }, endGame: { showResultPage: true, resultPage: { succesGreeting: "Congratulations!", successComment: "You have enough correct answers to pass the test.", failGreeting: "Sorry!", failComment: "You don't have enough correct answers to pass this test.", scoreString: "@score/@total", finishButtonText: "Finish" }, animations: { showAnimations: false, succesResultAnimation: { machineName: "H5P.Image", options: {image: ""} }, failedResultAnimation: { machineName: "H5P.Image", options: {image: ""} } } } }; var template = new EJS({text: texttemplate}); var endTemplate = new EJS({text: resulttemplate}); var params = $.extend({}, defaults, options); var currentQuestion = 0; var questionInstances = new Array(); var allQuestionsAnswered = false; var $myDom; if (params.randomOrder) { // TODO: Randomize order of questions console.log("TODO: Randomize order of questions"); } // Instantiate question instances for (var i=0; i= 0; i--) { answered = answered && (questionInstances[i]).getAnswerGiven(); } $('.finish.button', $myDom).attr({'disabled': !answered}); }; var _showQuestion = function (questionNumber) { // Sanitize input. if (questionNumber < 0) { questionNumber = 0; } if (questionNumber >= params.questions.length) { questionNumber = params.questions.length - 1; } $('.prev.button', $myDom).attr({'disabled': (questionNumber === 0)}); $('.next.button', $myDom).attr({'disabled': (questionNumber == params.questions.length-1)}); // Hide all questions $('.question-container', $myDom).hide(); // Reshow the requested question $('#q-' + questionNumber, $myDom).show(); // Update progress indicator // Test if current has been answered. if (params.progressType == 'textual') { $('.progress-text', $myDom).text(params.texts.textualProgress.replace("@current", questionNumber+1).replace("@total", params.questions.length)); } else { // Set currentNess $('.progress-dot.current', $myDom).removeClass('current'); $('#qdot-' + questionNumber, $myDom).addClass('current'); } // Remember where we are currentQuestion = questionNumber; return currentQuestion; }; // Function for attaching the multichoice to a DOM element. var attach = function (targetId) { // Render own DOM into target. template.update(targetId, params); $myDom = $('#' + targetId); $myDom.css({backgroundImage: 'url(' + params.backgroundImage + ')'}); // Attach questions for (var i=0; i= params.passPercentage); var eventData = { score: scoreString, passed: success }; // Display result page. if (params.endGame.showResultPage) { // Render result page into. var eparams = { greeting: (success ? params.endGame.resultPage.succesGreeting : params.endGame.resultPage.failGreeting), score: scoreString, scoreclass: (success ? 'success' : 'fail'), resulttext: (success ? params.endGame.resultPage.successComment : params.endGame.resultPage.failComment), finishButtonText: params.endGame.resultPage.finishButtonText }; endTemplate.update(targetId, eparams); $('.qs-finishbutton').click(function (ev) { // Display animation if present. if (params.endGame.animations.showAnimations) { // Init anims. console.log("Now we should have started some anims..."); // On animation finished: $(returnObject).trigger('h5pQuestionSetFinished', eventData); } else { // Trigger finished event. $(returnObject).trigger('h5pQuestionSetFinished', eventData); } }); } else { $(returnObject).trigger('h5pQuestionSetFinished', eventData); } }); // Hide all but initial Question. _showQuestion(params.initialQuestion); _updateFinishButton(); return this; }; // Get current score for questionset. var getScore = function () { var score = 0; for (var i = questionInstances.length - 1; i >= 0; i--) { score += questionInstances[i].getScore(); } return score; }; // Get total score possible for questionset. var totalScore = function () { return questionInstances.length; // FIXME: questions need to get totalScore function. var score = 0; for (var i = questionInstances.length - 1; i >= 0; i--) { score += questionInstances[i].totalScore(); } return score; }; // Masquerade the main object to hide inner properties and functions. var returnObject = { attach: attach, // Attach to DOM object getQuestions: function () {return questionInstances;}, getScore: getScore, totalScore: totalScore, defaults: defaults // Provide defaults for inspection }; return returnObject; };