diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 0000000..48edea1
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,3 @@
+files:
+ - source: /language/.en.json
+ translation: /language/%two_letters_code%.json
diff --git a/css/questionset.css b/css/questionset.css
index 22e65d2..a9eb1fc 100644
--- a/css/questionset.css
+++ b/css/questionset.css
@@ -1,15 +1,3 @@
-/* IcoMoon font licensed under the GNU General Public License: http://www.gnu.org/licenses/gpl.html */
-@font-face {
- font-family: 'icomoon-questionset';
- src:url('../fonts/icomoon.eot');
- src:url('../fonts/icomoon.eot?#iefix') format('embedded-opentype'),
- url('../fonts/icomoon.woff') format('woff'),
- url('../fonts/icomoon.ttf') format('truetype'),
- url('../fonts/icomoon.svg#icomoon') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
.questionset-results h2 {
font-size: 1.2em;
font-weight: bold;
@@ -237,30 +225,27 @@
font-size: 1.25em;
}
-.questionset-results .feedback-section .feedback-text {
- font-weight: normal;
- color: #777;
-}
-
.questionset-results .buttons {
- margin-bottom: 1.5em;
+ margin: 2em 0 1em 0;
}
.questionset-results .result-header,
-.questionset-results .result-text {
+.questionset-results .result-text,
+.questionset-results .feedback-section .feedback-text {
color: #1a73d9;
font-weight: bold;
}
.questionset-results .result-header {
font-size: 2em;
- margin-top: 1em;
+ margin: 1em 0.5em 0.5em 0.5em;
}
-.questionset-results .result-text {
+.questionset-results .result-text,
+.questionset-results .feedback-section .feedback-text {
font-size: 1.25em;
line-height: 1.25em;
- margin: 1em 1em 2.25em;
+ margin: 1em;
}
/* No margin for questions when no frame */
diff --git a/fonts/icomoon.eot b/fonts/icomoon.eot
deleted file mode 100644
index d8cdc1a..0000000
Binary files a/fonts/icomoon.eot and /dev/null differ
diff --git a/fonts/icomoon.svg b/fonts/icomoon.svg
deleted file mode 100644
index 1a48364..0000000
--- a/fonts/icomoon.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/fonts/icomoon.ttf b/fonts/icomoon.ttf
deleted file mode 100644
index 9649f7e..0000000
Binary files a/fonts/icomoon.ttf and /dev/null differ
diff --git a/fonts/icomoon.woff b/fonts/icomoon.woff
deleted file mode 100644
index 5d29f5d..0000000
Binary files a/fonts/icomoon.woff and /dev/null differ
diff --git a/js/questionset.js b/js/questionset.js
index 0fdd085..0a29e99 100644
--- a/js/questionset.js
+++ b/js/questionset.js
@@ -61,6 +61,10 @@ H5P.QuestionSet = function (options, contentId, contentData) {
' ' +
'';
+ var solutionButtonTemplate = options.endGame.showSolutionButton ?
+ ' ':
+ '';
+
var resulttemplate =
'
' +
'
<%= message %>
' +
@@ -76,7 +80,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
' <% } %>' +
'
' +
' ' +
- ' ' +
+ solutionButtonTemplate +
' ' +
'
' +
'
';
@@ -108,17 +112,20 @@ H5P.QuestionSet = function (options, contentId, contentData) {
showResultPage: true,
noResultMessage: 'Finished',
message: 'Your result:',
- successGreeting: 'Congratulations!',
- successComment: 'You have enough correct answers to pass the test.',
- failGreeting: 'Sorry!',
- failComment: "You don't have enough correct answers to pass this test.",
- scoreString: 'You got @score of @total points',
+ oldFeedback: {
+ successGreeting: '',
+ successComment: '',
+ failGreeting: '',
+ failComment: ''
+ },
+ overallFeedback: [],
finishButtonText: 'Finish',
solutionButtonText: 'Show solution',
retryButtonText: 'Retry',
showAnimations: false,
skipButtonText: 'Skip video'
},
+ override: {},
disableBackwardsNavigation: false
};
@@ -154,27 +161,27 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var randomizeQuestionOrdering = function (questions) {
// 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]; });
// Shuffle the multidimensional array
questionOrdering = H5P.shuffleArray(questionOrdering);
// Retrieve question objects from the first index
- var questions = [];
+ questions = [];
for (var i = 0; i < questionOrdering.length; i++) {
questions[i] = questionOrdering[i][0];
}
// Retrieve the new shuffled order from the second index
var newOrder = [];
- for (var i = 0; i< questionOrdering.length; i++) {
+ for (var j = 0; j < questionOrdering.length; j++) {
// Use a previous order if it exists
- if(contentData.previousState && contentData.previousState.questionOrder) {
- newOrder[i] = questionOrder[questionOrdering[i][1]];
+ if (contentData.previousState && contentData.previousState.questionOrder) {
+ newOrder[j] = questionOrder[questionOrdering[j][1]];
}
else {
- newOrder[i] = questionOrdering[i][1];
+ newOrder[j] = questionOrdering[j][1];
}
}
@@ -189,7 +196,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
if (params.poolSize > 0) {
// If a previous pool exists, recreate it
- if(contentData.previousState && contentData.previousState.poolOrder) {
+ if (contentData.previousState && contentData.previousState.poolOrder) {
poolOrder = contentData.previousState.poolOrder;
// Recreate the pool from the saved data
@@ -243,7 +250,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
* @param {object} questions H5P content types to be created as instances
* @return {array} Array of questions instances
*/
- var createQuestionInstancesFromQuestions = function(questions) {
+ var createQuestionInstancesFromQuestions = function (questions) {
var result = [];
// Create question instances from questions
// Instantiate question instances
@@ -265,9 +272,6 @@ H5P.QuestionSet = function (options, contentId, contentData) {
}
question.params = question.params || {};
- question.params.overrideSettings = question.params.overrideSettings || {};
- question.params.overrideSettings.$confirmationDialogParent = $template.last();
- question.params.overrideSettings.instance = this;
var hasAnswers = contentData.previousState && contentData.previousState.answers;
var questionInstance = H5P.newRunnable(question, contentId, undefined, undefined,
{
@@ -282,7 +286,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
}
return result;
- }
+ };
// Create question instances from questions given by params
questionInstances = createQuestionInstancesFromQuestions(params.questions);
@@ -311,8 +315,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var _updateButtons = function () {
// Verify that current question is answered when backward nav is disabled
if (params.disableBackwardsNavigation) {
- if (questionInstances[currentQuestion].getAnswerGiven()
- && questionInstances.length-1 !== currentQuestion) {
+ if (questionInstances[currentQuestion].getAnswerGiven() &&
+ questionInstances.length-1 !== currentQuestion) {
questionInstances[currentQuestion].showButton('next');
}
else {
@@ -353,6 +357,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
currentQuestion = questionNumber;
+ handleAutoPlay(currentQuestion);
+
// Hide all questions
$('.question-container', $myDom).hide().eq(questionNumber).show();
@@ -403,6 +409,31 @@ H5P.QuestionSet = function (options, contentId, contentData) {
return currentQuestion;
};
+ /**
+ * Handle autoplays, limit to one at a time
+ *
+ * @param {number} currentQuestionIndex
+ */
+ var handleAutoPlay = function (currentQuestionIndex) {
+ for (var i = 0; i < questionInstances.length; i++) {
+ questionInstances[i].pause();
+ }
+
+ var currentQuestion = params.questions[currentQuestionIndex];
+
+ var hasAutoPlay = currentQuestion &&
+ currentQuestion.params.media &&
+ currentQuestion.params.media.params &&
+ currentQuestion.params.media.params.playback &&
+ currentQuestion.params.media.params.playback.autoplay;
+
+ if (hasAutoPlay && typeof questionInstances[currentQuestionIndex].play === 'function') {
+ questionInstances[currentQuestionIndex].play();
+ }
+ };
+
+
+
/**
* Show solutions for subcontent, and hide subcontent buttons.
* Used for contracts with integrated content.
@@ -496,7 +527,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
//Force the last page to be reRendered
rendered = false;
- if(params.poolSize > 0){
+ if (params.poolSize > 0) {
// Make new pool from params.questions
// Randomize and get the results
@@ -549,7 +580,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var replaceQuestionsInDOM = function (questionInstances) {
// Find all question containers and detach questions from them
- $('.question-container', $myDom).each(function (){
+ $('.question-container', $myDom).each(function () {
$(this).children().detach();
});
@@ -564,19 +595,19 @@ H5P.QuestionSet = function (options, contentId, contentData) {
question.attach($('.question-container:eq(' + i + ')', $myDom));
//Show buttons if necessary
- if(questionInstances[questionInstances.length -1] === question
- && question.hasButton('finish')) {
+ if (questionInstances[questionInstances.length -1] === question &&
+ question.hasButton('finish')) {
question.showButton('finish');
}
- if(questionInstances[questionInstances.length -1] !== question
- && question.hasButton('next')) {
+ if (questionInstances[questionInstances.length -1] !== question &&
+ question.hasButton('next')) {
question.showButton('next');
}
- if(questionInstances[0] !== question
- && question.hasButton('prev')
- && !params.disableBackwardsNavigation) {
+ if (questionInstances[0] !== question &&
+ question.hasButton('prev') &&
+ !params.disableBackwardsNavigation) {
question.showButton('prev');
}
@@ -617,7 +648,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
* @param {number} dotIndex Index of dot
* @param {boolean} isAnswered True if is answered, False if not answered
*/
- var toggleAnsweredDot = function(dotIndex, isAnswered) {
+ var toggleAnsweredDot = function (dotIndex, isAnswered) {
var $el = $('.progress-dot:eq(' + dotIndex +')', $myDom);
// Skip current button
@@ -679,12 +710,9 @@ H5P.QuestionSet = function (options, contentId, contentData) {
// Get total score.
var finals = self.getScore();
var totals = self.getMaxScore();
- var scoreString = params.endGame.scoreString.replace("@score", finals).replace("@total", totals);
+
+ var scoreString = H5P.Question.determineOverallFeedback(params.endGame.overallFeedback, finals / totals).replace('@score', finals).replace('@total', totals);
var success = ((100 * finals / totals) >= params.passPercentage);
- var eventData = {
- score: scoreString,
- passed: success
- };
/**
* Makes our buttons behave like other buttons.
@@ -707,8 +735,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
var eparams = {
message: params.endGame.showResultPage ? params.endGame.message : params.endGame.noResultMessage,
- comment: params.endGame.showResultPage ? (success ? params.endGame.successGreeting : params.endGame.failGreeting) : undefined,
- resulttext: params.endGame.showResultPage ? (success ? params.endGame.successComment : params.endGame.failComment) : undefined,
+ comment: params.endGame.showResultPage ? (success ? params.endGame.oldFeedback.successGreeting : params.endGame.oldFeedback.failGreeting) : undefined,
+ resulttext: params.endGame.showResultPage ? (success ? params.endGame.oldFeedback.successComment : params.endGame.oldFeedback.failComment) : undefined,
finishButtonText: params.endGame.finishButtonText,
solutionButtonText: params.endGame.solutionButtonText,
retryButtonText: params.endGame.retryButtonText
@@ -719,10 +747,6 @@ H5P.QuestionSet = function (options, contentId, contentData) {
$myDom.append(endTemplate.render(eparams));
if (params.endGame.showResultPage) {
- // Add event handlers to summary buttons
- hookUpButton('.qs-finishbutton', function () {
- self.trigger('h5pQuestionSetFinished', eventData);
- });
hookUpButton('.qs-solutionbutton', function () {
showSolutions();
$myDom.children().hide().filter('.questionset').show();
@@ -852,7 +876,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
});
// Hide next button if it is the last question
- if(questionInstances[questionInstances.length -1] === question) {
+ if (questionInstances[questionInstances.length -1] === question) {
question.hideButton('next');
}
@@ -1080,10 +1104,10 @@ H5P.QuestionSet = function (options, contentId, contentData) {
return info;
};
- this.getQuestions = function() {
+ this.getQuestions = function () {
return questionInstances;
};
- this.showSolutions = function() {
+ this.showSolutions = function () {
renderSolutions = true;
};
@@ -1141,7 +1165,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
/**
* Add the question itself to the definition part of an xAPIEvent
*/
- var addQuestionToXAPI = function(xAPIEvent) {
+ var addQuestionToXAPI = function (xAPIEvent) {
var definition = xAPIEvent.getVerifiedStatementValue(['object', 'definition']);
$.extend(definition, getxAPIDefinition());
};
@@ -1152,8 +1176,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
* @param {Object} metaContentType
* @returns {array}
*/
- var getXAPIDataFromChildren = function(metaContentType) {
- return metaContentType.getQuestions().map(function(question) {
+ var getXAPIDataFromChildren = function (metaContentType) {
+ return metaContentType.getQuestions().map(function (question) {
return question.getXAPIData();
});
};
@@ -1164,7 +1188,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
*
* @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6}
*/
- this.getXAPIData = function(){
+ this.getXAPIData = function () {
var xAPIEvent = this.createXAPIEventTemplate('answered');
addQuestionToXAPI(xAPIEvent);
xAPIEvent.setScoredResult(this.getScore(),
@@ -1176,7 +1200,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
return {
statement: xAPIEvent.data.statement,
children: getXAPIDataFromChildren(this)
- }
+ };
};
};
diff --git a/language/.en.json b/language/.en.json
new file mode 100644
index 0000000..5dbdf69
--- /dev/null
+++ b/language/.en.json
@@ -0,0 +1,251 @@
+{
+ "semantics": [
+ {
+ "label": "Quiz introduction",
+ "fields": [
+ {
+ "label": "Display introduction"
+ },
+ {
+ "label": "Title",
+ "description": "This title will be displayed above the introduction text."
+ },
+ {
+ "label": "Introduction text",
+ "description": "This text will be displayed before the quiz starts."
+ },
+ {
+ "label": "Start button text",
+ "default": "Start Quiz"
+ },
+ {
+ "label": "Background image",
+ "description": "An optional background image for the introduction."
+ }
+ ]
+ },
+ {
+ "label": "Background image",
+ "description": "An optional background image for the Question set."
+ },
+ {
+ "label": "Progress indicator",
+ "description": "Question set progress indicator style.",
+ "options": [
+ {
+ "label": "Textual"
+ },
+ {
+ "label": "Dots"
+ }
+ ],
+ "default": "dots"
+ },
+ {
+ "label": "Pass percentage",
+ "description": "Percentage of Total score required for passing the quiz."
+ },
+ {
+ "label": "Questions",
+ "widgets": [
+ {
+ "label": "Default"
+ },
+ {
+ "label": "Textual"
+ }
+ ],
+ "entity": "question",
+ "field": {
+ "label": "Question type",
+ "description": "Library for this question."
+ }
+ },
+ {
+ "label": "Interface texts in quiz",
+ "fields": [
+ {
+ "label": "Back button",
+ "default": "Previous question"
+ },
+ {
+ "label": "Next button",
+ "default": "Next question"
+ },
+ {
+ "label": "Finish button",
+ "default": "Finish"
+ },
+ {
+ "label": "Progress text",
+ "description": "Text used if textual progress is selected.",
+ "default": "Question: @current of @total questions"
+ },
+ {
+ "label": "Label for jumping to a certain question",
+ "description": "You must use the placeholder '%d' instead of the question number, and %total instead of total amount of questions.",
+ "default": "Question %d of %total"
+ },
+ {
+ "label": "Copyright dialog question label",
+ "default": "Question"
+ },
+ {
+ "label": "Readspeaker progress",
+ "description": "May use @current and @total question variables",
+ "default": "Question @current of @total"
+ },
+ {
+ "label": "Unanswered question text",
+ "default": "Unanswered"
+ },
+ {
+ "label": "Answered question text",
+ "default": "Answered"
+ },
+ {
+ "label": "Current question text",
+ "default": "Current question"
+ }
+ ]
+ },
+ {
+ "label": "Disable backwards navigation",
+ "description": "This option will only allow you to move forward in Question Set"
+ },
+ {
+ "label": "Randomize questions",
+ "description": "Enable to randomize the order of questions on display."
+ },
+ {
+ "label": "Number of questions to be shown:",
+ "description": "Create a randomized batch of questions from the total."
+ },
+ {
+ "label": "Quiz finished",
+ "fields": [
+ {
+ "label": "Display results"
+ },
+ {
+ "label": "Display solution button"
+ },
+ {
+ "label": "No results message",
+ "description": "Text displayed on end page when \"Display results\" is disabled",
+ "default": "Finished"
+ },
+ {
+ "label": "Feedback heading",
+ "default": "Your result:",
+ "description": "This heading will be displayed at the end of the quiz when the user has answered all questions."
+ },
+ {
+ "label": "Overall Feedback",
+ "fields": [
+ {
+ "widgets": [],
+ "label": "Define custom feedback for any score range",
+ "description": "Example: 0-20% Bad score, 21-91% Average Score, 91-100% Great Score!",
+ "entity": "range",
+ "field": {
+ "fields": [
+ {
+ "label": "Score Range"
+ },
+ {},
+ {
+ "label": "Feedback for defined score range",
+ "placeholder": "Fill in the feedback"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "label": "Old Feedback",
+ "fields": [
+ {
+ "label": "Quiz passed greeting",
+ "description": "This text will be displayed above the score if the user has successfully passed the quiz."
+ },
+ {
+ "label": "Passed comment",
+ "description": "This comment will be displayed after the score if the user has successfully passed the quiz."
+ },
+ {
+ "label": "Quiz failed title",
+ "description": "This text will be displayed above the score if the user has failed the quiz."
+ },
+ {
+ "label": "Failed comment",
+ "description": "This comment will be displayed after the score if the user has failed the quiz."
+ }
+ ]
+ },
+ {
+ "label": "Solution button label",
+ "default": "Show solution",
+ "description": "Text for the solution button."
+ },
+ {
+ "label": "Retry button label",
+ "default": "Retry",
+ "description": "Text for the retry button."
+ },
+ {
+ "label": "Finish button text",
+ "default": "Finish"
+ },
+ {
+ "label": "Display video before quiz results"
+ },
+ {
+ "label": "Enable skip video button"
+ },
+ {
+ "label": "Skip video button label",
+ "default": "Skip video"
+ },
+ {
+ "label": "Passed video",
+ "description": "This video will be played if the user successfully passed the quiz."
+ },
+ {
+ "label": "Fail video",
+ "description": "This video will be played if the user failes the quiz."
+ }
+ ]
+ },
+ {
+ "label": "Settings for \"Show solution\" and \"Retry\" buttons",
+ "fields": [
+ {
+ "label": "Override \"Show Solution\" button",
+ "description": "This option determines if the \"Show Solution\" button will be shown for all questions, disabled for all or configured for each question individually.",
+ "options": [
+ {
+ "label": "Enabled"
+ },
+ {
+ "label": "Disabled"
+ }
+ ]
+ },
+ {
+ "label": "Override \"Retry\" button",
+ "description": "This option determines if the \"Retry\" button will be shown for all questions, disabled for all or configured for each question individually.",
+ "options": [
+ {
+ "label": "Enabled"
+ },
+ {
+ "label": "Disabled"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/language/ar.json b/language/ar.json
index 838ccf7..e8b0509 100644
--- a/language/ar.json
+++ b/language/ar.json
@@ -121,6 +121,9 @@
{
"label": "عرض النتائج"
},
+ {
+ "label": "Display solution button"
+ },
{
"label": "No results message",
"description": "Text displayed on end page when \"Display results\" is disabled",
@@ -210,4 +213,4 @@
]
}
]
-}
+}
\ No newline at end of file
diff --git a/language/bs.json b/language/bs.json
new file mode 100644
index 0000000..c92f10e
--- /dev/null
+++ b/language/bs.json
@@ -0,0 +1,229 @@
+{
+ "semantics": [
+ {
+ "label": "Uvod u kviz",
+ "fields": [
+ {
+ "label": "Prikaži uvod"
+ },
+ {
+ "label": "Naziv",
+ "description": "Ovaj će naziv biti prikazan iznad uvodnog teksta."
+ },
+ {
+ "label": "Tekst uvoda",
+ "description": "Ovaj će naziv biti prikazan prije početka kviza."
+ },
+ {
+ "label": "Oznaka za dugme \"Start\"",
+ "default": "Start"
+ },
+ {
+ "label": "Slika pozadine",
+ "description": "Slika pozadine na početku. (opcionalno)."
+ }
+ ]
+ },
+ {
+ "label": "Slika pozadine",
+ "description": "Slika pozadine seta pitanja. (opcionalno)."
+ },
+ {
+ "label": "Prikaz napredovanja",
+ "description": "Prikazivanje napredovanja",
+ "options": [
+ {
+ "label": "Tekst"
+ },
+ {
+ "label": "Bodovi"
+ }
+ ]
+ },
+ {
+ "label": "Minimalno procenata za prolaz",
+ "description": "Minimalno osvojenih procenata da bi se kviz smatrao uspješno prođenim."
+ },
+ {
+ "label": "Pitanja",
+ "widgets": [
+ {
+ "label": "Standard"
+ },
+ {
+ "label": "Tekst"
+ }
+ ],
+ "entity": "Pitanje",
+ "field": {
+ "label": "Vrsta pitanja",
+ "description": "Biblioteka za ovo pitanje."
+ }
+ },
+ {
+ "label": "Prikaz teksta u kvizu",
+ "fields": [
+ {
+ "label": "Oznaka za dugme \"Nazad\"",
+ "default": "Zurück"
+ },
+ {
+ "label": "Oznaka za dugme \"Naprijed\"",
+ "default": "Weiter"
+ },
+ {
+ "label": "Oznaka za dugme \"Završi\"",
+ "default": "Završi"
+ },
+ {
+ "label": "Tekst o napredovanju",
+ "description": "Koristi tekst ako je izabran za napredak u pisanom obliku.",
+ "default": "Aktuelno pitanje: @current od @total pitanja"
+ },
+ {
+ "label": "Označavanje za skakanje do određene tačke",
+ "description": "Koristi mjesto '%d' za redoslijed pitanja i %total za ukupan broj pitanja.",
+ "default": "Pitanje %d od %total"
+ },
+ {
+ "label": "Opis pitanja u vezi sa vezi s autorom",
+ "default": "Pitanje"
+ },
+ {
+ "label": "Napredno \"Readspeaker\"",
+ "description": "Varijable: @current i @total",
+ "default": "Pitanje @current od @total"
+ },
+ {
+ "label": "Tekst za neodgovorena pitanja",
+ "default": "Neodgovoreno"
+ },
+ {
+ "label": "Tekst za odgovorena pitanja",
+ "default": "Odgovoreno"
+ },
+ {
+ "label": "Tekst za trenutno pitanja",
+ "default": "Trenutno pitanje"
+ }
+ ]
+ },
+ {
+ "label": "Deaktivirati mogućnost povratka unazad",
+ "description": "Ako je aktivirano, korisnik će moći ići samo naprijed u odgovaranju na pitanja."
+ },
+ {
+ "label": "Izmješati pitanja",
+ "description": "Ako je aktivirano, pitanja će kod svakog učitavanja kviza imati drugi raspored."
+ },
+ {
+ "label": "Broj pitanja za prikaz:",
+ "description": "Može se koristiti kod odabira slučajnog pitanja."
+ },
+ {
+ "label": "Završi kviz",
+ "fields": [
+ {
+ "label": "Prikaz rezultata"
+ },
+ {
+ "label": "Napomena ako nema rezultata",
+ "description": "Tekst koji će biti prikazan u slučaju da je \"Prikaz rezultata\" deaktiviran",
+ "default": "Završi"
+ },
+ {
+ "label": "Oznaka za povratne informacije",
+ "default": "Tvoj rezultat:",
+ "description": "Ovaj tekst će biti prikazan na kraju kviza kada korisnik odgovori na pitanja."
+ },
+ {
+ "label": "Tekst za prikaz broj odova",
+ "description": "Ovaj tekst će se koristiti da prikaže ukupan broj bodova korisnika. \"@score\" će biti zamjenjen sa osvojenim bodovima, \"@total\" će biti zamjenjeno sa maksimalnim brojem bodova.",
+ "default": "Osvojeno @score bodova od @total mogućih."
+ },
+ {
+ "label": "Oznaka za \"Kviz položen\"",
+ "placeholder": "BRAVO!",
+ "default": "BRAVO!",
+ "description": "Ovaj tekst će biti prikazan iznad broja bodova kada je korisnik uspješno završio kviz."
+ },
+ {
+ "label": "Komentar za uspješno završen kviz",
+ "default": "Nije loše!",
+ "description": "Ovaj tekst će biti prikazan iznad broja bodova kada je korisnik uspješno završio kviz."
+ },
+ {
+ "label": "Oznaka kod neuspješnog završetka kviza",
+ "default": "Ovoga puta nije dovoljno dobro.",
+ "description": "Ovaj tekst će biti prikazan iznad broja bodova kada je korisnik nije uspješno završio kviz."
+ },
+ {
+ "label": "Oznaka kod neuspješnog završetka kviza",
+ "default": "Pokušaj još jednom!",
+ "description": "Ovaj komentar će se pokazati nakon što korisnik nije sakupio dovoljan broj bodova za uspješan završetak kviza."
+ },
+ {
+ "label": "Oznaka za dugme \"Prikaži rješenje\"",
+ "default": "Prikaži rješenje",
+ "description": "Oznaka za dugme \"Prikaži rješenje\""
+ },
+ {
+ "label": "Oznaka za dugme \"Ponovi\"",
+ "default": "Ponovi",
+ "description": "Oznaka za dugme \"Ponovi\""
+ },
+ {
+ "label": "Oznaka za dugme \"Završi\"",
+ "default": "Završi"
+ },
+ {
+ "label": "Prikaži video prije rezultata kviza"
+ },
+ {
+ "label": "Aktiviraj dugme \"Preskoči vidio\""
+ },
+ {
+ "label": "Oznaka za dugme \"Preskoči video\"",
+ "default": "Preskoči video"
+ },
+ {
+ "label": "Video nakon položenog kviza",
+ "description": "Ovaj video se prikazuje nakon što korisnik uspješno položi kviz."
+ },
+ {
+ "label": "Video nakon nepoloženog kviza",
+ "description": "Ovaj video se prikazuje nakon što korisnik neuspješno završi kviz."
+ }
+ ]
+ },
+ {
+ "label": "Podešavanje dugmeta \"Prikaži rješenje\" i \"Ponovi\".",
+ "fields": [
+ {
+ "label": "Poništi dugme \"Prikaži rješenje\"",
+ "description": "Ova opcija podešava prikazivanje dugmeta \"Prikaži rješenje\" za sva pitanja ili da bude za svako posebno pitanje konfigurirano.",
+ "options": [
+ {
+ "label": "Prikaži"
+ },
+ {
+ "label": "Nemoj prikazati"
+ }
+ ]
+ },
+ {
+ "label": "Poništi dugme \"Ponovi\"",
+ "description": "Ova opcija podešava prikazivanje dugmeta \"Ponovi\" za sva pitanja ili da bude za svako posebno pitanje konfigurirano.",
+ "options": [
+ {
+ "label": "Prikaži"
+ },
+ {
+ "label": "Nemoj prikazati"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/language/da.json b/language/da.json
new file mode 100644
index 0000000..c629729
--- /dev/null
+++ b/language/da.json
@@ -0,0 +1,255 @@
+{
+ "semantics":[
+ {
+ "label":"Quiz introduction",
+ "fields":[
+ {
+ "label":"Display introduction"
+ },
+ {
+ "label":"Title",
+ "description":"This title will be displayed above the introduction text."
+ },
+ {
+ "label":"Introduction text",
+ "description":"This text will be displayed before the quiz starts."
+ },
+ {
+ "label":"Start button text",
+ "default":"Start Quiz"
+ },
+ {
+ "label":"Background image",
+ "description":"An optional background image for the introduction."
+ }
+ ]
+ },
+ {
+ "label":"Background image",
+ "description":"An optional background image for the Question set."
+ },
+ {
+ "label":"Progress indicator",
+ "description":"Question set progress indicator style.",
+ "options":[
+ {
+ "label":"Textual"
+ },
+ {
+ "label":"Dots"
+ }
+ ],
+ "default":"dots"
+ },
+ {
+ "label":"Pass percentage",
+ "description":"Percentage of Total score required for passing the quiz."
+ },
+ {
+ "label":"Questions",
+ "widgets":[
+ {
+ "label":"Default"
+ },
+ {
+ "label":"Textual"
+ }
+ ],
+ "entity":"question",
+ "field":{
+ "label":"Question type",
+ "description":"Library for this question."
+ }
+ },
+ {
+ "label":"Interface texts in quiz",
+ "fields":[
+ {
+ "label":"Back button",
+ "default":"Forrige spørgsmål"
+ },
+ {
+ "label":"Next button",
+ "default":"Næste spørgsmål"
+ },
+ {
+ "label":"Finish button",
+ "default":"Færdig"
+ },
+ {
+ "label":"Progress text",
+ "description":"Text used if textual progress is selected.",
+ "default":"Spørgsmål:nummer @current ud af @spørgsmål"
+ },
+ {
+ "label":"Label for jumping to a certain question",
+ "description":"You must use the placeholder '%d' instead of the question number, and %total instead of total amount of questions.",
+ "default":"Spørgsmål %d ud af %total"
+ },
+ {
+ "label":"Copyright dialog question label",
+ "default":"Spørgsmål"
+ },
+ {
+ "label":"Readspeaker progress",
+ "description":"May use @current and @total question variables",
+ "default":"Spørgsmål @current ud af @total"
+ },
+ {
+ "label":"Unanswered question text",
+ "default":"Ubesvaret"
+ },
+ {
+ "label":"Answered question text",
+ "default":"Besvaret"
+ },
+ {
+ "label":"Current question text",
+ "default":"Aktuel spørgsmål"
+ }
+ ]
+ },
+ {
+ "label":"Disable backwards navigation",
+ "description":"This option will only allow you to move forward in Question Set"
+ },
+ {
+ "label":"Randomize questions",
+ "description":"Enable to randomize the order of questions on display."
+ },
+ {
+ "label":"Number of questions to be shown:",
+ "description":"Create a randomized batch of questions from the total."
+ },
+ {
+ "label":"Quiz finished",
+ "fields":[
+ {
+ "label":"Display results"
+ },
+ {
+ "label":"Display solution button"
+ },
+ {
+ "label":"No results message",
+ "description":"Text displayed on end page when \"Display results\" is disabled",
+ "default":"Finished"
+ },
+ {
+ "label":"Feedback heading",
+ "default":"Your result:",
+ "description":"This heading will be displayed at the end of the quiz when the user has answered all questions."
+ },
+ {
+ "label":"Overall Feedback",
+ "fields":[
+ {
+ "widgets":[
+
+ ],
+ "label":"Define custom feedback for any score range",
+ "description":"Example: 0-20% Bad score, 21-91% Average Score, 91-100% Great Score!",
+ "entity":"range",
+ "field":{
+ "fields":[
+ {
+ "label":"Score Range"
+ },
+ {
+
+ },
+ {
+ "label":"Feedback for defined score range",
+ "placeholder":"Fill in the feedback"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "label":"Old Feedback",
+ "fields":[
+ {
+ "label":"Quiz passed greeting",
+ "description":"This text will be displayed above the score if the user has successfully passed the quiz."
+ },
+ {
+ "label":"Passed comment",
+ "description":"This comment will be displayed after the score if the user has successfully passed the quiz."
+ },
+ {
+ "label":"Quiz failed title",
+ "description":"This text will be displayed above the score if the user has failed the quiz."
+ },
+ {
+ "label":"Failed comment",
+ "description":"This comment will be displayed after the score if the user has failed the quiz."
+ }
+ ]
+ },
+ {
+ "label":"Solution button label",
+ "default":"Show solution",
+ "description":"Text for the solution button."
+ },
+ {
+ "label":"Retry button label",
+ "default":"Retry",
+ "description":"Text for the retry button."
+ },
+ {
+ "label":"Finish button text",
+ "default":"Finish"
+ },
+ {
+ "label":"Display video before quiz results"
+ },
+ {
+ "label":"Enable skip video button"
+ },
+ {
+ "label":"Skip video button label",
+ "default":"Skip video"
+ },
+ {
+ "label":"Passed video",
+ "description":"This video will be played if the user successfully passed the quiz."
+ },
+ {
+ "label":"Fail video",
+ "description":"This video will be played if the user failes the quiz."
+ }
+ ]
+ },
+ {
+ "label":"Settings for \"Show solution\" and \"Retry\" buttons",
+ "fields":[
+ {
+ "label":"Override \"Show Solution\" button",
+ "description":"This option determines if the \"Show Solution\" button will be shown for all questions, disabled for all or configured for each question individually.",
+ "options":[
+ {
+ "label":"Enabled"
+ },
+ {
+ "label":"Disabled"
+ }
+ ]
+ },
+ {
+ "label":"Override \"Retry\" button",
+ "description":"This option determines if the \"Retry\" button will be shown for all questions, disabled for all or configured for each question individually.",
+ "options":[
+ {
+ "label":"Enabled"
+ },
+ {
+ "label":"Disabled"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/language/de.json b/language/de.json
index 1713d8b..8c8542e 100644
--- a/language/de.json
+++ b/language/de.json
@@ -103,7 +103,7 @@
"default": "Beantwortet"
},
{
- "label": "Text fpr aktuelle Frage",
+ "label": "Text für aktuelle Frage",
"default": "Aktuelle Frage"
}
]
@@ -154,7 +154,7 @@
},
{
"label": "Kopfzeile für nicht bestandenes Quiz",
- "default": "Diese Mal hast du nicht bestanden.",
+ "default": "Dieses Mal hast du nicht bestanden.",
"description": "Dieser Text wird oberhalb der Punkte angezeigt, wenn der Nutzer das Quiz nicht bestanden hat."
},
{
diff --git a/language/fr.json b/language/fr.json
index dc445fa..25d6038 100644
--- a/language/fr.json
+++ b/language/fr.json
@@ -126,6 +126,9 @@
{
"label": "Afficher les résultats"
},
+ {
+ "label": "Display solution button"
+ },
{
"label": "Message si pas de résultats",
"description": "Texte affiché sur la page finale si l'option \"Afficher les résultats\" est désactivée.",
@@ -226,4 +229,4 @@
]
}
]
-}
+}
\ No newline at end of file
diff --git a/language/it.json b/language/it.json
index d520b11..7b7a5b5 100644
--- a/language/it.json
+++ b/language/it.json
@@ -121,6 +121,9 @@
{
"label": "Visualizza risultati"
},
+ {
+ "label": "Display solution button"
+ },
{
"label": "No results message",
"description": "Text displayed on end page when \"Display results\" is disabled",
@@ -210,4 +213,4 @@
]
}
]
-}
+}
\ No newline at end of file
diff --git a/language/nb.json b/language/nb.json
index 4c2aa48..650641d 100644
--- a/language/nb.json
+++ b/language/nb.json
@@ -126,6 +126,9 @@
{
"label": "Vis resultater"
},
+ {
+ "label": "Vis resultatknapp"
+ },
{
"label": "Melding når resultater ikke vises",
"description": "Teksten vises på avslutnings-siden når resultater ikke vises",
@@ -225,4 +228,4 @@
]
}
]
-}
+}
\ No newline at end of file
diff --git a/language/nn.json b/language/nn.json
index 33507d1..54a5a25 100644
--- a/language/nn.json
+++ b/language/nn.json
@@ -126,6 +126,9 @@
{
"label": "Vis resultat"
},
+ {
+ "label": "Vis resultatknapp"
+ },
{
"label": "Melding når resultater ikke vises",
"description": "Teksten vises på avslutnings-siden når resultater ikke vises",
@@ -225,4 +228,4 @@
]
}
]
-}
+}
\ No newline at end of file
diff --git a/library.json b/library.json
index dcb9339..0c46467 100644
--- a/library.json
+++ b/library.json
@@ -3,8 +3,8 @@
"description": "Put together a set of different questions that has to be solved. (Quiz)",
"contentType": "question",
"majorVersion": 1,
- "minorVersion": 12,
- "patchVersion": 1,
+ "minorVersion": 13,
+ "patchVersion": 0,
"embedTypes": [
"iframe"
],
@@ -14,7 +14,7 @@
"author": "Joubel",
"coreApi": {
"majorVersion": 1,
- "minorVersion": 6
+ "minorVersion": 14
},
"license": "MIT",
"preloadedJs": [
@@ -50,6 +50,11 @@
}
],
"editorDependencies": [
+ {
+ "machineName": "H5PEditor.RangeList",
+ "majorVersion": 1,
+ "minorVersion": 0
+ },
{
"machineName": "H5PEditor.VerticalTabs",
"majorVersion": 1,
@@ -61,4 +66,4 @@
"minorVersion": 2
}
]
-}
\ No newline at end of file
+}
diff --git a/semantics.json b/semantics.json
index a501305..733e68e 100644
--- a/semantics.json
+++ b/semantics.json
@@ -121,11 +121,11 @@
"importance": "high",
"description": "Library for this question.",
"options": [
- "H5P.MultiChoice 1.9",
- "H5P.DragQuestion 1.9",
- "H5P.Blanks 1.7",
- "H5P.MarkTheWords 1.6",
- "H5P.DragText 1.5",
+ "H5P.MultiChoice 1.10",
+ "H5P.DragQuestion 1.11",
+ "H5P.Blanks 1.8",
+ "H5P.MarkTheWords 1.7",
+ "H5P.DragText 1.6",
"H5P.TrueFalse 1.1"
]
}
@@ -255,6 +255,12 @@
"importance": "low",
"default": true
},
+ {
+ "name": "showSolutionButton",
+ "type": "boolean",
+ "label": "Display solution button",
+ "default": true
+ },
{
"name": "noResultMessage",
"type": "text",
@@ -270,7 +276,6 @@
"label": "Feedback heading",
"importance": "low",
"default": "Your result:",
- "optional": true,
"description": "This heading will be displayed at the end of the quiz when the user has answered all questions.",
"tags": [
"strong",
@@ -278,75 +283,127 @@
]
},
{
- "name": "scoreString",
- "type": "text",
- "label": "Score display text",
+ "name": "overallFeedback",
+ "type": "group",
+ "label": "Overall Feedback",
"importance": "low",
- "description": "Text used to display Total user score. \"@score\" will be replaced by calculated score, \"@total\" will be replaced by maximum possible score. ",
- "default": "You got @score of @total points",
- "optional": true
- },
- {
- "name": "successGreeting",
- "type": "text",
- "label": "Quiz passed greeting",
- "importance": "low",
- "placeholder": "Congratulations!",
- "default": "Congratulations!",
- "optional": true,
- "description": "This text will be displayed above the score if the user has successfully passed the quiz.",
- "tags": [
- "strong",
- "em"
+ "fields": [
+ {
+ "name": "overallFeedback",
+ "type": "list",
+ "widgets": [
+ {
+ "name": "RangeList",
+ "label": "Default"
+ }
+ ],
+ "importance": "high",
+ "label": "Define custom feedback for any score range",
+ "description": "Example: 0-20% Bad score, 21-91% Average Score, 91-100% Great Score!",
+ "entity": "range",
+ "min": 1,
+ "defaultNum": 1,
+ "optional": true,
+ "field": {
+ "name": "overallFeedback",
+ "type": "group",
+ "importance": "low",
+ "fields": [
+ {
+ "name": "from",
+ "type": "number",
+ "label": "Score Range",
+ "min": 0,
+ "max": 100,
+ "default": 0,
+ "unit": "%"
+ },
+ {
+ "name": "to",
+ "type": "number",
+ "min": 0,
+ "max": 100,
+ "default": 100,
+ "unit": "%"
+ },
+ {
+ "name": "feedback",
+ "type": "text",
+ "label": "Feedback for defined score range",
+ "importance": "low",
+ "placeholder": "Fill in the feedback",
+ "optional": true
+ }
+ ]
+ }
+ }
]
},
{
- "name": "successComment",
- "type": "text",
- "widget": "html",
- "label": "Passed comment",
+ "name": "oldFeedback",
+ "type": "group",
+ "label": "Old Feedback",
"importance": "low",
- "default": "You did very well!",
- "optional": true,
- "description": "This comment will be displayed after the score if the user has successfully passed the quiz.",
- "tags": [
- "sub",
- "sup",
- "strong",
- "em",
- "a",
- "p"
- ]
- },
- {
- "name": "failGreeting",
- "type": "text",
- "label": "Quiz failed title",
- "importance": "low",
- "default": "You did not pass this time.",
- "optional": true,
- "description": "This text will be displayed above the score if the user has failed the quiz.",
- "tags": [
- "strong",
- "em"
- ]
- },
- {
- "name": "failComment",
- "type": "text",
- "widget": "html",
- "label": "Failed comment",
- "importance": "low",
- "default": "Have another try!",
- "optional": true,
- "description": "This comment will be displayed after the score if the user has failed the quiz.",
- "tags": [
- "sub",
- "sup",
- "strong",
- "em",
- "a",
- "p"
+ "deprecated": true,
+ "fields": [
+ {
+ "name": "successGreeting",
+ "type": "text",
+ "label": "Quiz passed greeting",
+ "importance": "low",
+ "optional": true,
+ "description": "This text will be displayed above the score if the user has successfully passed the quiz.",
+ "tags": [
+ "strong",
+ "em"
+ ]
+ },
+ {
+ "name": "successComment",
+ "type": "text",
+ "widget": "html",
+ "label": "Passed comment",
+ "importance": "low",
+ "optional": true,
+ "description": "This comment will be displayed after the score if the user has successfully passed the quiz.",
+ "tags": [
+ "sub",
+ "sup",
+ "strong",
+ "em",
+ "a",
+ "p"
+ ]
+ },
+ {
+ "name": "failGreeting",
+ "type": "text",
+ "label": "Quiz failed title",
+ "importance": "low",
+ "optional": true,
+ "description": "This text will be displayed above the score if the user has failed the quiz.",
+ "tags": [
+ "strong",
+ "em"
+ ]
+ },
+ {
+ "name": "failComment",
+ "type": "text",
+ "widget": "html",
+ "label": "Failed comment",
+ "importance": "low",
+ "optional": true,
+ "description": "This comment will be displayed after the score if the user has failed the quiz.",
+ "tags": [
+ "sub",
+ "sup",
+ "strong",
+ "em",
+ "a",
+ "p"
+ ]
+ }
]
},
{
@@ -454,4 +511,4 @@
}
]
}
-]
\ No newline at end of file
+]
diff --git a/upgrades.js b/upgrades.js
index dc41328..7829f31 100644
--- a/upgrades.js
+++ b/upgrades.js
@@ -52,6 +52,52 @@ H5PUpgrades['H5P.QuestionSet'] = (function ($) {
// Remove old copyright dialog question label
delete parameters.questionLabel;
+ finished(null, parameters);
+ },
+
+ /**
+ * Asynchronous content upgrade hook.
+ *
+ * Upgrade params to support overall feedback
+ *
+ * @param {Object} parameters
+ * @param {function} finished
+ */
+ 13: function (parameters, finished) {
+
+ parameters.endGame = parameters.endGame || {};
+ parameters.endGame.overallFeedback = [];
+
+ if (parameters.endGame.scoreString) {
+ parameters.endGame.overallFeedback.push({
+ from: 0,
+ to: 100,
+ feedback: parameters.endGame.scoreString
+ });
+
+ delete parameters.endGame.scoreString;
+ }
+
+ // Group old feedback fields
+ if (parameters.endGame.successGreeting ||
+ parameters.endGame.successComment ||
+ parameters.endGame.failGreeting ||
+ parameters.endGame.failComment) {
+ parameters.endGame.oldFeedback = {};
+ if (parameters.endGame.successGreeting) {
+ parameters.endGame.oldFeedback.successGreeting = parameters.endGame.successGreeting;
+ }
+ if (parameters.endGame.successComment) {
+ parameters.endGame.oldFeedback.successComment = parameters.endGame.successComment;
+ }
+ if (parameters.endGame.failGreeting) {
+ parameters.endGame.oldFeedback.failGreeting = parameters.endGame.failGreeting;
+ }
+ if (parameters.endGame.failComment) {
+ parameters.endGame.oldFeedback.failComment = parameters.endGame.failComment;
+ }
+ }
+
finished(null, parameters);
}
}