diff --git a/css/questionset.css b/css/questionset.css index 19130c0..fef0b6f 100644 --- a/css/questionset.css +++ b/css/questionset.css @@ -62,7 +62,7 @@ font-weight: bold; text-align: center; } -.intro-page .title > span { +.intro-page .title > span { padding: 0.125em 0.5em; border-radius: 0.125em; background: rgb(255,255,255); /* Fallback for browsers not supporting rgba */ @@ -91,37 +91,7 @@ .qs-footer { overflow: hidden; } -.qs-footer .h5p-button, .qs-startbutton, .qs-finishbutton, .questionset-results .h5p-button, .video-container > .h5p-button { - display: inline-block; - 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+ */ - background: -webkit-linear-gradient(top, rgba(100,152,254,1) 0%,rgba(4,104,206,1) 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(100,152,254,1) 0%,rgba(4,104,206,1) 100%); /* Opera 11.10+ */ - 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 .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+ */ - background: -webkit-linear-gradient(top, rgba(4,104,206,1) 0%,rgba(100,152,254,1) 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(4,104,206,1) 0%,rgba(100,152,254,1) 100%); /* Opera 11.10+ */ - background: -ms-linear-gradient(top, rgba(4,104,206,1) 0%,rgba(100,152,254,1) 100%); /* IE10+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0468ce', endColorstr='#6498fe',GradientType=0 ); /* IE6-9 */ -} + .qs-footer > .prev { float: left; } @@ -137,35 +107,60 @@ .questionset-results a.h5p-button.qs-retrybutton:before { font-family: 'H5PFontAwesome4'; padding-right: 0.5em; - content: "\f021"; + content: "\f01e"; } .qs-footer > .next, .qs-footer > .finish, .qs-finishbutton { float: right; } -.qs-footer a.next.h5p-button:after { - font-family: 'H5PFontAwesome4'; - content: "\f054"; /* TODO: Use margin not whitespace, spacing is not content! */ +.h5p-question .h5p-question-prev, +.h5p-question .h5p-question-finish, +.h5p-question .h5p-question-next { + float: right; } -.qs-footer a.prev.h5p-button:before { - font-family: 'H5PFontAwesome4'; +.h5p-question .h5p-question-prev, +.h5p-question .h5p-question-next { + padding: 0; + height: 2.1875em; + width: 2.1875em; +} + +.h5p-question .h5p-question-next, +.h5p-question .h5p-question-finish { + margin: 0 0 1.5em 0.5em; +} + +.h5p-question .h5p-question-prev { + margin: 0 0.5em 1.5em 0.5em; +} + +.h5p-question .h5p-question-next:before { + content: "\f054"; + padding-right: 0; + position: relative; + left: 2px; +} + +.h5p-question .h5p-question-prev:before { content: "\f053"; + padding-right: 0; + position: relative; + left: -2px; } .questionset-results .qs-finishbutton { display: none; } -.qs-footer a.finish.h5p-button:before { - font-family: 'H5PFontAwesome4'; - content: "\f00c "; +.h5p-question .h5p-question-finish:before { + content: "\f00c"; } .questionset-results a.h5p-button.qs-solutionbutton:before { font-family: 'H5PFontAwesome4'; - content: "\f06e "; + content: "\f06e "; /* TODO: Use margin not whitespace, spacing is not content! */ } .video-container { @@ -192,80 +187,31 @@ padding: 0.625em; } -.questionset-results .greeting { - text-align: left; - border-bottom: 0.1em solid #ddd; - width: 100%; +.questionset-results .feedback-section { + margin: 1em; } -.questionset-results .score { - margin: 0; - display: block; - margin-bottom: 2em; +.questionset-results .feedback-section .feedback-text { + font-weight: bold; + color: #1a73d9; } -.questionset-results .resulttext { - text-align: left; - font-size: 1.25em; - line-height: 1.25em; - margin: 1em 0em; - background-repeat: no-repeat; - background-position: left center; +.questionset-results .buttons { + margin-bottom: 1.5em; } -.questionset-results .resulttext.fail em { - font-style: normal; - color: #b9272d; +/* No margin for questions when no frame */ +.h5p-no-frame .questionset .h5p-question > * { + margin-left: 0; + margin-right: 0; } -.questionset-results .score.success .emoticon:before { - font-family: icomoon-questionset; - font-size: 5em; - line-height: 100%; - content: "\e606"; - float: left; +.h5p-no-frame .questionset-results .feedback-section, +.h5p-no-frame .questionset .h5p-question > *:first-child { + margin-top: 0; } -.questionset-results .score.fail .emoticon:before { - font-family: icomoon-questionset; - font-size: 5em; - line-height: 100%; - content: "\e607"; - float: left; -} - -.questionset-results .resulttext.success, -.questionset-results .resulttext.almost, -.questionset-results .resulttext.fail -{ - display: block; - background: #eee; - padding: 1em; - border-radius: 1em; - margin-left: 6.5em; - position: relative; - font-size: 1em; -} - -.questionset-results .resulttext.success:before, -.questionset-results .resulttext.fail:before -{ - font-family: icomoon-questionset; - content: ""; - font-size: 5em; - position: absolute; - left: -14px; - top: 36px; - height: 0; - width: 0; - border-top: 15px solid transparent; - border-bottom: 15px solid transparent; - border-right: 15px solid #eee; - display: inline-block; -} - -.questionset-results .resulttext.success em { - font-style: normal; - color: #6aa81b; - text-align: left; +.h5p-no-frame .questionset-results .buttons, +.h5p-no-frame .questionset .h5p-question > *:last-child { + margin-bottom: 0; } diff --git a/js/questionset.js b/js/questionset.js index 6554bdf..ff08a33 100644 --- a/js/questionset.js +++ b/js/questionset.js @@ -28,7 +28,7 @@ H5P.QuestionSet = function (options, contentId) { ' <% if (introPage.introduction) { %>' + '
<%= introPage.introduction %>
' + ' <% } %>' + - '
<%= introPage.startButtonText %>
' + + '
<%= introPage.startButtonText %>
' + '' + '<% } %>' + '
' + @@ -47,20 +47,20 @@ H5P.QuestionSet = function (options, contentId) { ' ' + ' <% } %>' + '
' + - ' ' + - ' ' + - ' <%= texts.finishButton %>' + ' ' + ''; var resulttemplate = '
' + - '
<%= message %>
' + - '
' + - '
' + - '
<% if (comment) { %>

<%= comment %>

<% } %><%= score %>
<%= resulttext %>
' + + ' ' + + ' ' + - ' ' + '
'; var defaults = { @@ -109,6 +109,7 @@ H5P.QuestionSet = function (options, contentId) { var currentQuestion = 0; var questionInstances = []; var $myDom; + var scoreBar; renderSolutions = false; // Instantiate question instances @@ -126,11 +127,15 @@ H5P.QuestionSet = function (options, contentId) { } var questionInstance = H5P.newRunnable(question, contentId, undefined, undefined, {parent: self}); questionInstances.push(questionInstance); - questionInstance.on('resize', function() { - self.trigger('resize'); - }); } + // Resize all interactions on resize + self.on('resize', function () { + for (var i = 0; i < questionInstances.length; i++) { + questionInstances[i].trigger('resize'); + } + }); + // Update button state. var _updateButtons = function () { var answered = true; @@ -138,19 +143,8 @@ H5P.QuestionSet = function (options, contentId) { answered = answered && (questionInstances[i]).getAnswerGiven(); } - if (currentQuestion === 0) { - $('.prev.h5p-button', $myDom).hide(); - } else { - $('.prev.h5p-button', $myDom).show(); - } - if (currentQuestion === (params.questions.length - 1)) { - $('.next.h5p-button', $myDom).hide(); - if (answered) { - $('.finish.h5p-button', $myDom).show(); - } - } else { - $('.next.h5p-button', $myDom).show(); - $('.finish.h5p-button', $myDom).hide(); + if (currentQuestion === (params.questions.length - 1) && answered) { + questionInstances[currentQuestion].showButton('finish'); } }; @@ -201,8 +195,8 @@ H5P.QuestionSet = function (options, contentId) { questionInstances[i].showSolutions(); } catch(error) { - console.log(error); - console.log("subcontent does not contain a valid showSolutions() function"); + H5P.error("subcontent does not contain a valid showSolutions function"); + H5P.error(error); } } }; @@ -218,10 +212,14 @@ H5P.QuestionSet = function (options, contentId) { questionInstances[i].resetTask(); } catch(error) { - console.log(error); - console.log("subcontent does not contain a valid resetTask() function"); + H5P.error("subcontent does not contain a valid resetTask function"); + H5P.error(error); } } + + // Hide finish button + questionInstances[questionInstances.length - 1].hideButton('finish'); + //Force the last page to be reRendered rendered = false; }; @@ -260,11 +258,7 @@ H5P.QuestionSet = function (options, contentId) { } var eparams = { - message: params.endGame.message, comment: (success ? params.endGame.successGreeting : params.endGame.failGreeting), - score: scoreString, - scoreclass: (success ? 'success' : 'fail'), - resulttext: (success ? params.endGame.successComment : params.endGame.failComment), finishButtonText: params.endGame.finishButtonText, solutionButtonText: params.endGame.solutionButtonText }; @@ -272,7 +266,7 @@ H5P.QuestionSet = function (options, contentId) { // Show result page. $myDom.children().hide(); $myDom.append(endTemplate.render(eparams)); - $('.qs-finishbutton').click(function () { + $('.qs-finishbutton', $myDom).click(function () { self.trigger('h5pQuestionSetFinished', eventData); }); $('.qs-solutionbutton', $myDom).click(function () { @@ -286,6 +280,13 @@ H5P.QuestionSet = function (options, contentId) { resetTask(); $myDom.children().hide().filter('.questionset').show(); _showQuestion(params.initialQuestion);}); + + if (scoreBar === undefined) { + scoreBar = H5P.JoubelUI.createScoreBar(totals); + } + scoreBar.appendTo($('.feedback-scorebar', $myDom)); + scoreBar.setScore(finals); + $('.feedback-text', $myDom).html(scoreString); }; if (params.endGame.showAnimations) { @@ -314,7 +315,7 @@ H5P.QuestionSet = function (options, contentId) { video.play(); if (params.endGame.skipButtonText) { - $('').click(function () { + $('').click(function () { video.pause(); $videoContainer.hide(); displayResults(); @@ -331,6 +332,7 @@ H5P.QuestionSet = function (options, contentId) { // Function for attaching the multichoice to a DOM element. this.attach = function (target) { + this.setActivityStarted(); if (typeof(target) === "string") { $myDom = $('#' + target); } @@ -363,11 +365,45 @@ H5P.QuestionSet = function (options, contentId) { var question = questionInstances[i]; question.attach($('.question-container:eq(' + i + ')', $myDom)); + + // Disable feedback for question + question.setBehaviour({disableFeedback: true}); + + // Add next/finish button + if (questionInstances[questionInstances.length -1] === question) { + + // Add finish question set button + question.addButton('finish', params.texts.finishButton, function () { + _displayEndGame(); + }); + + } else { + + // Add next question button + question.addButton('next', '', function () { + _showQuestion(currentQuestion + 1); + }); + } + + // Add previous question button + if (questionInstances[0] !== question) { + question.addButton('prev', '', function () { + _showQuestion(currentQuestion - 1); + }); + } + question.on('xAPI', function (event) { - if (event.getVerb() === 'attempted') { + var shortVerb = event.getVerb(); + if (shortVerb === 'interacted' || + shortVerb === 'answered' || + shortVerb === 'attempted') { $('.progress-dot:eq(' + currentQuestion +')', $myDom).removeClass('unanswered').addClass('answered'); _updateButtons(); } + if (shortVerb === 'completed') { + // An activity within this activity is not allowed to send completed events + event.setVerb('answered'); + } }); if (question.getAnswerGiven()) { $('.progress-dot:eq(' + i +')', $myDom).removeClass('unanswered').addClass('answered'); @@ -387,15 +423,6 @@ H5P.QuestionSet = function (options, contentId) { $('.progress-dot', $myDom).click(function () { _showQuestion($(this).index()); }); - $('.next.h5p-button', $myDom).click(function () { - _showQuestion(currentQuestion + 1); - }); - $('.prev.h5p-button', $myDom).click(function () { - _showQuestion(currentQuestion - 1); - }); - $('.finish.h5p-button', $myDom).click(function () { - _displayEndGame(); - }); // Hide all but initial Question. _showQuestion(params.initialQuestion); diff --git a/language/fr.json b/language/fr.json new file mode 100644 index 0000000..27eb841 --- /dev/null +++ b/language/fr.json @@ -0,0 +1,163 @@ +{ + "semantics": [ + { + "label": "Introduction du Quiz ", + "fields": [ + { + "label": "Montrer l'introduction" + }, + { + "label": "Titre", + "description": "Ce titre sera affiché au-dessus de votre texte d'introduction." + }, + { + "label": "Texte d'introduction ", + "description": "Ce texte sera affiché avant le démarrage du quiz." + }, + { + "label": "Texte du bouton de démarrage" + }, + { + "label": "Image d'arrière-plan", + "description": "Image d'arrière-plan optionnelle pour l'introduction." + } + ] + }, + { + "label": "Image d'arrière-plan", + "description": "Image d'arrière-plan optionnelle pour la série de questions." + }, + { + "label": "Indicateur de progression", + "description": "Style de l'indicateur de progression de la série de questions", + "options": [ + { + "label": "Texte" + }, + { + "label": "Points" + } + ] + }, + { + "label": "Pourcentage de réussite", + "description": "Pourcentage exigé pour la réussite du quiz." + }, + { + "label": "Questions", + "widgets": [ + { + "label": "Par défaut" + }, + { + "label": "Texte" + } + ], + "entity": "question", + "field": { + "label": "Type de question", + "description": "Types possibles pour cette question." + } + }, + { + "label": "Interface des Textes dans le quiz", + "fields": [ + { + "label": "Bouton précédent" + }, + { + "label": "Bouton suivant" + }, + { + "label": "Bouton fin" + }, + { + "label": "Texte de progression", + "description": "Texte utilisé si la progression textuelle est utilisée." + } + ] + }, + { + "label": "Quiz fini", + "fields": [ + { + "label": "Montrer les résultats" + }, + { + "label": "Feedback de fin", + "description": "Ce texte sera affiché quand l'utilisateur aura totalement terminé le quiz." + }, + { + "label": "Texte d'affichage du score", + "description": "Texte utilisé pour afficher le score total de l'utilisateur. \"@score\" sera remplacé par le score de l'utilisateur, \"@total\" sera remplacé par le score maximum possible." + }, + { + "label": "Texte de félicitation", + "description": "Texte affiché lors du passage du quiz avec succès." + }, + { + "label": "Commentaire de fin de quiz réussi", + "description": "Commentaire affiché lors du passage du quiz avec succès." + }, + { + "label": "Texte d'échec", + "description": "Texte affiché lors de l'échec au quiz." + }, + { + "label": "Commentaire de fin de quiz échoué", + "description": "Commentaire affiché lors de l'échec au quiz." + }, + { + "label": "Texte du bouton Solution", + "description": "Texte pour le bouton de solution." + }, + { + "label": "Texte du bouton Réessayer", + "description": "Texte pour le bouton Réessayer." + }, + { + "label": "Texte pour le bouton de fin" + }, + { + "label": "Montrer une vidéo avant l'affichage des résultats du quiz" + }, + { + "label": "Activer le bouton passer la vidéo" + }, + { + "label": "Texte du bouton passer la vidéo" + }, + { + "label": "Video en cas de succès", + "description": "Vidéo affichée lors du passage du quiz avec succès." + }, + { + "label": "Video en cas d'échec", + "description": "Vidéo affichée lors de l'échec au quiz." + } + ] + }, + { + "label": "Options pour les boutons \"Montrer la solution\" et \"Réessayer\".", + "description": "Ces options vous permettent de choisir quand afficher les boutons \"Solutions\" et \"Réessayer\" dans votre acivité h5p..", + "fields": [ + { + "label": "Activer les réglages par défaut pour les boutons \"Solution\" et \"Réessayer\".", + "description": "Si cette option est choisie, les réglages seront valables pour toutes les questions, les réglages individuels ne seront pas pris en compte." + }, + { + "label": "Afficher le bouton \"Solution\".", + "description": "Affiche le bouton \"Solution\"." + }, + { + "label": "Afficher le bouton \"Réessayer\".", + "description": "Affiche le bouton \"Réessayer\"." + } + ] + }, + { + "label": "Texte de la question", + "default": "Question" + } + ] +} diff --git a/library.json b/library.json index 2f96968..5f45d14 100644 --- a/library.json +++ b/library.json @@ -1,5 +1,6 @@ { - "title": "Question set", + "title": "Question Set", + "description": "Put together a set of different questions that has to be solved. (Quiz)", "contentType": "question", "majorVersion": 1, "minorVersion": 4, @@ -13,9 +14,9 @@ "author": "Joubel AS", "coreApi": { "majorVersion": 1, - "minorVersion": 5 + "minorVersion": 6 }, - "license": "cc-by-sa", + "license": "MIT", "preloadedJs": [ { "path": "js/questionset.js" @@ -41,6 +42,11 @@ "machineName": "H5P.Video", "majorVersion": 1, "minorVersion": 1 + }, + { + "machineName": "H5P.JoubelUI", + "majorVersion": 1, + "minorVersion": 1 } ], "editorDependencies": [ @@ -55,4 +61,4 @@ "minorVersion": 0 } ] -} \ No newline at end of file +}