diff --git a/css/questionset.css b/css/questionset.css index bf83c08..19130c0 100644 --- a/css/questionset.css +++ b/css/questionset.css @@ -22,9 +22,6 @@ .questionset.hidden { display: none; } -.questionset .h5p-multichoice > .h5p-show-solution, .questionset .dragndrop > .h5p-show-solution, .h5p-blanks .h5p-button { - display: none; -} .questionset, .intro-page, .questionset-results { position: relative; } @@ -53,10 +50,10 @@ box-shadow: 0 0 0.5em #c7c7c7; } .progress-dot.answered { - background: #bccade; + background: #73a2d5; } .progress-dot.current { - background: #267ec9; + background: #285585; } .intro-page .title { @@ -94,16 +91,16 @@ .qs-footer { overflow: hidden; } -.qs-footer .button, .qs-startbutton, .qs-finishbutton, .questionset-results .button, .video-container > .button { +.qs-footer .h5p-button, .qs-startbutton, .qs-finishbutton, .questionset-results .h5p-button, .video-container > .h5p-button { display: inline-block; - padding: 0.2em 1em; + padding: 0 0.7em; border: 0.2em solid #fff; border-radius: 0.4em; margin: 0 0.5em 1em; cursor: pointer; color: #ffffff; box-shadow: 0 0 0.5em #999; - + line-height: 1.9em; background: rgb(100,152,254); /* Old browsers */ background: -moz-linear-gradient(top, rgba(100,152,254,1) 0%, rgba(4,104,206,1) 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(100,152,254,1)), color-stop(100%,rgba(4,104,206,1))); /* Chrome,Safari4+ */ @@ -112,11 +109,11 @@ background: -ms-linear-gradient(top, rgba(100,152,254,1) 0%,rgba(4,104,206,1) 100%); /* IE10+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6498fe', endColorstr='#0468ce',GradientType=0 ); /* IE6-9 */ } -.qs-footer .button:hover, .qs-startbutton:hover, .questionset-results .button:hover, .video-container > .button:hover { +.qs-footer .h5p-button:hover, .qs-startbutton:hover, .questionset-results .h5p-button:hover, .video-container > .h5p-button:hover { text-decoration: none; box-shadow: 0 0 0.5em #999; color: #ffffff; - + border-color: #fff; background: rgb(4,104,206); /* Old browsers */ background: -moz-linear-gradient(top, rgba(4,104,206,1) 0%, rgba(100,152,254,1) 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(4,104,206,1)), color-stop(100%,rgba(100,152,254,1))); /* Chrome,Safari4+ */ @@ -133,30 +130,40 @@ float: none; } +.qs-footer > .qs-retrybutton { + float: none; +} + +.questionset-results a.h5p-button.qs-retrybutton:before { + font-family: 'H5PFontAwesome4'; + padding-right: 0.5em; + content: "\f021"; +} + .qs-footer > .next, .qs-footer > .finish, .qs-finishbutton { float: right; } -.qs-footer a.next.button:after { +.qs-footer a.next.h5p-button:after { font-family: 'H5PFontAwesome4'; - content: " \f054"; /* TODO: Use margin not whitespace, spacing is not content! */ + content: "\f054"; /* TODO: Use margin not whitespace, spacing is not content! */ } -.qs-footer a.prev.button:before { +.qs-footer a.prev.h5p-button:before { font-family: 'H5PFontAwesome4'; - content: "\f053 "; + content: "\f053"; } .questionset-results .qs-finishbutton { display: none; } -.qs-footer a.finish.button:before { +.qs-footer a.finish.h5p-button:before { font-family: 'H5PFontAwesome4'; content: "\f00c "; } -.questionset-results a.button.qs-solutionbutton:before { +.questionset-results a.h5p-button.qs-solutionbutton:before { font-family: 'H5PFontAwesome4'; content: "\f06e "; } @@ -167,7 +174,7 @@ .video-container > video { background-color: #000; } -.video-container > .button { +.video-container > .h5p-button { position: absolute; top: 0.5em; right: 0.5em; diff --git a/js/questionset.js b/js/questionset.js index 053eaf8..6050ae4 100644 --- a/js/questionset.js +++ b/js/questionset.js @@ -14,9 +14,10 @@ H5P.QuestionSet = function (options, contentId) { if (!(this instanceof H5P.QuestionSet)) { return new H5P.QuestionSet(options, contentId); } - + H5P.EventDispatcher.call(this); var $ = H5P.jQuery; var self = this; + this.contentId = contentId; var texttemplate = '<% if (introPage.showIntroPage) { %>' + @@ -27,7 +28,7 @@ H5P.QuestionSet = function (options, contentId) { ' <% if (introPage.introduction) { %>' + '
<%= introPage.introduction %>
' + ' <% } %>' + - '
<%= introPage.startButtonText %>
' + + '
<%= introPage.startButtonText %>
' + '' + '<% } %>' + '
' + @@ -46,9 +47,9 @@ H5P.QuestionSet = function (options, contentId) { ' ' + ' <% } %>' + '
' + - ' ' + - ' ' + - ' <%= texts.finishButton %>' + + ' ' + + ' ' + + ' <%= texts.finishButton %>' + ' ' + ''; @@ -59,7 +60,7 @@ H5P.QuestionSet = function (options, contentId) { '
' + '
<% if (comment) { %>

<%= comment %>

<% } %><%= score %>
<%= resulttext %>
' + ' ' + - '
<%= finishButtonText %><%= solutionButtonText %>
' + + '
<%= finishButtonText %><%= solutionButtonText %>
' + ''; var defaults = { @@ -90,7 +91,13 @@ H5P.QuestionSet = function (options, contentId) { scoreString: 'You got @score points of @total possible.', finishButtonText: 'Finish', solutionButtonText: 'Show solution', + retryButtonText: 'Retry', showAnimations: false + }, + override: { + overrideButtons: false, + overrideShowSolutionButton: false, + overrideRetry: false } }; @@ -108,10 +115,19 @@ H5P.QuestionSet = function (options, contentId) { var question = params.questions[i]; // TODO: Render on init, inject in template. - $.extend(question.params, { - displaySolutionsButton: false + // override content parameters. + if (params.override.overrideButtons) { + // Extend subcontent with the overrided settings. + $.extend(question.params.behaviour, { + enableRetry: params.override.overrideRetry, + enableSolutionsButton: params.override.overrideShowSolutionButton + }); + } + var questionInstance = H5P.newRunnable(question, contentId); + questionInstances.push(questionInstance); + questionInstance.on('resize', function() { + self.trigger('resize'); }); - questionInstances.push(H5P.newRunnable(question, contentId)); } // Update button state. @@ -122,18 +138,18 @@ H5P.QuestionSet = function (options, contentId) { } if (currentQuestion === 0) { - $('.prev.button', $myDom).hide(); + $('.prev.h5p-button', $myDom).hide(); } else { - $('.prev.button', $myDom).show(); + $('.prev.h5p-button', $myDom).show(); } if (currentQuestion === (params.questions.length - 1)) { - $('.next.button', $myDom).hide(); + $('.next.h5p-button', $myDom).hide(); if (answered) { - $('.finish.button', $myDom).show(); + $('.finish.h5p-button', $myDom).show(); } } else { - $('.next.button', $myDom).show(); - $('.finish.button', $myDom).hide(); + $('.next.h5p-button', $myDom).show(); + $('.finish.h5p-button', $myDom).hide(); } }; @@ -169,18 +185,49 @@ H5P.QuestionSet = function (options, contentId) { // Remember where we are currentQuestion = questionNumber; _updateButtons(); + self.trigger('resize'); return currentQuestion; }; + /** + * Show solutions for subcontent, and hide subcontent buttons. + * Used for contracts with integrated content. + * @public + */ var showSolutions = function () { for (var i = 0; i < questionInstances.length; i++) { - questionInstances[i].showSolutions(); + try { + questionInstances[i].showSolutions(); + } + catch(error) { + console.log(error); + console.log("subcontent does not contain a valid showSolutions() function"); + } } }; + /** + * Resets the task and every subcontent task. + * Used for contracts with integrated content. + * @public + */ + var resetTask = function () { + for (var i = 0; i < questionInstances.length; i++) { + try { + questionInstances[i].resetTask(); + } + catch(error) { + console.log(error); + console.log("subcontent does not contain a valid resetTask() function"); + } + } + //Force the last page to be reRendered + rendered = false; + }; + var rendered = false; - var reRender = function () { + this.reRender = function () { rendered = false; }; @@ -189,11 +236,13 @@ H5P.QuestionSet = function (options, contentId) { $myDom.children().hide().filter('.questionset-results').show(); return; } + //Remove old score screen. + $myDom.children().hide().filter('.questionset-results').remove(); rendered = true; // Get total score. - var finals = getScore(); - var totals = totalScore(); + var finals = self.getScore(); + var totals = self.totalScore(); var scoreString = params.endGame.scoreString.replace("@score", finals).replace("@total", totals); var success = ((100 * finals / totals) >= params.passPercentage); var eventData = { @@ -201,10 +250,10 @@ H5P.QuestionSet = function (options, contentId) { passed: success }; var displayResults = function () { - self.triggerXAPI('completed', {result: H5P.getxAPIScoredResult(getScore(), totalScore())}); + self.triggerXAPICompleted(self.getScore(), self.totalScore()); if (!params.endGame.showResultPage) { - $(returnObject).trigger('h5pQuestionSetFinished', eventData); + self.trigger('h5pQuestionSetFinished', eventData); return; } @@ -222,13 +271,19 @@ H5P.QuestionSet = function (options, contentId) { $myDom.children().hide(); $myDom.append(endTemplate.render(eparams)); $('.qs-finishbutton').click(function () { - $(returnObject).trigger('h5pQuestionSetFinished', eventData); + self.trigger('h5pQuestionSetFinished', eventData); }); $('.qs-solutionbutton', $myDom).click(function () { showSolutions(); $myDom.children().hide().filter('.questionset').show(); _showQuestion(params.initialQuestion); }); + $('.qs-retrybutton', $myDom) + .html(params.endGame.retryButtonText) + .click(function () { + resetTask(); + $myDom.children().hide().filter('.questionset').show(); + _showQuestion(params.initialQuestion);}); }; if (params.endGame.showAnimations) { @@ -251,7 +306,7 @@ H5P.QuestionSet = function (options, contentId) { video.play(); if (params.endGame.skipButtonText) { - $('').click(function () { + $('').click(function () { video.stop(); $videoContainer.hide(); displayResults(); @@ -266,7 +321,7 @@ H5P.QuestionSet = function (options, contentId) { }; // Function for attaching the multichoice to a DOM element. - var attach = function (target) { + this.attach = function (target) { if (typeof(target) === "string") { $myDom = $('#' + target); } @@ -279,16 +334,16 @@ H5P.QuestionSet = function (options, contentId) { if (params.backgroundImage !== undefined) { $myDom.css({ overflow: 'hidden', - background: '#000 url("' + H5P.getPath(params.backgroundImage.path, contentId) + '") no-repeat 50% 50%', + 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) { $intro.css({ - background: '#000 url("' + H5P.getPath(params.introPage.backgroundImage.path, contentId) + '") no-repeat 50% 50%', + background: '#fff url("' + H5P.getPath(params.introPage.backgroundImage.path, contentId) + '") no-repeat 50% 50%', backgroundSize: '100% auto' }); } @@ -299,7 +354,7 @@ H5P.QuestionSet = function (options, contentId) { var question = questionInstances[i]; question.attach($('.question-container:eq(' + i + ')', $myDom)); - question.registerH5PEventListener('xAPI', function (event) { + question.on('xAPI', function (event) { if (event.verb === 'attempted') { $('.progress-dot:eq(' + currentQuestion +')', $myDom).removeClass('unanswered').addClass('answered'); _updateButtons(); @@ -324,13 +379,13 @@ H5P.QuestionSet = function (options, contentId) { $('.progress-dot', $myDom).click(function () { _showQuestion($(this).index()); }); - $('.next.button', $myDom).click(function () { + $('.next.h5p-button', $myDom).click(function () { _showQuestion(currentQuestion + 1); }); - $('.prev.button', $myDom).click(function () { + $('.prev.h5p-button', $myDom).click(function () { _showQuestion(currentQuestion - 1); }); - $('.finish.button', $myDom).click(function () { + $('.finish.h5p-button', $myDom).click(function () { _displayEndGame(); }); @@ -343,11 +398,12 @@ H5P.QuestionSet = function (options, contentId) { } this.trigger('resize'); + return this; }; // Get current score for questionset. - var getScore = function () { + this.getScore = function () { var score = 0; for (var i = questionInstances.length - 1; i >= 0; i--) { score += questionInstances[i].getScore(); @@ -356,29 +412,29 @@ H5P.QuestionSet = function (options, contentId) { }; // Get total score possible for questionset. - var totalScore = function () { + this.totalScore = function () { var score = 0; for (var i = questionInstances.length - 1; i >= 0; i--) { score += questionInstances[i].getMaxScore(); } return score; }; - + /** * Gather copyright information for the current content. * * @returns {H5P.ContentCopyrights} */ - var getCopyrights = function () { + this.getCopyrights = function () { var info = new H5P.ContentCopyrights(); - + // Background if (params.backgroundImage !== undefined && params.backgroundImage.copyright !== undefined) { var background = new H5P.MediaCopyright(params.backgroundImage.copyright); background.setThumbnail(new H5P.Thumbnail(H5P.getPath(params.backgroundImage.path, contentId), params.backgroundImage.width, params.backgroundImage.height)); info.addMedia(background); } - + // Questions for (var i = 0; i < questionInstances.length; i++) { var questionInstance = questionInstances[i]; @@ -390,7 +446,7 @@ H5P.QuestionSet = function (options, contentId) { } } } - + // Success video if (params.endGame.successVideo !== undefined && params.endGame.successVideo.length > 0) { var video = params.endGame.successVideo[0]; @@ -398,7 +454,7 @@ H5P.QuestionSet = function (options, contentId) { info.addMedia(new H5P.MediaCopyright(video.copyright)); } } - + // Fail video if (params.endGame.failVideo !== undefined && params.endGame.failVideo.length > 0) { video = params.endGame.failVideo[0]; @@ -406,23 +462,15 @@ H5P.QuestionSet = function (options, contentId) { info.addMedia(new H5P.MediaCopyright(video.copyright)); } } - + return info; }; - - // Masquerade the main object to hide inner properties and functions. - var returnObject = { - $: $(this), - attach: attach, // Attach to DOM object - getQuestions: function () {return questionInstances;}, - getScore: getScore, - showSolutions: function () { - renderSolutions = true; - }, - totalScore: totalScore, - reRender: reRender, - defaults: defaults, // Provide defaults for inspection - getCopyrights: getCopyrights + this.getQuestions = function() { + return questionInstances; }; - return returnObject; + this.showSolutions = function() { + renderSolutions = true; + } }; +H5P.QuestionSet.prototype = Object.create(H5P.EventDispatcher.prototype); +H5P.QuestionSet.prototype.constructor = H5P.QuestionSet; \ No newline at end of file diff --git a/language/nb.json b/language/nb.json index c5e68e8..c731683 100644 --- a/language/nb.json +++ b/language/nb.json @@ -143,6 +143,24 @@ "description": "Denne videoen vil bli vist dersom brukeren ikke består spørsmålssettet." } ] + }, + { + "label": "Innstillinger for \"Vis svar\" knapp og \"Prøv igjen\".", + "description": "Disse instillingene lar deg overstyre når \"Vis svar\" knapp og \"Prøv igjen\" er slått på i integrert h5p innhold.", + "fields": [ + { + "label": "Slå på overstyring for \"Vis svar\" og \"Prøv igjen\".", + "description": "Aktivering vil overstyre de følgende innstillingene for integrert innhold." + }, + { + "label": "Slå på \"Vis svar\" knapp.", + "description": "Aktivering vil slå på \"Vis svar\" knappen." + }, + { + "label": "Slå på \"Prøv igjen\".", + "description": "Aktivering vil slå på \"Prøv igjen\" ." + } + ] } ] } diff --git a/language/nn.json b/language/nn.json index e14190f..667389e 100644 --- a/language/nn.json +++ b/language/nn.json @@ -143,6 +143,24 @@ "description": "Denne videoen vil bli vist dersom brukaren ikkje består spørsmålssettet." } ] + }, + { + "label": "Innstillinger for \"Vis svar\" knapp og \"Prøv igjen\".", + "description": "Disse instillingene lar deg overstyre når \"Vis svar\" knapp og \"Prøv igjen\" er slått på i integrert h5p innhald.", + "fields": [ + { + "label": "Slå på overstyring for \"Vis svar\" og \"Prøv igjen\".", + "description": "Aktivering vil overstyre dei følgjande innstillingene for integrert innhald." + }, + { + "label": "Slå på \"Vis svar\" knapp.", + "description": "Aktivering vil slå på \"Vis svar\" knappen." + }, + { + "label": "Slå på \"Prøv igjen\".", + "description": "Aktivering vil slå på \"Prøv igjen\" ." + } + ] } ] } diff --git a/library.json b/library.json index a172167..645e854 100644 --- a/library.json +++ b/library.json @@ -2,8 +2,11 @@ "title": "Question set", "contentType": "question", "majorVersion": 1, - "minorVersion": 0, - "patchVersion": 55, + "minorVersion": 1, + "patchVersion": 0, + "embedTypes": [ + "iframe" + ], "runnable": 1, "fullscreen": 0, "machineName": "H5P.QuestionSet", diff --git a/semantics.json b/semantics.json index 7e061cc..cc8a64d 100644 --- a/semantics.json +++ b/semantics.json @@ -101,9 +101,11 @@ "label": "Question type", "description": "Library for this question.", "options": [ - "H5P.MultiChoice 1.0", - "H5P.DragQuestion 1.0", - "H5P.Blanks 1.0" + "H5P.MultiChoice 1.2", + "H5P.DragQuestion 1.2", + "H5P.Blanks 1.2", + "H5P.MarkTheWords 1.2", + "H5P.DragText 1.2" ] } }, @@ -239,6 +241,13 @@ "default": "Show solution", "description": "Text for the solution button." }, + { + "name": "retryButtonText", + "type": "text", + "label": "Retry button label", + "default": "Retry", + "description": "Text for the retry button." + }, { "name": "finishButtonText", "type": "text", @@ -259,8 +268,7 @@ "name": "skipButtonText", "type": "text", "label": "Skip video button label", - "default": "Skip video", - "common": true + "default": "Skip video" }, { "name": "successVideo", @@ -277,5 +285,35 @@ "description": "This video will be played if the user failes the quiz." } ] + }, + { + "name": "override", + "type": "group", + "label": "Settings for \"Show solution\" button and \"Retry\".", + "description": "These options will let you override when to display \"Show solution\" button and \"Retry\" in integrated h5p content.", + "optional": true, + "fields": [ + { + "name": "overrideButtons", + "type": "boolean", + "label": "Enable override for \"Show solution\" and \"Retry\" settings.", + "description": "If this is enabled the questions own settings will be ignored and the below settings will be used instead.", + "default": false + }, + { + "name": "overrideShowSolutionButton", + "type": "boolean", + "label": "Enable \"Show solution\" buttons.", + "description": "Enabling this option will make questions show the \"Show solution\" button.", + "default": false + }, + { + "name": "overrideRetry", + "type": "boolean", + "label": "Enable \"Retry\".", + "description": "Enabling this option will make the user able to \"Retry\" .", + "default": false + } + ] } ]