Merge branch 'HFP-1174-overall-feedback'
commit
f89204789c
|
@ -225,30 +225,27 @@
|
||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.questionset-results .feedback-section .feedback-text {
|
|
||||||
font-weight: normal;
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
.questionset-results .buttons {
|
.questionset-results .buttons {
|
||||||
margin-bottom: 1.5em;
|
margin: 2em 0 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.questionset-results .result-header,
|
.questionset-results .result-header,
|
||||||
.questionset-results .result-text {
|
.questionset-results .result-text,
|
||||||
|
.questionset-results .feedback-section .feedback-text {
|
||||||
color: #1a73d9;
|
color: #1a73d9;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.questionset-results .result-header {
|
.questionset-results .result-header {
|
||||||
font-size: 2em;
|
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;
|
font-size: 1.25em;
|
||||||
line-height: 1.25em;
|
line-height: 1.25em;
|
||||||
margin: 1em 1em 2.25em;
|
margin: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No margin for questions when no frame */
|
/* No margin for questions when no frame */
|
||||||
|
|
|
@ -112,11 +112,13 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
showResultPage: true,
|
showResultPage: true,
|
||||||
noResultMessage: 'Finished',
|
noResultMessage: 'Finished',
|
||||||
message: 'Your result:',
|
message: 'Your result:',
|
||||||
successGreeting: 'Congratulations!',
|
oldFeedback: {
|
||||||
successComment: 'You have enough correct answers to pass the test.',
|
successGreeting: '',
|
||||||
failGreeting: 'Sorry!',
|
successComment: '',
|
||||||
failComment: "You don't have enough correct answers to pass this test.",
|
failGreeting: '',
|
||||||
scoreString: 'You got @score of @total points',
|
failComment: ''
|
||||||
|
},
|
||||||
|
overallFeedback: [],
|
||||||
finishButtonText: 'Finish',
|
finishButtonText: 'Finish',
|
||||||
solutionButtonText: 'Show solution',
|
solutionButtonText: 'Show solution',
|
||||||
retryButtonText: 'Retry',
|
retryButtonText: 'Retry',
|
||||||
|
@ -158,27 +160,27 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
var randomizeQuestionOrdering = function (questions) {
|
var randomizeQuestionOrdering = function (questions) {
|
||||||
|
|
||||||
// Save the original order of the questions in a multidimensional array [[question0,0],[question1,1]...
|
// 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
|
// Shuffle the multidimensional array
|
||||||
questionOrdering = H5P.shuffleArray(questionOrdering);
|
questionOrdering = H5P.shuffleArray(questionOrdering);
|
||||||
|
|
||||||
// Retrieve question objects from the first index
|
// Retrieve question objects from the first index
|
||||||
var questions = [];
|
questions = [];
|
||||||
for (var i = 0; i < questionOrdering.length; i++) {
|
for (var i = 0; i < questionOrdering.length; i++) {
|
||||||
questions[i] = questionOrdering[i][0];
|
questions[i] = questionOrdering[i][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the new shuffled order from the second index
|
// Retrieve the new shuffled order from the second index
|
||||||
var newOrder = [];
|
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
|
// Use a previous order if it exists
|
||||||
if(contentData.previousState && contentData.previousState.questionOrder) {
|
if (contentData.previousState && contentData.previousState.questionOrder) {
|
||||||
newOrder[i] = questionOrder[questionOrdering[i][1]];
|
newOrder[j] = questionOrder[questionOrdering[j][1]];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newOrder[i] = questionOrdering[i][1];
|
newOrder[j] = questionOrdering[j][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +195,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
if (params.poolSize > 0) {
|
if (params.poolSize > 0) {
|
||||||
|
|
||||||
// If a previous pool exists, recreate it
|
// If a previous pool exists, recreate it
|
||||||
if(contentData.previousState && contentData.previousState.poolOrder) {
|
if (contentData.previousState && contentData.previousState.poolOrder) {
|
||||||
poolOrder = contentData.previousState.poolOrder;
|
poolOrder = contentData.previousState.poolOrder;
|
||||||
|
|
||||||
// Recreate the pool from the saved data
|
// Recreate the pool from the saved data
|
||||||
|
@ -247,7 +249,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
* @param {object} questions H5P content types to be created as instances
|
* @param {object} questions H5P content types to be created as instances
|
||||||
* @return {array} Array of questions instances
|
* @return {array} Array of questions instances
|
||||||
*/
|
*/
|
||||||
var createQuestionInstancesFromQuestions = function(questions) {
|
var createQuestionInstancesFromQuestions = function (questions) {
|
||||||
var result = [];
|
var result = [];
|
||||||
// Create question instances from questions
|
// Create question instances from questions
|
||||||
// Instantiate question instances
|
// Instantiate question instances
|
||||||
|
@ -312,8 +314,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
var _updateButtons = function () {
|
var _updateButtons = function () {
|
||||||
// Verify that current question is answered when backward nav is disabled
|
// Verify that current question is answered when backward nav is disabled
|
||||||
if (params.disableBackwardsNavigation) {
|
if (params.disableBackwardsNavigation) {
|
||||||
if (questionInstances[currentQuestion].getAnswerGiven()
|
if (questionInstances[currentQuestion].getAnswerGiven() &&
|
||||||
&& questionInstances.length-1 !== currentQuestion) {
|
questionInstances.length-1 !== currentQuestion) {
|
||||||
questionInstances[currentQuestion].showButton('next');
|
questionInstances[currentQuestion].showButton('next');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -418,15 +420,19 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
|
|
||||||
var currentQuestion = params.questions[currentQuestionIndex];
|
var currentQuestion = params.questions[currentQuestionIndex];
|
||||||
|
|
||||||
var hasAutoPlay = currentQuestion
|
var hasAutoPlay = currentQuestion &&
|
||||||
&& currentQuestion.params.media
|
currentQuestion.params.media &&
|
||||||
&& currentQuestion.params.media.params.playback.autoplay;
|
currentQuestion.params.media.params &&
|
||||||
|
currentQuestion.params.media.params.playback &&
|
||||||
|
currentQuestion.params.media.params.playback.autoplay;
|
||||||
|
|
||||||
if (hasAutoPlay) {
|
if (hasAutoPlay && typeof questionInstances[currentQuestionIndex].play === 'function') {
|
||||||
questionInstances[currentQuestionIndex].play();
|
questionInstances[currentQuestionIndex].play();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show solutions for subcontent, and hide subcontent buttons.
|
* Show solutions for subcontent, and hide subcontent buttons.
|
||||||
* Used for contracts with integrated content.
|
* Used for contracts with integrated content.
|
||||||
|
@ -520,7 +526,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
//Force the last page to be reRendered
|
//Force the last page to be reRendered
|
||||||
rendered = false;
|
rendered = false;
|
||||||
|
|
||||||
if(params.poolSize > 0){
|
if (params.poolSize > 0) {
|
||||||
|
|
||||||
// Make new pool from params.questions
|
// Make new pool from params.questions
|
||||||
// Randomize and get the results
|
// Randomize and get the results
|
||||||
|
@ -573,7 +579,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
var replaceQuestionsInDOM = function (questionInstances) {
|
var replaceQuestionsInDOM = function (questionInstances) {
|
||||||
|
|
||||||
// Find all question containers and detach questions from them
|
// Find all question containers and detach questions from them
|
||||||
$('.question-container', $myDom).each(function (){
|
$('.question-container', $myDom).each(function () {
|
||||||
$(this).children().detach();
|
$(this).children().detach();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -588,19 +594,19 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
question.attach($('.question-container:eq(' + i + ')', $myDom));
|
question.attach($('.question-container:eq(' + i + ')', $myDom));
|
||||||
|
|
||||||
//Show buttons if necessary
|
//Show buttons if necessary
|
||||||
if(questionInstances[questionInstances.length -1] === question
|
if (questionInstances[questionInstances.length -1] === question &&
|
||||||
&& question.hasButton('finish')) {
|
question.hasButton('finish')) {
|
||||||
question.showButton('finish');
|
question.showButton('finish');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(questionInstances[questionInstances.length -1] !== question
|
if (questionInstances[questionInstances.length -1] !== question &&
|
||||||
&& question.hasButton('next')) {
|
question.hasButton('next')) {
|
||||||
question.showButton('next');
|
question.showButton('next');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(questionInstances[0] !== question
|
if (questionInstances[0] !== question &&
|
||||||
&& question.hasButton('prev')
|
question.hasButton('prev') &&
|
||||||
&& !params.disableBackwardsNavigation) {
|
!params.disableBackwardsNavigation) {
|
||||||
question.showButton('prev');
|
question.showButton('prev');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +647,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
* @param {number} dotIndex Index of dot
|
* @param {number} dotIndex Index of dot
|
||||||
* @param {boolean} isAnswered True if is answered, False if not answered
|
* @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);
|
var $el = $('.progress-dot:eq(' + dotIndex +')', $myDom);
|
||||||
|
|
||||||
// Skip current button
|
// Skip current button
|
||||||
|
@ -703,12 +709,9 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
// Get total score.
|
// Get total score.
|
||||||
var finals = self.getScore();
|
var finals = self.getScore();
|
||||||
var totals = self.getMaxScore();
|
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 success = ((100 * finals / totals) >= params.passPercentage);
|
||||||
var eventData = {
|
|
||||||
score: scoreString,
|
|
||||||
passed: success
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes our buttons behave like other buttons.
|
* Makes our buttons behave like other buttons.
|
||||||
|
@ -731,8 +734,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
|
|
||||||
var eparams = {
|
var eparams = {
|
||||||
message: params.endGame.showResultPage ? params.endGame.message : params.endGame.noResultMessage,
|
message: params.endGame.showResultPage ? params.endGame.message : params.endGame.noResultMessage,
|
||||||
comment: params.endGame.showResultPage ? (success ? params.endGame.successGreeting : params.endGame.failGreeting) : undefined,
|
comment: params.endGame.showResultPage ? (success ? params.endGame.oldFeedback.successGreeting : params.endGame.oldFeedback.failGreeting) : undefined,
|
||||||
resulttext: params.endGame.showResultPage ? (success ? params.endGame.successComment : params.endGame.failComment) : undefined,
|
resulttext: params.endGame.showResultPage ? (success ? params.endGame.oldFeedback.successComment : params.endGame.oldFeedback.failComment) : undefined,
|
||||||
finishButtonText: params.endGame.finishButtonText,
|
finishButtonText: params.endGame.finishButtonText,
|
||||||
solutionButtonText: params.endGame.solutionButtonText,
|
solutionButtonText: params.endGame.solutionButtonText,
|
||||||
retryButtonText: params.endGame.retryButtonText
|
retryButtonText: params.endGame.retryButtonText
|
||||||
|
@ -743,10 +746,6 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
$myDom.append(endTemplate.render(eparams));
|
$myDom.append(endTemplate.render(eparams));
|
||||||
|
|
||||||
if (params.endGame.showResultPage) {
|
if (params.endGame.showResultPage) {
|
||||||
// Add event handlers to summary buttons
|
|
||||||
hookUpButton('.qs-finishbutton', function () {
|
|
||||||
self.trigger('h5pQuestionSetFinished', eventData);
|
|
||||||
});
|
|
||||||
hookUpButton('.qs-solutionbutton', function () {
|
hookUpButton('.qs-solutionbutton', function () {
|
||||||
showSolutions();
|
showSolutions();
|
||||||
$myDom.children().hide().filter('.questionset').show();
|
$myDom.children().hide().filter('.questionset').show();
|
||||||
|
@ -876,7 +875,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Hide next button if it is the last question
|
// Hide next button if it is the last question
|
||||||
if(questionInstances[questionInstances.length -1] === question) {
|
if (questionInstances[questionInstances.length -1] === question) {
|
||||||
question.hideButton('next');
|
question.hideButton('next');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,10 +1103,10 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
};
|
};
|
||||||
this.getQuestions = function() {
|
this.getQuestions = function () {
|
||||||
return questionInstances;
|
return questionInstances;
|
||||||
};
|
};
|
||||||
this.showSolutions = function() {
|
this.showSolutions = function () {
|
||||||
renderSolutions = true;
|
renderSolutions = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1165,7 +1164,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
/**
|
/**
|
||||||
* Add the question itself to the definition part of an xAPIEvent
|
* 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']);
|
var definition = xAPIEvent.getVerifiedStatementValue(['object', 'definition']);
|
||||||
$.extend(definition, getxAPIDefinition());
|
$.extend(definition, getxAPIDefinition());
|
||||||
};
|
};
|
||||||
|
@ -1176,8 +1175,8 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
* @param {Object} metaContentType
|
* @param {Object} metaContentType
|
||||||
* @returns {array}
|
* @returns {array}
|
||||||
*/
|
*/
|
||||||
var getXAPIDataFromChildren = function(metaContentType) {
|
var getXAPIDataFromChildren = function (metaContentType) {
|
||||||
return metaContentType.getQuestions().map(function(question) {
|
return metaContentType.getQuestions().map(function (question) {
|
||||||
return question.getXAPIData();
|
return question.getXAPIData();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1188,7 +1187,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
*
|
*
|
||||||
* @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6}
|
* @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6}
|
||||||
*/
|
*/
|
||||||
this.getXAPIData = function(){
|
this.getXAPIData = function () {
|
||||||
var xAPIEvent = this.createXAPIEventTemplate('answered');
|
var xAPIEvent = this.createXAPIEventTemplate('answered');
|
||||||
addQuestionToXAPI(xAPIEvent);
|
addQuestionToXAPI(xAPIEvent);
|
||||||
xAPIEvent.setScoredResult(this.getScore(),
|
xAPIEvent.setScoredResult(this.getScore(),
|
||||||
|
@ -1200,7 +1199,7 @@ H5P.QuestionSet = function (options, contentId, contentData) {
|
||||||
return {
|
return {
|
||||||
statement: xAPIEvent.data.statement,
|
statement: xAPIEvent.data.statement,
|
||||||
children: getXAPIDataFromChildren(this)
|
children: getXAPIDataFromChildren(this)
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -141,30 +141,48 @@
|
||||||
"description": "This heading will be displayed at the end of the quiz when the user has answered all questions."
|
"description": "This heading will be displayed at the end of the quiz when the user has answered all questions."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Score display text",
|
"label": "Overall Feedback",
|
||||||
"description": "Text used to display Total user score. \"@score\" will be replaced by calculated score, \"@total\" will be replaced by maximum possible score. ",
|
"fields": [
|
||||||
"default": "You got @score of @total points"
|
{
|
||||||
|
"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",
|
"label": "Quiz passed greeting",
|
||||||
"placeholder": "Congratulations!",
|
|
||||||
"default": "Congratulations!",
|
|
||||||
"description": "This text will be displayed above the score if the user has successfully passed the quiz."
|
"description": "This text will be displayed above the score if the user has successfully passed the quiz."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Passed comment",
|
"label": "Passed comment",
|
||||||
"default": "You did very well!",
|
|
||||||
"description": "This comment will be displayed after the score if the user has successfully passed the quiz."
|
"description": "This comment will be displayed after the score if the user has successfully passed the quiz."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Quiz failed title",
|
"label": "Quiz failed title",
|
||||||
"default": "You did not pass this time.",
|
|
||||||
"description": "This text will be displayed above the score if the user has failed the quiz."
|
"description": "This text will be displayed above the score if the user has failed the quiz."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Failed comment",
|
"label": "Failed comment",
|
||||||
"default": "Have another try!",
|
|
||||||
"description": "This comment will be displayed after the score if the user has failed the quiz."
|
"description": "This comment will be displayed after the score if the user has failed the quiz."
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Solution button label",
|
"label": "Solution button label",
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"description": "Put together a set of different questions that has to be solved. (Quiz)",
|
"description": "Put together a set of different questions that has to be solved. (Quiz)",
|
||||||
"contentType": "question",
|
"contentType": "question",
|
||||||
"majorVersion": 1,
|
"majorVersion": 1,
|
||||||
"minorVersion": 15,
|
"minorVersion": 13,
|
||||||
"patchVersion": 0,
|
"patchVersion": 0,
|
||||||
"embedTypes": [
|
"embedTypes": [
|
||||||
"iframe"
|
"iframe"
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
"author": "Joubel",
|
"author": "Joubel",
|
||||||
"coreApi": {
|
"coreApi": {
|
||||||
"majorVersion": 1,
|
"majorVersion": 1,
|
||||||
"minorVersion": 6
|
"minorVersion": 14
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"preloadedJs": [
|
"preloadedJs": [
|
||||||
|
@ -50,6 +50,11 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"editorDependencies": [
|
"editorDependencies": [
|
||||||
|
{
|
||||||
|
"machineName": "H5PEditor.RangeList",
|
||||||
|
"majorVersion": 1,
|
||||||
|
"minorVersion": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"machineName": "H5PEditor.VerticalTabs",
|
"machineName": "H5PEditor.VerticalTabs",
|
||||||
"majorVersion": 1,
|
"majorVersion": 1,
|
||||||
|
|
|
@ -276,7 +276,6 @@
|
||||||
"label": "Feedback heading",
|
"label": "Feedback heading",
|
||||||
"importance": "low",
|
"importance": "low",
|
||||||
"default": "Your result:",
|
"default": "Your result:",
|
||||||
"optional": true,
|
|
||||||
"description": "This heading will be displayed at the end of the quiz when the user has answered all questions.",
|
"description": "This heading will be displayed at the end of the quiz when the user has answered all questions.",
|
||||||
"tags": [
|
"tags": [
|
||||||
"strong",
|
"strong",
|
||||||
|
@ -284,21 +283,74 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scoreString",
|
"name": "overallFeedback",
|
||||||
"type": "text",
|
"type": "group",
|
||||||
"label": "Score display text",
|
"label": "Overall Feedback",
|
||||||
"importance": "low",
|
"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. ",
|
"fields": [
|
||||||
"default": "You got @score of @total points",
|
{
|
||||||
"optional": true
|
"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": "oldFeedback",
|
||||||
|
"type": "group",
|
||||||
|
"label": "Old Feedback",
|
||||||
|
"importance": "low",
|
||||||
|
"deprecated": true,
|
||||||
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "successGreeting",
|
"name": "successGreeting",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"label": "Quiz passed greeting",
|
"label": "Quiz passed greeting",
|
||||||
"importance": "low",
|
"importance": "low",
|
||||||
"placeholder": "Congratulations!",
|
|
||||||
"default": "Congratulations!",
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "This text will be displayed above the score if the user has successfully passed the quiz.",
|
"description": "This text will be displayed above the score if the user has successfully passed the quiz.",
|
||||||
"tags": [
|
"tags": [
|
||||||
|
@ -312,7 +364,6 @@
|
||||||
"widget": "html",
|
"widget": "html",
|
||||||
"label": "Passed comment",
|
"label": "Passed comment",
|
||||||
"importance": "low",
|
"importance": "low",
|
||||||
"default": "You did very well!",
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "This comment will be displayed after the score if the user has successfully passed the quiz.",
|
"description": "This comment will be displayed after the score if the user has successfully passed the quiz.",
|
||||||
"tags": [
|
"tags": [
|
||||||
|
@ -329,7 +380,6 @@
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"label": "Quiz failed title",
|
"label": "Quiz failed title",
|
||||||
"importance": "low",
|
"importance": "low",
|
||||||
"default": "You did not pass this time.",
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "This text will be displayed above the score if the user has failed the quiz.",
|
"description": "This text will be displayed above the score if the user has failed the quiz.",
|
||||||
"tags": [
|
"tags": [
|
||||||
|
@ -343,7 +393,6 @@
|
||||||
"widget": "html",
|
"widget": "html",
|
||||||
"label": "Failed comment",
|
"label": "Failed comment",
|
||||||
"importance": "low",
|
"importance": "low",
|
||||||
"default": "Have another try!",
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "This comment will be displayed after the score if the user has failed the quiz.",
|
"description": "This comment will be displayed after the score if the user has failed the quiz.",
|
||||||
"tags": [
|
"tags": [
|
||||||
|
@ -354,6 +403,8 @@
|
||||||
"a",
|
"a",
|
||||||
"p"
|
"p"
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "solutionButtonText",
|
"name": "solutionButtonText",
|
||||||
|
|
46
upgrades.js
46
upgrades.js
|
@ -52,6 +52,52 @@ H5PUpgrades['H5P.QuestionSet'] = (function ($) {
|
||||||
// Remove old copyright dialog question label
|
// Remove old copyright dialog question label
|
||||||
delete parameters.questionLabel;
|
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);
|
finished(null, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue