Merge branch 'master' of github.com:h5p/h5p-question-set

pull/7/head
Pål Jørgensen 2016-10-06 21:47:54 +02:00
commit f7c772b212
2 changed files with 100 additions and 26 deletions

View File

@ -52,7 +52,12 @@
background: #fff; background: #fff;
background: #cecece; background: #cecece;
} }
.progress-dot:hover {
.progress-dot.disabled {
cursor: default;
}
.progress-dot:not(.disabled):hover {
box-shadow: 0 0 0.5em #c7c7c7; box-shadow: 0 0 0.5em #c7c7c7;
} }
.progress-dot.answered { .progress-dot.answered {
@ -61,6 +66,11 @@
.progress-dot.current { .progress-dot.current {
background: #285585; background: #285585;
} }
.progress-dot.disabled:focus {
outline: none
}
.progress-dot:focus { .progress-dot:focus {
outline-color: rgb(40, 130, 211); outline-color: rgb(40, 130, 211);
outline-width: thin; outline-width: thin;

View File

@ -39,14 +39,19 @@ H5P.QuestionSet = function (options, contentId, contentData) {
' <% } %>' + ' <% } %>' +
' <div class="qs-footer">' + ' <div class="qs-footer">' +
' <div class="qs-progress">' + ' <div class="qs-progress">' +
' <% if (progressType == "dots" && !disableBackwardsNavigation) { %>' + ' <% if (progressType == "dots") { %>' +
' <ul class="dots-container" role="navigation">' + ' <ul class="dots-container" role="navigation">' +
' <% for (var i=0; i<questions.length; i++) { %>' + ' <% for (var i=0; i<questions.length; i++) { %>' +
' <li class="progress-item"><a href="#" class="progress-dot unanswered" ' + ' <li class="progress-item">' +
' aria-label="<%=' + ' <a href="#" ' +
' texts.jumpToQuestion.replace("%d", i + 1).replace("%total", questions.length)' + ' class="progress-dot unanswered<%' +
' + ", " + texts.unansweredText' + ' if (disableBackwardsNavigation) { %> disabled <% } %>"' +
' %>" tabindex="-1"></a></li>' + ' aria-label="<%=' +
' texts.jumpToQuestion.replace("%d", i + 1).replace("%total", questions.length)' +
' + ", " + texts.unansweredText %>" tabindex="-1" ' +
' <% if (disableBackwardsNavigation) { %> aria-disabled="true" <% } %>' +
' ></a>' +
' </li>' +
' <% } %>' + ' <% } %>' +
' </div>' + ' </div>' +
' <% } else if (progressType == "textual") { %>' + ' <% } else if (progressType == "textual") { %>' +
@ -128,8 +133,9 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var scoreBar; var scoreBar;
var up; var up;
var renderSolutions = false; var renderSolutions = false;
var showingSolutions = false;
contentData = contentData || {}; contentData = contentData || {};
if (contentData.previousState) { if (contentData.previousState && contentData.previousState.progress) {
currentQuestion = contentData.previousState.progress; currentQuestion = contentData.previousState.progress;
} }
@ -164,9 +170,10 @@ H5P.QuestionSet = function (options, contentId, contentData) {
question.params.overrideSettings = question.params.overrideSettings || {}; question.params.overrideSettings = question.params.overrideSettings || {};
question.params.overrideSettings.$confirmationDialogParent = $template.last(); question.params.overrideSettings.$confirmationDialogParent = $template.last();
question.params.overrideSettings.instance = this; question.params.overrideSettings.instance = this;
var hasAnswers = contentData.previousState && contentData.previousState.answers;
var questionInstance = H5P.newRunnable(question, contentId, undefined, undefined, var questionInstance = H5P.newRunnable(question, contentId, undefined, undefined,
{ {
previousState: contentData.previousState ? contentData.previousState.answers[i] : undefined, previousState: hasAnswers ? contentData.previousState.answers[i] : undefined,
parent: self parent: self
}); });
questionInstance.on('resize', function () { questionInstance.on('resize', function () {
@ -191,6 +198,16 @@ H5P.QuestionSet = function (options, contentId, contentData) {
// Update button state. // Update button state.
var _updateButtons = function () { var _updateButtons = function () {
// Verify that current question is answered when backward nav is disabled
if (params.disableBackwardsNavigation) {
if (questionInstances[currentQuestion].getAnswerGiven()) {
questionInstances[currentQuestion].showButton('next');
}
else {
questionInstances[currentQuestion].hideButton('next');
}
}
var answered = true; var answered = true;
for (var i = questionInstances.length - 1; i >= 0; i--) { for (var i = questionInstances.length - 1; i >= 0; i--) {
answered = answered && (questionInstances[i]).getAnswerGiven(); answered = answered && (questionInstances[i]).getAnswerGiven();
@ -280,7 +297,18 @@ H5P.QuestionSet = function (options, contentId, contentData) {
* @public * @public
*/ */
var showSolutions = function () { var showSolutions = function () {
showingSolutions = true;
for (var i = 0; i < questionInstances.length; i++) { for (var i = 0; i < questionInstances.length; i++) {
// Enable back and forth navigation in solution mode
toggleDotsNavigation(true);
if (i < questionInstances.length - 1) {
questionInstances[i].showButton('next');
}
if (i > 0) {
questionInstances[i].showButton('prev');
}
try { try {
// Do not read answers // Do not read answers
questionInstances[i].toggleReadSpeaker(true); questionInstances[i].toggleReadSpeaker(true);
@ -294,15 +322,45 @@ H5P.QuestionSet = function (options, contentId, contentData) {
} }
}; };
/**
* Toggles whether dots are enabled for navigation
*/
var toggleDotsNavigation = function (enable) {
$('.progress-dot', $myDom).each(function () {
$(this).toggleClass('disabled', !enable);
$(this).attr('aria-disabled', enable ? 'false' : 'true');
// Remove tabindex
if (!enable) {
$(this).attr('tabindex', '-1');
}
});
};
/** /**
* Resets the task and every subcontent task. * Resets the task and every subcontent task.
* Used for contracts with integrated content. * Used for contracts with integrated content.
* @public * @public
*/ */
var resetTask = function () { var resetTask = function () {
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();
// Hide back and forth navigation in normal mode
if (params.disableBackwardsNavigation) {
toggleDotsNavigation(false);
// Check if first question is answered by default
if (i === 0 && questionInstances[i].getAnswerGiven()) {
questionInstances[i].showButton('next');
}
else {
questionInstances[i].hideButton('next');
}
questionInstances[i].hideButton('prev');
}
} }
catch(error) { catch(error) {
H5P.error("subcontent does not contain a valid resetTask function"); H5P.error("subcontent does not contain a valid resetTask function");
@ -329,17 +387,19 @@ H5P.QuestionSet = function (options, contentId, contentData) {
}; };
var moveQuestion = function (direction) { var moveQuestion = function (direction) {
if (params.disableBackwardsNavigation && !questionInstances[currentQuestion].getAnswerGiven()) {
questionInstances[currentQuestion].hideButton('next');
questionInstances[currentQuestion].hideButton('finish');
return;
}
_stopQuestion(currentQuestion); _stopQuestion(currentQuestion);
if (currentQuestion + direction >= questionInstances.length) { if (currentQuestion + direction >= questionInstances.length) {
_displayEndGame(); _displayEndGame();
}
else if (!params.disableBackwardsNavigation || questionInstances[currentQuestion].getAnswerGiven()) {
// Allow movement if backward navigation enabled or answer given
_showQuestion(currentQuestion + direction);
} }
else { else {
//TODO: Give an error message ? or disable/grey out previous button when not allowed // Allow movement if backward navigation enabled or answer given
_showQuestion(currentQuestion + direction);
} }
}; };
@ -390,9 +450,10 @@ H5P.QuestionSet = function (options, contentId, contentData) {
label += ', ' + texts.currentQuestionText; label += ', ' + texts.currentQuestionText;
} }
var disabledTabindex = params.disableBackwardsNavigation && !showingSolutions;
$el.toggleClass('current', isCurrent) $el.toggleClass('current', isCurrent)
.attr('aria-label', label) .attr('aria-label', label)
.attr('tabindex', isCurrent ? 0 : -1); .attr('tabindex', isCurrent && !disabledTabindex ? 0 : -1);
}; };
var _displayEndGame = function () { var _displayEndGame = function () {
@ -598,21 +659,20 @@ H5P.QuestionSet = function (options, contentId, contentData) {
moveQuestion.bind(this, 1), false); moveQuestion.bind(this, 1), false);
} else { } else {
// Only show button next button when answered or is allowed to go back
// Add next question button question.addButton('next', '', moveQuestion.bind(this, 1),
question.addButton('next', '', moveQuestion.bind(this, 1), true, { !params.disableBackwardsNavigation || !!question.getAnswerGiven(), {
href: '#', // Use href since this is a navigation button href: '#', // Use href since this is a navigation button
'aria-label': params.texts.nextButton 'aria-label': params.texts.nextButton
}); });
} }
// Add previous question button // Add previous question button
if (questionInstances[0] !== question && !params.disableBackwardsNavigation) { question.addButton('prev', '', moveQuestion.bind(this, -1),
question.addButton('prev', '', moveQuestion.bind(this, -1), true, { !(questionInstances[0] === question || params.disableBackwardsNavigation), {
href: '#', // Use href since this is a navigation button href: '#', // Use href since this is a navigation button
'aria-label': params.texts.prevButton 'aria-label': params.texts.prevButton
}); });
}
question.on('xAPI', function (event) { question.on('xAPI', function (event) {
var shortVerb = event.getVerb(); var shortVerb = event.getVerb();
@ -653,9 +713,13 @@ H5P.QuestionSet = function (options, contentId, contentData) {
* @param {Object} [event] * @param {Object} [event]
*/ */
var handleProgressDotClick = function (event) { var handleProgressDotClick = function (event) {
// Disable dots when backward nav disabled
event.preventDefault();
if (params.disableBackwardsNavigation && !showingSolutions) {
return;
}
_stopQuestion(currentQuestion); _stopQuestion(currentQuestion);
_showQuestion($(this).parent().index()); _showQuestion($(this).parent().index());
event.preventDefault();
}; };
// Set event listeners. // Set event listeners.