Merged new repo into old sub module.

Conflicts:
	css/questionset.css
	js/questionset.js
	library.json
	semantics.json
d3summaryChart
Frode Petterson 2014-03-28 17:05:08 +01:00
commit e2fd4e2ba4
11 changed files with 970 additions and 309 deletions

16
README.md Normal file
View File

@ -0,0 +1,16 @@
H5P Question Set
==========
Test your users with by putting together multiple tasks into a question set(quiz).
## License
(The MIT License)
Copyright (c) 2012-2014 Amendor AS
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,111 +1,246 @@
/* 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;
padding-bottom: 0.5em;
}
.questionset, .intro-page, .questionset-results {
overflow: hidden;
}
.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;
}
.h5p-multichoice > .h5p-question {
text-align: left;
margin: 0.5em 0.5em 0.7em;
background: rgba(255, 255, 255, 0.9);
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#e6FFFFFF,endColorstr=#e6FFFFFF);
zoom: 1;
}
.dots-container {
text-align: center;
line-height: 2em;
}
.progress-dot {
display: inline-block;
width: 10px;
height: 10px;
width: 0.6em;
height: 0.6em;
border-radius: 50%;
border: 1px solid #494949;
margin: 0 3px;
margin: 0 0.25em;
cursor: pointer;
background: #fff;
background: #cecece;
}
.progress-dot:hover {
box-shadow: 0 0 0.5em #c7c7c7;
}
.progress-dot.answered {
background: #494949;
background: #bccade;
}
.progress-dot.current {
box-shadow: 1px 1px 4px #494949;
margin: -1px 4px 1px 2px;
}
.intro-page {
/*background-color: rgba(255,255,255,0.9);*/
/*padding: 10px;*/
position: absolute;
z-index: 20;
height: 100%;
width: 100%;
left: 0px;
top: 0px;
}
.intro-page .title {
font-size: 200%;
font-weight: bold;
text-align: center;
margin: 1em;
}
.intro-page .introduction {
font-size: 125%;
margin: 1em 10%;
}
.intro-page .buttons {
position: absolute;
top: 200px;
left: 182px;
text-align: right;
background: #267ec9;
}
#qs-startbutton {
border: 4px solid #BABABA;
border-radius: 10px 10px 10px 10px;
font-size: 50px;
padding: 10px 20px;
.intro-page .title {
font-size: 2em;
line-height: 2em;
font-weight: bold;
text-align: center;
}
.intro-page .introduction {
font-size: 1.25em;
margin: 0 1em;
}
.intro-page .buttons {
margin: 3em auto;
text-align: center;
}
.qs-footer {
overflow: hidden;
}
.qs-footer .button, .qs-startbutton, .qs-finishbutton, .questionset-results .button, .video-container > .button {
display: inline-block;
padding: 0.2em 1em;
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;
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 .button:hover, .qs-startbutton:hover, .questionset-results .button:hover, .video-container > .button:hover {
text-decoration: none;
box-shadow: 0 0 0.5em #999;
color: #ffffff;
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;
}
.qs-footer > .qs-solutionbutton {
float: none;
}
.qs-footer > .next, .qs-footer > .finish, .qs-finishbutton {
float: right;
}
.qs-footer a.next.button:after {
font-family: H5PFontAwesome;
content: " \f054";
}
.qs-footer a.prev.button:before {
font-family: H5PFontAwesome;
content: "\f053 ";
}
.questionset-results .qs-finishbutton {
display: none;
}
.qs-footer a.finish.button:before {
font-family: H5PFontAwesome;
content: "\f00c ";
}
.questionset-results a.button.qs-solutionbutton:before {
font-family: H5PFontAwesome;
content: "\f06e ";
}
.video-container {
position: relative;
}
.video-container > video {
background-color: #000;
}
.video-container > .button {
position: absolute;
top: 0.5em;
right: 0.5em;
}
.qs-progress {
line-height: 40px;
padding: 0;
text-align: center;
line-height: 1.5em;
}
.questionset-results {
background-image: url(img/Paper-clean.png);
background-color: rgba(255, 255, 255, 0.75);
padding: 10px;
height: 480px;
text-align: center;
background: rgba(255, 255, 255, 0.9);
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#E6FFFFFF,endColorstr=#E6FFFFFF);
padding: 0.625em;
}
.questionset-results .greeting {
margin-top: 180px;
text-align: left;
border-bottom: 0.1em solid #ddd;
width: 100%;
}
.questionset-results .score {
font-size: 25px;
margin-top: 40px;
margin: 0;
display: block;
margin-bottom: 2em;
}
.questionset-results .resulttext {
font-size: 20px;
line-height: 25px;
margin: 40px 100px;
padding-left: 60px;
min-height: 60px;
text-align: left;
font-size: 1.25em;
line-height: 1.25em;
margin: 1em 0em;
background-repeat: no-repeat;
background-position: left center;
}
.questionset-results .resulttext.fail {
background-image: url(img/mark-fail.png);
}
.questionset-results .resulttext.fail em {
font-style: normal;
color: #b9272d;
}
.questionset-results .resulttext.success {
background-image: url(img/mark-pass.png);
.questionset-results .score.success .emoticon:before {
font-family: icomoon-questionset;
font-size: 5em;
line-height: 100%;
content: "\e606";
float: left;
}
.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: -15px;
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;
}
.questionset-results .buttons {
position: absolute;
bottom: 40px;
right: 25px;
}
button, .button {
cursor: pointer;
}

BIN
fonts/icomoon.eot Normal file

Binary file not shown.

14
fonts/icomoon.svg Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" d="" horiz-adv-x="512" />
<glyph unicode="&#xe604;" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM256 640c0 35.346 28.654 64 64 64s64-28.654 64-64c0-35.346-28.654-64-64-64-35.346 0-64 28.654-64 64zM640 640c0 35.346 28.654 64 64 64s64-28.654 64-64c0-35.346-28.654-64-64-64-35.346 0-64 28.654-64 64zM704.098 332.74l82.328-49.396c-55.962-93.070-157.916-155.344-274.426-155.344s-218.464 62.274-274.426 155.344l82.328 49.396c39.174-65.148 110.542-108.74 192.098-108.74s152.924 43.592 192.098 108.74z" />
<glyph unicode="&#xe605;" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM745.74 358.38l22.488-76.776-437.008-128.002-22.488 76.776zM256 640c0 35.346 28.654 64 64 64s64-28.654 64-64c0-35.346-28.654-64-64-64-35.346 0-64 28.654-64 64zM640 640c0 35.346 28.654 64 64 64s64-28.654 64-64c0-35.346-28.654-64-64-64-35.346 0-64 28.654-64 64z" />
<glyph unicode="&#xe606;" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM192 448v-64c0-140.8 115.2-256 256-256h128c140.8 0 256 115.2 256 256v64h-640zM384 203.012c-26.538 9.458-50.924 24.822-71.544 45.446-36.406 36.402-56.456 84.54-56.456 135.542h128v-180.988zM576 192h-128v192h128v-192zM711.544 248.458c-20.624-20.624-45.010-35.988-71.544-45.446v180.988h128c0-51.002-20.048-99.14-56.456-135.542zM225.352 576c0.002 0 0 0 0 0 9.768 0 18.108 7.056 19.724 16.69 6.158 36.684 37.668 63.31 74.924 63.31s68.766-26.626 74.924-63.31c1.616-9.632 9.956-16.69 19.722-16.69 9.768 0 18.108 7.056 19.724 16.688 1.082 6.436 1.628 12.934 1.628 19.312 0 63.962-52.038 116-116 116s-116-52.038-116-116c0-6.378 0.548-12.876 1.628-19.312 1.62-9.632 9.96-16.688 19.726-16.688zM609.352 576c0.002 0 0 0 0 0 9.77 0 18.112 7.056 19.724 16.69 6.158 36.684 37.668 63.31 74.924 63.31s68.766-26.626 74.924-63.31c1.616-9.632 9.958-16.69 19.722-16.69s18.108 7.056 19.722 16.688c1.082 6.436 1.628 12.934 1.628 19.312 0 63.962-52.038 116-116 116s-116-52.038-116-116c0-6.378 0.544-12.876 1.626-19.312 1.624-9.632 9.964-16.688 19.73-16.688z" />
<glyph unicode="&#xe607;" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM384 256c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128-70.692 0-128 57.308-128 128zM640 608c0 53.019 28.654 96 64 96s64-42.981 64-96c0-53.019-28.654-96-64-96-35.346 0-64 42.981-64 96zM256 608c0 53.019 28.654 96 64 96s64-42.981 64-96c0-53.019-28.654-96-64-96-35.346 0-64 42.981-64 96z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
fonts/icomoon.ttf Normal file

Binary file not shown.

BIN
fonts/icomoon.woff Normal file

Binary file not shown.

View File

@ -1,125 +1,140 @@
// Will render a Question with multiple choices for answers.
// Options format:
// {
// title: "Optional title for question box",
// question: "Question text",
// answers: [{text: "Answer text", correct: false}, ...],
// singleAnswer: true, // or false, will change rendered output slightly.
// }
//
// Events provided:
// - h5pQuestionSetFinished: Triggered when a question is finished. (User presses Finish-button)
var H5P = H5P || {};
if (H5P.getPath === undefined) {
/**
* Find the path to the content files based on the id of the content
*
* Also identifies and returns absolute paths
*
* @param {String} path Absolute path to a file, or relative path to a file in the content folder
* @param {Number} contentId Identifier of the content requesting the path
* @returns {String} The path to use.
*/
H5P.getPath = function (path, contentId) {
if (path.substr(0, 7) === 'http://' || path.substr(0, 8) === 'https://') {
return path;
}
return H5PIntegration.getContentPath(contentId) + path;
};
}
/**
* Will render a Question with multiple choices for answers.
*
* Events provided:
* - h5pQuestionSetFinished: Triggered when a question is finished. (User presses Finish-button)
*
* @param {Array} options
* @param {int} contentId
* @returns {H5P.QuestionSet} Instance
*/
H5P.QuestionSet = function (options, contentId) {
if ( !(this instanceof H5P.QuestionSet) )
if (!(this instanceof H5P.QuestionSet)) {
return new H5P.QuestionSet(options, contentId);
}
var $ = H5P.jQuery;
var cp = H5P.getContentPath(contentId);
var texttemplate = '' +
'<% if (introPage.showIntroPage) { %>' +
'<div class="intro-page">' +
' <div class="title"><%= introPage.title %></div>' +
' <div class="introduction"><%= introPage.introduction %></div>' +
' <div class="buttons"><a id="qs-startbutton" class="button"><%= introPage.startButtonText %></a></div>' +
'</div>' +
'<%} %>' +
'<div class="questionset hidden">' +
' <div class="title"><%= title %></div>' +
' <% for (var i=0; i<questions.length; i++) { %>' +
' <div class="question-container" id="q-<%= i %>">' +
' <div><%= questions[i].library %></div>' +
' </div>' +
' <% } %>' +
' <div class="qs-footer">' +
' <div class="qs-progress">' +
' <% if (progressType == "dots") { %>' +
' <div class="dots-container">' +
' <% for (var i=0; i<questions.length; i++) { %>' +
' <span class="progress-dot unanswered" id="qdot-<%= i %>"></span>' +
' <%} %>' +
' </div>' +
' <% } else if (progressType == "textual") { %>' +
' <span class="progress-text"></span>' +
' <% } %>' +
' </div>' +
' <a class="prev button"><%= texts.prevButton %></a>' +
' <a class="next button"><%= texts.nextButton %></a>' +
' <a class="finish button"><%= texts.finishButton %></a>' +
' </div>' +
'</div>' +
'';
var resulttemplate = '' +
'<div class="questionset-results">' +
' <div class="greeting"><%= greeting %></div>' +
' <div class="score <%= scoreclass %>"><%= score %></div>' +
' <div class="resulttext <%= scoreclass %>"><%= resulttext %></div>' +
' <div class="buttons"><a class="button qs-finishbutton"><%= finishButtonText %></a></div>' +
'</div>' +
'';
var texttemplate =
'<% if (introPage.showIntroPage) { %>' +
'<div class="intro-page">' +
' <div class="title"><%= introPage.title %></div>' +
' <div class="introduction"><%= introPage.introduction %></div>' +
' <div class="buttons"><a class="qs-startbutton button"><%= introPage.startButtonText %></a></div>' +
'</div>' +
'<% } %>' +
'<div class="questionset<% if (introPage.showIntroPage) { %> hidden<% } %>">' +
' <% for (var i=0; i<questions.length; i++) { %>' +
' <div class="question-container"></div>' +
' <% } %>' +
' <div class="qs-footer">' +
' <div class="qs-progress">' +
' <% if (progressType == "dots") { %>' +
' <div class="dots-container">' +
' <% for (var i=0; i<questions.length; i++) { %>' +
' <span class="progress-dot unanswered"></span>' +
' <%} %>' +
' </div>' +
' <% } else if (progressType == "textual") { %>' +
' <span class="progress-text"></span>' +
' <% } %>' +
' </div>' +
' <a class="prev button"><%= texts.prevButton %></a>' +
' <a class="next button"><%= texts.nextButton %></a>' +
' <a class="finish button"><%= texts.finishButton %></a>' +
' </div>' +
'</div>';
var resulttemplate =
'<div class="questionset-results">' +
' <div class="greeting"><%= message %></div>' +
' <div class="score <%= scoreclass %>">' +
' <div class="emoticon"></div>' +
' <div class="resulttext <%= scoreclass %>"><% if (comment) { %><h2><%= comment %></h2><% } %><%= score %><br><%= resulttext %></div>' +
' </div>' +
' <div class="buttons"><a class="button qs-finishbutton"><%= finishButtonText %></a><a class="button qs-solutionbutton"><%= solutionButtonText %></a></div>' +
'</div>';
var that = this;
var defaults = {
title: "",
randomOrder: false,
initialQuestion: 0,
backgroundImage: "",
backgroundImage: undefined,
progressType: 'dots',
passPercentage: 50,
questions: [],
introPage: {
showIntroPage: true,
title: "Welcome",
introduction: "Click start to start.",
startButtonText: "Start"
showIntroPage: false,
title: '',
introduction: '',
startButtonText: 'Start'
},
texts: {
prevButton: "Previous",
nextButton: "Next",
finishButton: "Finish",
textualProgress: "Question: @current of @total questions"
prevButton: 'Previous',
nextButton: 'Next',
finishButton: 'Finish',
textualProgress: 'Question: @current of @total questions'
},
endGame: {
showResultPage: true,
resultPage: {
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: "@score/@total",
finishButtonText: "Finish"
},
animations: {
showAnimations: false,
successVideo: undefined,
failVideo: undefined
}
}
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 points of @total possible.',
finishButtonText: 'Finish',
solutionButtonText: 'Show solution',
showAnimations: false,
successVideo: undefined,
failVideo: undefined
},
postUserStatistics: (H5P.postUserStatistics === true)
};
var template = new EJS({text: texttemplate});
var endTemplate = new EJS({text: resulttemplate});
var params = $.extend({}, defaults, options);
var params = $.extend(true, {}, defaults, options);
var currentQuestion = 0;
var questionInstances = new Array();
var allQuestionsAnswered = false;
var $myDom;
renderSolutions = false;
if (params.randomOrder) {
// TODO: Randomize order of questions
console.log("TODO: Randomize order of questions");
}
// if (params.randomOrder) {
// // TODO: Randomize order of questions
// }
// Instantiate question instances
for (var i=0; i<params.questions.length; i++) {
for (var i = 0; i < params.questions.length; i++) {
var question = params.questions[i];
// TODO: Render on init, inject in template.
var libraryObject = H5P.libraryFromString(question.library);
$.extend(question.params, {
displaySolutionsButton: false,
postUserStatistics: false
});
var tmp = new (H5P.classFromName(libraryObject.machineName))(question.params, contentId);
questionInstances.push(tmp);
}
@ -136,7 +151,7 @@ H5P.QuestionSet = function (options, contentId) {
} else {
$('.prev.button', $myDom).show();
}
if (currentQuestion == (params.questions.length - 1)) {
if (currentQuestion === (params.questions.length - 1)) {
$('.next.button', $myDom).hide();
if (answered) {
$('.finish.button', $myDom).show();
@ -145,28 +160,34 @@ H5P.QuestionSet = function (options, contentId) {
$('.next.button', $myDom).show();
$('.finish.button', $myDom).hide();
}
};
var _showQuestion = function (questionNumber) {
// Sanitize input.
if (questionNumber < 0) { questionNumber = 0; }
if (questionNumber >= params.questions.length) { questionNumber = params.questions.length - 1; }
if (questionNumber < 0) {
questionNumber = 0;
}
if (questionNumber >= params.questions.length) {
questionNumber = params.questions.length - 1;
}
// Hide all questions
$('.question-container', $myDom).hide();
$('.question-container', $myDom).hide().eq(questionNumber).show();
// Reshow the requested question
$('#q-' + questionNumber, $myDom).show();
// Trigger resize on question in case the size of the QS has changed.
if (questionInstances[questionNumber].resize !== undefined) {
questionInstances[questionNumber].resize();
}
// Update progress indicator
// Test if current has been answered.
if (params.progressType == 'textual') {
if (params.progressType === 'textual') {
$('.progress-text', $myDom).text(params.texts.textualProgress.replace("@current", questionNumber+1).replace("@total", params.questions.length));
} else {
}
else {
// Set currentNess
$('.progress-dot.current', $myDom).removeClass('current');
$('#qdot-' + questionNumber, $myDom).addClass('current');
$('.progress-dot:eq(' + questionNumber +')', $myDom).addClass('current');
}
// Remember where we are
@ -175,44 +196,94 @@ H5P.QuestionSet = function (options, contentId) {
return currentQuestion;
};
var showSolutions = function () {
for (var i = 0; i < questionInstances.length; i++) {
questionInstances[i].showSolutions();
}
};
var rendered = false;
var reRender = function () {
rendered = false;
};
var _displayEndGame = function () {
if (rendered) {
$myDom.children().hide().filter('.questionset-results').show();
return;
}
rendered = true;
// Get total score.
var finals = getScore();
var totals = totalScore();
var scoreString = params.endGame.resultPage.scoreString.replace("@score", finals).replace("@total", totals);
var scoreString = params.endGame.scoreString.replace("@score", finals).replace("@total", totals);
var success = ((100 * finals / totals) >= params.passPercentage);
var eventData = {
score: scoreString,
passed: success
};
var displayResults = function () {
if (params.postUserStatistics === true) {
H5P.setFinished(contentId, getScore(), totalScore());
}
if (!params.endGame.showResultPage) {
$(returnObject).trigger('h5pQuestionSetFinished', eventData);
return;
}
var eparams = {
greeting: (success ? params.endGame.resultPage.succesGreeting : params.endGame.resultPage.failGreeting),
message: params.endGame.message,
comment: (success ? params.endGame.successGreeting : params.endGame.failGreeting),
score: scoreString,
scoreclass: (success ? 'success' : 'fail'),
resulttext: (success ? params.endGame.resultPage.successComment : params.endGame.resultPage.failComment),
finishButtonText: params.endGame.resultPage.finishButtonText
resulttext: (success ? params.endGame.successComment : params.endGame.failComment),
finishButtonText: params.endGame.finishButtonText,
solutionButtonText: params.endGame.solutionButtonText
};
// Show result page.
$myDom.children().hide();
$myDom.append(endTemplate.render(eparams));
$('.qs-finishbutton').click(function (ev) {
$('.qs-finishbutton').click(function () {
$(returnObject).trigger('h5pQuestionSetFinished', eventData);
});
$('.qs-solutionbutton', $myDom).click(function () {
showSolutions();
$myDom.children().hide().filter('.questionset').show();
_showQuestion(params.initialQuestion);
});
};
if (params.endGame.animations.showAnimations) {
var videoData = success ? params.endGame.animations.successVideo : params.endGame.animations.failVideo;
if (params.endGame.showAnimations) {
var videoData = success ? params.endGame.successVideo : params.endGame.failVideo;
if (videoData) {
H5P.playVideo($myDom, videoData, params.endGame.animations.skipButtonText, cp, function () {
$myDom.children().hide();
var $videoContainer = $('<div class="video-container"></div>').appendTo($myDom);
var video = new H5P.Video({
files: videoData,
fitToWrapper: true,
controls: false,
autoplay: false
}, contentId);
video.endedCallback = function () {
displayResults();
});
$videoContainer.hide();
};
video.attach($videoContainer);
video.play();
if (params.endGame.skipButtonText) {
$('<a class="button skip">' + params.endGame.skipButtonText + '</a>').click(function () {
video.stop();
$videoContainer.hide();
displayResults();
}).appendTo($videoContainer);
}
return;
}
}
@ -222,54 +293,68 @@ H5P.QuestionSet = function (options, contentId) {
// Function for attaching the multichoice to a DOM element.
var attach = function (target) {
if (typeof(target) == "string") {
$myDom = $("#" + target);
} else {
if (typeof(target) === "string") {
$myDom = $('#' + target);
}
else {
$myDom = $(target);
}
// Render own DOM into target.
$myDom.html(template.render(params)).css({
backgroundImage: 'url(' + cp + params.backgroundImage.path + ')'
});
$myDom.html(template.render(params));
if (params.backgroundImage !== undefined) {
$myDom.css({
overflow: 'hidden',
background: '#000 url("' + H5P.getPath(params.backgroundImage.path, contentId) + '") no-repeat 50% 50%',
backgroundSize: '100% auto'
});
}
// Attach questions
for (var i=0; i<questionInstances.length; i++) {
for (var i = 0; i < questionInstances.length; i++) {
var question = questionInstances[i];
// TODO: Render on init, inject in template.
question.attach('q-' + i);
$(question).on('h5pQuestionAnswered', function (ev) {
$('#qdot-' + currentQuestion, $myDom).removeClass('unanswered').addClass('answered');
question.attach($('.question-container:eq(' + i + ')', $myDom));
$(question).on('h5pQuestionAnswered', function () {
$('.progress-dot:eq(' + currentQuestion +')', $myDom).removeClass('unanswered').addClass('answered');
_updateButtons();
});
if (question.getAnswerGiven()) {
$('#qdot-'+i, $myDom).removeClass('unanswered').addClass('answered');
$('.progress-dot:eq(' + i +')'
, $myDom).removeClass('unanswered').addClass('answered');
}
}
$('#qs-startbutton').click(function (ev) {
// Allow other libraries to add transitions after the questions have been inited
$('.questionset', $myDom).addClass('started');
$('.qs-startbutton', $myDom).click(function () {
$(this).parents('.intro-page').hide();
$('.questionset', $myDom).removeClass('hidden');
_showQuestion(currentQuestion);
});
// Set event listeners.
$('.progress-dot', $myDom).click(function (ev) {
var idx = parseInt($(this).attr('id').split('-')[1], 10);
_showQuestion(idx);
$('.progress-dot', $myDom).click(function () {
_showQuestion($(this).index());
});
$('.next.button', $myDom).click(function (ev) {
$('.next.button', $myDom).click(function () {
_showQuestion(currentQuestion + 1);
});
$('.prev.button', $myDom).click(function (ev) {
$('.prev.button', $myDom).click(function () {
_showQuestion(currentQuestion - 1);
});
$('.finish.button', $myDom).click(function (ev) {
$('.finish.button', $myDom).click(function () {
_displayEndGame();
});
// Hide all but initial Question.
_showQuestion(params.initialQuestion);
_updateButtons();
if (renderSolutions) {
showSolutions();
}
return this;
};
@ -286,18 +371,65 @@ H5P.QuestionSet = function (options, contentId) {
var totalScore = function () {
var score = 0;
for (var i = questionInstances.length - 1; i >= 0; i--) {
score += questionInstances[i].totalScore();
score += questionInstances[i].getMaxScore();
}
return score;
};
/**
* Gather copyright information for the current content.
*
* @returns {H5P.ContentCopyrights}
*/
var getCopyrights = function () {
var info = new H5P.ContentCopyrights();
// Background
if (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];
if (questionInstance.getCopyrights !== undefined) {
var rights = questionInstance.getCopyrights();
if (rights !== undefined) {
rights.setLabel('Question '+(i+1));
info.addContent(rights);
}
}
}
// Success video
var video = params.endGame.successVideo[0];
if (video.copyright !== undefined) {
info.addMedia(new H5P.MediaCopyright(video.copyright));
}
// Fail video
video = params.endGame.failVideo[0];
if (video.copyright !== undefined) {
info.addMedia(new H5P.MediaCopyright(video.copyright));
}
return info;
}
// Masquerade the main object to hide inner properties and functions.
var returnObject = {
attach: attach, // Attach to DOM object
getQuestions: function () {return questionInstances;},
getScore: getScore,
showSolutions: function () {
renderSolutions = true;
},
totalScore: totalScore,
defaults: defaults // Provide defaults for inspection
reRender: reRender,
defaults: defaults, // Provide defaults for inspection
getCopyrights: getCopyrights
};
return returnObject;
};

144
language/nb.json Normal file
View File

@ -0,0 +1,144 @@
{
"semantics": [
{
"label": "Bakgrunnsbilde",
"description": "Bakgrunnsbilde for spørsmålssettet(ikke obligatorisk)."
},
{
"label": "Fremdriftsindikator",
"description": "Velg om fremdriften skal angis som prikker(få spørsmål) eller som tekst(mange spørsmål).",
"options": [
{
"label": "Angi fremdrift med tekst"
},
{
"label": "Angi fremdrift med prikker"
}
]
},
{
"label": "Krav for å bestå",
"description": "Antall prosent riktig som kreves for å bestå spørsmålssettet."
},
{
"label": "Spørsmål",
"entity": "spørsmål",
"field": {
"label": "Spørsmål",
"fields": [
{
"label": "Spørsmålstype",
"description": "Velg spørsmålstype for dette spørsmålet"
}
]
}
},
{
"label": "Introduksjon",
"fields": [
{
"label": "Vis introduksjon"
},
{
"label": "Tittel",
"description": "Tittel for intoduksjonssiden."
},
{
"label": "Introduksjonstekst",
"description": "Denne teksten vises før spørsmålssettet starter."
},
{
"label": "Tekst til \"Start\" knappen",
"default": "Start"
}
]
},
{
"label": "Ledetekster",
"fields": [
{
"label": "Forrige-knappen",
"default": "Forrige"
},
{
"label": "Neste-knappen",
"default": "Neste"
},
{
"label": "Avslutt-knappen",
"default": "Avslutt"
},
{
"label": "Fremdriftstekst",
"description": "Tekst brukt hvis tekstlig angivelse av fremdrift er valgt. Variabler: @current og @total",
"default": "Deloppgåve @current av @total"
}
]
},
{
"label": "Spørsmålssett avslutning",
"fields": [
{
"label": "Vis resultater"
},
{
"label": "Overskrift over tilbakemeldinger",
"default": "Ditt resultat:",
"description": "Denne overskriften vises over tilbakemeldingene på slutten av spørsmålssettet."
},
{
"label": "Poengvisningstekst",
"default": "Du fikk @score poeng av @total mulige.",
"description": "Tekst som viser brukerens oppnådde poeng. \"@score\" blir erstattet med utregnet resultat, \"@total\" blir erstattet med høyest mulige resultat."
},
{
"label": "Tittel ved bestått",
"default": "Gratulerer!",
"description": "Denne tittelen vises dersom brukeren har bestått spørsmålssettet."
},
{
"label": "Kommentar ved bestått",
"default": "Du presterte meget godt!",
"description": "Denne kommentaren vises dersom brukeren har bestått spørsmålssettet."
},
{
"label": "Tittel ved ikke bestått",
"default": "Ikke bestått",
"description": "Denne tittelen vises dersom brukeren ikke har bestått spørsmålssettet."
},
{
"label": "Kommentar ved ikke bestått",
"default": "Dette gikk ikke så bra. Prøv igjen!",
"description": "Denne kommentaren vises dersom brukeren ikke har bestått spørsmålssettet."
},
{
"label": "Tekst til \"Fasit\" knapp",
"default": "Vis fasit",
"description": ""
},
{
"label": "Tekst til \"Avslutt\" knapp",
"default": "Avslutt"
},
{
"label": "Vis video før resultatene"
},
{
"label": "Tillat å hoppe over video"
},
{
"label": "Tekst til \"Hopp over video\" knapp",
"default": "Hopp over"
},
{
"label": "Video ved bestått",
"description": "Denne videoen vil bli vist dersom brukeren består spørsmålssettet."
},
{
"label": "Video ved ikke bestått",
"description": "Denne videoen vil bli vist dersom brukeren ikke består spørsmålssettet."
}
]
}
]
}

144
language/nn.json Normal file
View File

@ -0,0 +1,144 @@
{
"semantics": [
{
"label": "Bakgrunnsbilde",
"description": "Bakgrunnsbilde for spørsmålssettet(ikke obligatorisk)."
},
{
"label": "Fremdriftsindikator",
"description": "Velg om fremdriften skal angis som prikker(få spørsmål) eller som tekst(mange spørsmål).",
"options": [
{
"label": "Angi fremdrift med tekst"
},
{
"label": "Angi fremdrift med prikker"
}
]
},
{
"label": "Krav for å bestå",
"description": "Antall prosent riktig som kreves for å bestå spørsmålssettet."
},
{
"label": "Spørsmål",
"entity": "spørsmål",
"field": {
"label": "Spørsmål",
"fields": [
{
"label": "Spørsmålstype",
"description": "Velg spørsmålstype for dette spørsmålet"
}
]
}
},
{
"label": "Introduksjon",
"fields": [
{
"label": "Vis introduksjon"
},
{
"label": "Tittel",
"description": "Tittel for intoduksjonssiden."
},
{
"label": "Introduksjonstekst",
"description": "Denne teksten vises før spørsmålssettet starter."
},
{
"label": "Tekst til \"Start\" knappen",
"default": "Start"
}
]
},
{
"label": "Ledetekster",
"fields": [
{
"label": "Forrige-knappen",
"default": "Forrige"
},
{
"label": "Neste-knappen",
"default": "Neste"
},
{
"label": "Avslutt-knappen",
"default": "Avslutt"
},
{
"label": "Fremdriftstekst",
"description": "Tekst brukt hvis tekstlig angivelse av fremdrift er valgt. Variabler: @current og @total",
"default": "Deloppgave @current av @total"
}
]
},
{
"label": "Spørsmålssett avslutning",
"fields": [
{
"label": "Vis resultat"
},
{
"label": "Overskrift over tilbakemeldingar",
"default": "Ditt resultat:",
"description": "Denne overskriften vises over tilbakemeldingane på slutten av spørsmålssettet."
},
{
"label": "Poengvisningstekst",
"default": "Du fikk @score poeng av @total mulige.",
"description": "Tekst som viser brukerens oppnådde poeng. \"@score\" blir erstatta med utregna resultat, \"@total\" blir erstatta med høgest mulig resultat."
},
{
"label": "Tittel ved bestått",
"default": "Gratulerer!",
"description": "Denne tittelen vises dersom brukeren har bestått spørsmålssettet."
},
{
"label": "Kommentar ved bestått",
"default": "Du presterte meget godt!",
"description": "Denne kommentaren vises dersom brukaren har bestått spørsmålssettet."
},
{
"label": "Tittel ved ikkje bestått",
"default": "Ikkje bestått",
"description": "Denne tittelen visast dersom brukaren ikkje har bestått spørsmålssettet."
},
{
"label": "Kommentar ved ikkje bestått",
"default": "Dette gikk ikkje så bra. Prøv igjen!",
"description": "Denne kommentaren vises dersom brukaren ikkje har bestått spørsmålssettet."
},
{
"label": "Tekst til \"Fasit\" knapp",
"default": "Vis fasit",
"description": ""
},
{
"label": "Tekst til \"Avslutt\" knapp",
"default": "Avslutt"
},
{
"label": "Vis video før resultata"
},
{
"label": "Tillat å hoppe over video"
},
{
"label": "Tekst til \"Hopp over video\" knapp",
"default": "Hopp over"
},
{
"label": "Video ved bestått",
"description": "Denne videoen vil bli vist dersom brukaren består spørsmålssettet."
},
{
"label": "Video ved ikke bestått",
"description": "Denne videoen vil bli vist dersom brukaren ikkje består spørsmålssettet."
}
]
}
]
}

View File

@ -3,8 +3,9 @@
"contentType": "question",
"majorVersion": 1,
"minorVersion": 0,
"patchVersion": 6,
"patchVersion": 43,
"runnable": 1,
"fullscreen": 0,
"machineName": "H5P.QuestionSet",
"author": "Amendor AS",
"license": "cc-by-sa",
@ -15,9 +16,31 @@
{"path": "css/questionset.css"}
],
"preloadedDependencies": [
{
"machineName": "H5P.API",
"majorVersion": 1,
"minorVersion": 0
},
{
"machineName": "EmbeddedJS",
"majorVersion": 1,
"majorVersion": 1,
"minorVersion": 0
},
{
"machineName": "FontAwesome",
"majorVersion": 3,
"minorVersion": 1
},
{
"machineName": "H5P.Video",
"majorVersion": 1,
"minorVersion": 0
}
],
"editorDependencies": [
{
"machineName": "H5PEditor.VerticalTabs",
"majorVersion": 1,
"minorVersion": 0
}
]

View File

@ -1,26 +1,9 @@
[
{
"name": "title",
"type": "text",
"label": "Title",
"description": "Question set title (optional)."
},
{
"name": "randomOrder",
"type": "boolean",
"label": "Randomize order",
"description": "Whether questions should be shown in random order."
},
{
"name": "initialQuestion",
"type": "number",
"label": "Initial question",
"description": "Which question to start with. Count from 0."
},
{
"name": "backgroundImage",
"type": "image",
"label": "Background image",
"optional": true,
"description": "An optional background image for the Question set."
},
{
@ -28,17 +11,17 @@
"type": "select",
"label": "Progress indicator",
"description": "Question set progress indicator style.",
"values": [
"options": [
{
"text": "Textual",
"value": "textual"
"value": "textual",
"label": "Textual"
},
{
"text": "Dots",
"value": "dots"
"value": "dots",
"label": "Dots"
}
],
"default": "textual"
"default": "dots"
},
{
"name": "passPercentage",
@ -52,50 +35,68 @@
},
{
"name": "questions",
"label": "Questions",
"type": "list",
"widget": "verticalTabs",
"min": 1,
"entity": "question",
"field": {
"name": "question",
"type": "group",
"label": "Question",
"fields": [
{
"name": "library",
"type": "library",
"label": "Question library",
"description": "Library for this question.",
"options": [
"H5P.MultiChoice 1.0"
]
}
"type": "library",
"label": "Question type",
"description": "Library for this question.",
"options": [
"H5P.MultiChoice 1.0",
"H5P.DragQuestion 1.0",
"H5P.Blanks 1.0"
]
}
},
{
"name": "introPage",
"type": "group",
"label": "Intro page",
"description": "Data for the intro page.",
"label": "Quiz introduction",
"fields": [
{
"name": "showIntroPage",
"type": "boolean",
"label": "Show intro page?"
"label": "Display introduction"
},
{
"name": "title",
"type": "text",
"label": "Title"
"label": "Title",
"optional": true,
"description": "This title will be displayed above the introduction text.",
"tags": [
"sub",
"sup",
"strong",
"em"
]
},
{
"name": "introduction",
"type": "text",
"label": "Introduction text"
"widget": "html",
"label": "Introduction text",
"optional": true,
"description": "This text will be displayed before the quiz starts.",
"enterMode": "p",
"tags": [
"sub",
"sup",
"strong",
"em",
"p"
]
},
{
"name": "startButtonText",
"type": "text",
"label": "Start button text"
"label": "Start button text",
"optional": true,
"default": "Start Quiz"
}
]
},
@ -128,94 +129,146 @@
"type": "text",
"label": "Progress text",
"description": "Text used if textual progress is selected.",
"default": "Question: @current of @total questions"
"default": "Question: @current of @total questions",
"tags": [
"strong",
"em"
]
}
]
},
{
"name": "endGame",
"type": "group",
"label": "End game data",
"label": "Quiz finished",
"fields": [
{
"name": "showResultPage",
"type": "boolean",
"label": "Show result page",
"label": "Display results",
"default": true
},
{
"name": "resultPage",
"type": "group",
"label": "Result page",
"description": "Data and texts for the result page.",
"fields": [
{
"name": "successGreeting",
"type": "text",
"label": "Success greeting",
"description": "Title in result page on success."
},
{
"name": "successComment",
"type": "text",
"label": "Success comment",
"description": "Comment shown after the score."
},
{
"name": "failGreeting",
"type": "text",
"label": "Failed greeting",
"description": "Title in result page on failed quiz."
},
{
"name": "failComment",
"type": "text",
"label": "Failed comment",
"description": "Comment shown after the score on failed quiz."
},
{
"name": "finishButtonText",
"type": "text",
"label": "Finish button text",
"description": "Text for the finish button."
}
"name": "message",
"type": "text",
"label": "Feedback heading",
"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",
"em"
]
},
{
"name": "animations",
"type": "group",
"label": "Animations",
"fields": [
{
"name": "showAnimations",
"type": "boolean",
"label": "Show animations"
},
{
"name": "skippable",
"type": "boolean",
"label": "Skippable"
},
{
"name": "skipButtonText",
"type": "text",
"label": "Skip button text",
"common": true
},
{
"name": "successVideo",
"type": "video",
"label": "Success video",
"description": "Video displayed on successful quiz."
},
{
"name": "failVideo",
"type": "video",
"label": "Fail video",
"description": "Video displayed on failed quiz."
}
"name": "scoreString",
"type": "text",
"label": "Score display text",
"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 points of @total possible.",
"optional": true
},
{
"name": "successGreeting",
"type": "text",
"label": "Quiz passed greeting",
"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"
]
},
{
"name": "successComment",
"type": "text",
"widget": "html",
"label": "Passed comment",
"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",
"p"
]
},
{
"name": "failGreeting",
"type": "text",
"label": "Quiz failed title",
"default": "Oh, no!",
"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",
"default": "This didn't go so well.",
"optional": true,
"description": "This comment will be displayed after the score if the user has failed the quiz.",
"tags": [
"sub",
"sup",
"strong",
"em",
"p"
]
},
{
"name": "solutionButtonText",
"type": "text",
"label": "Solution button label",
"default": "Show solution",
"description": "Text for the solution button."
},
{
"name": "finishButtonText",
"type": "text",
"label": "Finish button text",
"default": "Finish"
},
{
"name": "showAnimations",
"type": "boolean",
"label": "Display video before quiz results"
},
{
"name": "skippable",
"type": "boolean",
"label": "Enable skip video button"
},
{
"name": "skipButtonText",
"type": "text",
"label": "Skip video button label",
"default": "Skip video",
"common": true
},
{
"name": "successVideo",
"type": "video",
"label": "Passed video",
"optional": true,
"description": "This video will be played if the user successfully passed the quiz."
},
{
"name": "failVideo",
"type": "video",
"label": "Fail video",
"optional": true,
"description": "This video will be played if the user failes the quiz."
}
]
}
]
]