Randomize questions and update buttons [HFP-56]

Show and hide navigational buttons

Add functionality to save content state

Clean up code [HFP-59]

Randomize on initialization

Tidy up [HFP-56]
pull/4/head^2
Timothy Lim 2016-10-07 15:15:42 +02:00
parent 84c8751238
commit d19a8d52fc
2 changed files with 133 additions and 3 deletions

View File

@ -77,7 +77,6 @@ H5P.QuestionSet = function (options, contentId, contentData) {
'</div>'; '</div>';
var defaults = { var defaults = {
randomOrder: false,
initialQuestion: 0, initialQuestion: 0,
progressType: 'dots', progressType: 'dots',
passPercentage: 50, passPercentage: 50,
@ -124,14 +123,17 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var currentQuestion = 0; var currentQuestion = 0;
var questionInstances = []; var questionInstances = [];
var idMap = [];
var $myDom; var $myDom;
var scoreBar; var scoreBar;
var up; var up;
var renderSolutions = false; var renderSolutions = false;
var showingSolutions = false; var showingSolutions = false;
contentData = contentData || {}; contentData = contentData || {};
var answerIndex;
if (contentData.previousState) { if (contentData.previousState) {
currentQuestion = contentData.previousState.progress; currentQuestion = contentData.previousState.progress;
answerIndex = contentData.previousState.order;
} }
var $template = $(template.render(params)); var $template = $(template.render(params));
@ -168,7 +170,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var hasAnswers = contentData.previousState && contentData.previousState.answers; var hasAnswers = contentData.previousState && contentData.previousState.answers;
var questionInstance = H5P.newRunnable(question, contentId, undefined, undefined, var questionInstance = H5P.newRunnable(question, contentId, undefined, undefined,
{ {
previousState: hasAnswers ? contentData.previousState.answers[i] : undefined, previousState: hasAnswers ? contentData.previousState.answers[answerIndex[i]] : undefined,
parent: self parent: self
}); });
questionInstance.on('resize', function () { questionInstance.on('resize', function () {
@ -178,6 +180,40 @@ H5P.QuestionSet = function (options, contentId, contentData) {
questionInstances.push(questionInstance); questionInstances.push(questionInstance);
} }
// Save the original order of questions
for (var i = 0; i < questionInstances.length; i++) {
questionInstances[i].originalOrder = i;
idMap[i] = i;
}
// Randomize questions only once
if (params.randomQuestions && contentData.previousState === undefined) {
// Randomize order of the questions
questionInstances = H5P.shuffleArray(questionInstances);
// Save new randomized order in case the question is resumed
for (var i = 0; i < questionInstances.length; i++) {
idMap[i] = questionInstances[i].originalOrder;
}
}
// Restore previous order of questions if necessary
if (contentData && contentData.previousState !== undefined
&& contentData.previousState.order !== undefined) {
var temp = [];
// Fill temporary array in the previous order
for (var i = 0; i < questionInstances.length; i++) {
temp[contentData.previousState.order[i]] = questionInstances[i];
}
// Update current arrays using the temporary array
for (var i = 0; i < questionInstances.length; i++) {
questionInstances[i] = temp[i];
idMap[i] = i;
}
}
// Resize all interactions on resize // Resize all interactions on resize
self.on('resize', function () { self.on('resize', function () {
if (up) { if (up) {
@ -356,6 +392,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
//Force the last page to be reRendered //Force the last page to be reRendered
rendered = false; rendered = false;
randomizeQuestions();
}; };
var rendered = false; var rendered = false;
@ -364,6 +402,90 @@ H5P.QuestionSet = function (options, contentId, contentData) {
rendered = false; rendered = false;
}; };
var randomizeQuestions = function () {
if (!params.randomizeQuestions) {
return false;
}
// Randomize order of the questions
questionInstances = H5P.shuffleArray(questionInstances);
// Save new randomized order in case the question is resumed
for (var i = 0; i < questionInstances.length; i++) {
idMap[i] = questionInstances[i].originalOrder;
}
// Find all question containers and detach questions from them
$('.question-container', $myDom).each(function (){
$(this).children().detach();
});
// Reattach questions and their buttons in the new order
for (var i = 0; i < questionInstances.length; i++) {
var question = questionInstances[i];
question.attach($('.question-container:eq(' + i + ')', $myDom));
// Add 'finish' button if needed
if(questionInstances[questionInstances.length -1] === question) {
if (question.hasButton('finish')) {question.showButton('finish');}
else {
// Add finish question set button
question.addButton('finish', params.texts.finishButton,
moveQuestion.bind(this, 1), false);
}
}
// Add 'next' button if needed
if(questionInstances[questionInstances.length -1] !== question) {
if (question.hasButton('next')) {question.showButton('next');}
else {
// Only show button 'next' button when answered or is allowed to go back
question.addButton('next', '', moveQuestion.bind(this, 1),
!params.disableBackwardsNavigation || !!question.getAnswerGiven(), {
href: '#', // Use href since this is a navigation button
'aria-label': params.texts.nextButton
});
}
}
// Add 'previous' button if needed
if(questionInstances[0] !== question) {
if (question.hasButton('prev')) {question.showButton('prev');}
else {
// Only show button 'previous' button when answered or is allowed to go forward
question.addButton('prev', '', moveQuestion.bind(this, -1),
!(questionInstances[0] === question || params.disableBackwardsNavigation), {
href: '#', // Use href since this is a navigation button
'aria-label': params.texts.prevButton
});
}
}
// Hide relevant buttons since the order has changed
if (questionInstances[0] === question) {
question.hideButton('prev');
}
if (questionInstances[questionInstances.length-1] === question) {
question.hideButton('next');
}
if (questionInstances[questionInstances.length-1] !== question) {
question.hideButton('finish');
}
}
}
var moveQuestion = function (direction) { var moveQuestion = function (direction) {
if (params.disableBackwardsNavigation && !questionInstances[currentQuestion].getAnswerGiven()) { if (params.disableBackwardsNavigation && !questionInstances[currentQuestion].getAnswerGiven()) {
questionInstances[currentQuestion].hideButton('next'); questionInstances[currentQuestion].hideButton('next');
@ -865,7 +987,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
progress: currentQuestion, progress: currentQuestion,
answers: questionInstances.map(function (qi) { answers: questionInstances.map(function (qi) {
return qi.getCurrentState(); return qi.getCurrentState();
}) }),
order: idMap
}; };
return state; return state;

View File

@ -201,6 +201,13 @@
"optional": true, "optional": true,
"default": false "default": false
}, },
{
"name": "randomQuestions",
"type": "boolean",
"label": "Randomize questions",
"description": "Enable to randomize the order of questions on display.",
"default": true
},
{ {
"name": "endGame", "name": "endGame",
"type": "group", "type": "group",