commit
04642e6d5f
|
@ -1,4 +1,4 @@
|
||||||
var H5P = H5P || {};
|
H5P = H5P || {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will render a Question with multiple choices for answers.
|
* Will render a Question with multiple choices for answers.
|
||||||
|
@ -126,6 +126,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
var endTemplate = new EJS({text: resulttemplate});
|
var endTemplate = new EJS({text: resulttemplate});
|
||||||
var params = $.extend(true, {}, defaults, options);
|
var params = $.extend(true, {}, defaults, options);
|
||||||
|
|
||||||
|
var initialParams = $.extend(true, {}, defaults, options);
|
||||||
var poolOrder; // Order of questions in a pool
|
var poolOrder; // Order of questions in a pool
|
||||||
var currentQuestion = 0;
|
var currentQuestion = 0;
|
||||||
var questionInstances = [];
|
var questionInstances = [];
|
||||||
|
@ -145,14 +146,12 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
questionOrder = contentData.previousState.order;
|
questionOrder = contentData.previousState.order;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a pool of questions if necessary
|
|
||||||
/**
|
/**
|
||||||
* Randomizes questions in an array and updates an array containing their order
|
* Randomizes questions in an array and updates an array containing their order
|
||||||
* @param {array} questions
|
* @param {array} questions
|
||||||
* @param {array} questionOrder
|
|
||||||
* @return {Object.<array, array>} questionOrdering
|
* @return {Object.<array, array>} questionOrdering
|
||||||
*/
|
*/
|
||||||
var randomizeQuestionOrdering = function (questions, questionOrder) {
|
var randomizeQuestionOrdering = function (questions) {
|
||||||
|
|
||||||
// Save the original order of the questions in a multidimensional array [[question0,0],[question1,1]...
|
// Save the original order of the questions in a multidimensional array [[question0,0],[question1,1]...
|
||||||
var questionOrdering = questions.map(function(questionInstance, index) { return [questionInstance, index] });
|
var questionOrdering = questions.map(function(questionInstance, index) { return [questionInstance, index] });
|
||||||
|
@ -171,7 +170,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
for (var i = 0; i< questionOrdering.length; i++) {
|
for (var i = 0; i< questionOrdering.length; i++) {
|
||||||
|
|
||||||
// Use a previous order if it exists
|
// Use a previous order if it exists
|
||||||
if(questionOrder) {
|
if(contentData.previousState && contentData.previousState.questionOrder) {
|
||||||
newOrder[i] = questionOrder[questionOrdering[i][1]];
|
newOrder[i] = questionOrder[questionOrdering[i][1]];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -179,15 +178,15 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the questions in their new order *with* their new order
|
// Return the questions in their new order *with* their new indexes
|
||||||
return {
|
return {
|
||||||
questions: questions,
|
questions: questions,
|
||||||
questionOrder: newOrder
|
questionOrder: newOrder
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
// Create a pool (a subset) of questions if necessary
|
// Create a pool (a subset) of questions if necessary
|
||||||
if (params.poolSize && params.poolSize < params.questions.length) {
|
if (params.poolSize > 0) {
|
||||||
|
|
||||||
// If a previous pool exists, recreate it
|
// If a previous pool exists, recreate it
|
||||||
if(contentData.previousState && contentData.previousState.poolOrder) {
|
if(contentData.previousState && contentData.previousState.poolOrder) {
|
||||||
|
@ -204,7 +203,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
}
|
}
|
||||||
else { // Otherwise create a new pool
|
else { // Otherwise create a new pool
|
||||||
// Randomize and get the results
|
// Randomize and get the results
|
||||||
var poolResult = randomizeQuestionOrdering(params.questions, poolOrder);
|
var poolResult = randomizeQuestionOrdering(params.questions);
|
||||||
var poolQuestions = poolResult.questions;
|
var poolQuestions = poolResult.questions;
|
||||||
poolOrder = poolResult.questionOrder;
|
poolOrder = poolResult.questionOrder;
|
||||||
|
|
||||||
|
@ -238,17 +237,26 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates question instances from H5P objects
|
||||||
|
*
|
||||||
|
* @param {object} questions H5P content types to be created as instances
|
||||||
|
* @return {array} Array of questions instances
|
||||||
|
*/
|
||||||
|
var createQuestionInstancesFromQuestions = function(questions) {
|
||||||
|
var result = [];
|
||||||
|
// Create question instances from questions
|
||||||
// Instantiate question instances
|
// Instantiate question instances
|
||||||
for (var i = 0; i < params.questions.length; i++) {
|
for (var i = 0; i < questions.length; i++) {
|
||||||
|
|
||||||
var question;
|
var question;
|
||||||
// If a previous order exists, use it
|
// If a previous order exists, use it
|
||||||
if (questionOrder !== undefined) {
|
if (questionOrder !== undefined) {
|
||||||
question = params.questions[questionOrder[i]];
|
question = questions[questionOrder[i]];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Use a generic order when initialzing for the first time
|
// Use a generic order when initialzing for the first time
|
||||||
question = params.questions[i];
|
question = questions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (override) {
|
if (override) {
|
||||||
|
@ -270,12 +278,18 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
up = true;
|
up = true;
|
||||||
self.trigger('resize');
|
self.trigger('resize');
|
||||||
});
|
});
|
||||||
questionInstances.push(questionInstance);
|
result.push(questionInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create question instances from questions given by params
|
||||||
|
questionInstances = createQuestionInstancesFromQuestions(params.questions);
|
||||||
|
|
||||||
// Randomize questions only on instantiation
|
// Randomize questions only on instantiation
|
||||||
if (params.randomQuestions && contentData.previousState === undefined) {
|
if (params.randomQuestions && contentData.previousState === undefined) {
|
||||||
var result = randomizeQuestionOrdering(questionInstances,questionOrder);
|
var result = randomizeQuestionOrdering(questionInstances);
|
||||||
questionInstances = result.questions;
|
questionInstances = result.questions;
|
||||||
questionOrder = result.questionOrder;
|
questionOrder = result.questionOrder;
|
||||||
}
|
}
|
||||||
|
@ -440,7 +454,12 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
var resetTask = function () {
|
var resetTask = function () {
|
||||||
|
|
||||||
|
// Clear previous state to ensure questions are created cleanly
|
||||||
|
contentData.previousState = [];
|
||||||
|
|
||||||
showingSolutions = false;
|
showingSolutions = false;
|
||||||
|
|
||||||
for (var i = 0; i < questionInstances.length; i++) {
|
for (var i = 0; i < questionInstances.length; i++) {
|
||||||
try {
|
try {
|
||||||
questionInstances[i].resetTask();
|
questionInstances[i].resetTask();
|
||||||
|
@ -477,7 +496,28 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
//Force the last page to be reRendered
|
//Force the last page to be reRendered
|
||||||
rendered = false;
|
rendered = false;
|
||||||
|
|
||||||
if (params.randomQuestions) {
|
if(params.poolSize > 0){
|
||||||
|
|
||||||
|
// Make new pool from params.questions
|
||||||
|
// Randomize and get the results
|
||||||
|
var poolResult = randomizeQuestionOrdering(initialParams.questions);
|
||||||
|
var poolQuestions = poolResult.questions;
|
||||||
|
poolOrder = poolResult.questionOrder;
|
||||||
|
|
||||||
|
// Discard extra questions
|
||||||
|
poolQuestions = poolQuestions.slice(0, params.poolSize);
|
||||||
|
poolOrder = poolOrder.slice(0, params.poolSize);
|
||||||
|
|
||||||
|
// Replace original questions with just the ones in the pool
|
||||||
|
params.questions = poolQuestions;
|
||||||
|
|
||||||
|
// Recreate the question instances
|
||||||
|
questionInstances = createQuestionInstancesFromQuestions(params.questions);
|
||||||
|
|
||||||
|
// Update buttons
|
||||||
|
initializeQuestion();
|
||||||
|
|
||||||
|
} else if (params.randomQuestions) {
|
||||||
randomizeQuestions();
|
randomizeQuestions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,10 +534,21 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
*/
|
*/
|
||||||
var randomizeQuestions = function () {
|
var randomizeQuestions = function () {
|
||||||
|
|
||||||
var result = randomizeQuestionOrdering(questionInstances,questionOrder);
|
var result = randomizeQuestionOrdering(questionInstances);
|
||||||
questionInstances = result.questions;
|
questionInstances = result.questions;
|
||||||
questionOrder = result.questionOrder;
|
questionOrder = result.questionOrder;
|
||||||
|
|
||||||
|
replaceQuestionsInDOM(questionInstances);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty the DOM of all questions, attach new questions and update buttons
|
||||||
|
*
|
||||||
|
* @param {type} questionInstances Array of questions to be attached to the DOM
|
||||||
|
*/
|
||||||
|
var replaceQuestionsInDOM = function (questionInstances) {
|
||||||
|
|
||||||
// Find all question containers and detach questions from them
|
// Find all question containers and detach questions from them
|
||||||
$('.question-container', $myDom).each(function (){
|
$('.question-container', $myDom).each(function (){
|
||||||
$(this).children().detach();
|
$(this).children().detach();
|
||||||
|
@ -542,10 +593,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
if (questionInstances[questionInstances.length-1] !== question) {
|
if (questionInstances[questionInstances.length-1] !== question) {
|
||||||
question.hideButton('finish');
|
question.hideButton('finish');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var moveQuestion = function (direction) {
|
var moveQuestion = function (direction) {
|
||||||
if (params.disableBackwardsNavigation && !questionInstances[currentQuestion].getAnswerGiven()) {
|
if (params.disableBackwardsNavigation && !questionInstances[currentQuestion].getAnswerGiven()) {
|
||||||
|
@ -762,51 +811,25 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
self.trigger('resize');
|
self.trigger('resize');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function for attaching the multichoice to a DOM element.
|
|
||||||
this.attach = function (target) {
|
|
||||||
if (this.isRoot()) {
|
|
||||||
this.setActivityStarted();
|
|
||||||
}
|
|
||||||
if (typeof(target) === "string") {
|
|
||||||
$myDom = $('#' + target);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$myDom = $(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render own DOM into target.
|
|
||||||
$myDom.children().remove();
|
|
||||||
$myDom.append($template);
|
|
||||||
if (params.backgroundImage !== undefined) {
|
|
||||||
$myDom.css({
|
|
||||||
overflow: 'hidden',
|
|
||||||
background: '#fff url("' + H5P.getPath(params.backgroundImage.path, contentId) + '") no-repeat 50% 50%',
|
|
||||||
backgroundSize: '100% auto'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.introPage.backgroundImage !== undefined) {
|
|
||||||
var $intro = $myDom.find('.intro-page');
|
|
||||||
if ($intro.length) {
|
|
||||||
var bgImg = params.introPage.backgroundImage;
|
|
||||||
var bgImgRatio = (bgImg.height / bgImg.width);
|
|
||||||
$intro.css({
|
|
||||||
background: '#fff url("' + H5P.getPath(bgImg.path, contentId) + '") no-repeat 50% 50%',
|
|
||||||
backgroundSize: 'auto 100%',
|
|
||||||
minHeight: bgImgRatio * +window.getComputedStyle($intro[0]).width.replace('px','')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var registerImageLoadedListener = function (question) {
|
var registerImageLoadedListener = function (question) {
|
||||||
H5P.on(question, 'imageLoaded', function () {
|
H5P.on(question, 'imageLoaded', function () {
|
||||||
self.trigger('resize');
|
self.trigger('resize');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a question and attach it to the DOM
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function initializeQuestion() {
|
||||||
// Attach questions
|
// Attach questions
|
||||||
for (var i = 0; i < questionInstances.length; i++) {
|
for (var i = 0; i < questionInstances.length; i++) {
|
||||||
var question = questionInstances[i];
|
var question = questionInstances[i];
|
||||||
|
|
||||||
|
// Make sure styles are not being added twice
|
||||||
|
$('.question-container:eq(' + i + ')', $myDom).attr('class', 'question-container');
|
||||||
|
|
||||||
question.attach($('.question-container:eq(' + i + ')', $myDom));
|
question.attach($('.question-container:eq(' + i + ')', $myDom));
|
||||||
|
|
||||||
// Listen for image resize
|
// Listen for image resize
|
||||||
|
@ -857,6 +880,44 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
// Mark question if answered
|
// Mark question if answered
|
||||||
toggleAnsweredDot(i, question.getAnswerGiven());
|
toggleAnsweredDot(i, question.getAnswerGiven());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attach = function (target) {
|
||||||
|
if (this.isRoot()) {
|
||||||
|
this.setActivityStarted();
|
||||||
|
}
|
||||||
|
if (typeof(target) === "string") {
|
||||||
|
$myDom = $('#' + target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$myDom = $(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render own DOM into target.
|
||||||
|
$myDom.children().remove();
|
||||||
|
$myDom.append($template);
|
||||||
|
if (params.backgroundImage !== undefined) {
|
||||||
|
$myDom.css({
|
||||||
|
overflow: 'hidden',
|
||||||
|
background: '#fff url("' + H5P.getPath(params.backgroundImage.path, contentId) + '") no-repeat 50% 50%',
|
||||||
|
backgroundSize: '100% auto'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.introPage.backgroundImage !== undefined) {
|
||||||
|
var $intro = $myDom.find('.intro-page');
|
||||||
|
if ($intro.length) {
|
||||||
|
var bgImg = params.introPage.backgroundImage;
|
||||||
|
var bgImgRatio = (bgImg.height / bgImg.width);
|
||||||
|
$intro.css({
|
||||||
|
background: '#fff url("' + H5P.getPath(bgImg.path, contentId) + '") no-repeat 50% 50%',
|
||||||
|
backgroundSize: 'auto 100%',
|
||||||
|
minHeight: bgImgRatio * +window.getComputedStyle($intro[0]).width.replace('px','')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeQuestion();
|
||||||
|
|
||||||
// Allow other libraries to add transitions after the questions have been inited
|
// Allow other libraries to add transitions after the questions have been inited
|
||||||
$('.questionset', $myDom).addClass('started');
|
$('.questionset', $myDom).addClass('started');
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"contentType": "question",
|
"contentType": "question",
|
||||||
"majorVersion": 1,
|
"majorVersion": 1,
|
||||||
"minorVersion": 10,
|
"minorVersion": 10,
|
||||||
"patchVersion": 0,
|
"patchVersion": 1,
|
||||||
"embedTypes": [
|
"embedTypes": [
|
||||||
"iframe"
|
"iframe"
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue