Skip to content

Commit

Permalink
Added feedback [HFP-1030]
Browse files Browse the repository at this point in the history
  • Loading branch information
fnoks committed Jun 21, 2017
1 parent 7bdf728 commit 795851c
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 9 deletions.
4 changes: 2 additions & 2 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"title": "Simple Multi Choice",
"description": "Create a simple multiple choice",
"majorVersion": 1,
"minorVersion": 0,
"patchVersion": 5,
"minorVersion": 1,
"patchVersion": 0,
"runnable": 0,
"author": "thomasmars",
"license": "MIT",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"scripts": {
"test": "karma start",
"testdev": "karma start --autoWatch --no-single-run",
"build": "webpack",
"buildDev": "webpack --watch",
"build": "webpack -p",
"watch": "webpack --watch",
"dev": "webpack-dev-server --config webpack.dev.config.js -d --inline --hot --open"
},
"keywords": [
Expand Down
53 changes: 50 additions & 3 deletions semantics.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,57 @@
"entity": "Alternative",
"min": 2,
"field": {
"type": "group",
"name": "alternative",
"label": "Alternative",
"importance": "high",
"type": "text"
"fields": [
{
"name": "text",
"label": "Text",
"importance": "high",
"type": "text"
},
{
"name": "feedback",
"type": "group",
"label": "Feedback",
"importance": "low",
"optional": true,
"fields": [
{
"name": "chosenFeedback",
"type": "text",
"widget": "html",
"label": "Message displayed if answer is selected",
"importance": "low",
"description": "Message will appear below the answer on \"continue\" if this answer is selected.",
"optional": true,
"tags": [
"strong",
"em",
"sub",
"sup",
"a"
]
},
{
"name": "notChosenFeedback",
"type": "text",
"widget": "html",
"label": "Message displayed if answer is not selected",
"importance": "low",
"description": "Message will appear below the answer on \"continue\" if this answer is not selected.",
"optional": true,
"tags": [
"strong",
"em",
"sub",
"sup",
"a"
]
}
]
}
]
}
}
]
79 changes: 77 additions & 2 deletions src/scripts/simple-multiple-choice.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import './styles/simple-multiple-choice.css';
import xApiGenerator from './xapiGenerator';
let instanceId = 0;

const ALLOW_FINISH_ALWAYS = 0;
const ALLOW_FINISH_DENY = 1;
const ALLOW_FINISH_ALLOW = 2;

This comment has been minimized.

Copy link
@tajakobsen

tajakobsen Jun 26, 2017

I think the @enum pattern could improve grouping of these constants.
http://usejsdoc.org/tags-enum.html#examples

This comment has been minimized.

Copy link
@fnoks

fnoks Jun 27, 2017

Author Contributor

Have declared thhis enum in another way


export default class SimpleMultiChoice extends H5P.EventDispatcher {

/**
Expand All @@ -19,15 +23,29 @@ export default class SimpleMultiChoice extends H5P.EventDispatcher {
this.uniqueName = 'h5p-simple-multiple-choice-' + instanceId;
instanceId += 1;

// The <li> alternatives, so we can easily append feedback to them
this.listItems = [];

// Keeps the <div> feedback elements, so we can easily remove them
this.feedbackElements = [];

// Keep track of the state
this.state = alternatives.map((alt, i) => {
return {
id: i,
text: alt,
text: alt.text,
checked: false
}
});

// Does this have feedback at all?
this.hasFeedback = alternatives.some(alternative => {
return alternative.feedback.chosenFeedback ||
alternative.feedback.notChosenFeedback;
});
// Have we been given the possibility to display feedback?
this.feedbackShown = false;

this.xapiGenerator = new xApiGenerator({ question, alternatives });

/**
Expand Down Expand Up @@ -67,6 +85,16 @@ export default class SimpleMultiChoice extends H5P.EventDispatcher {
* @param {number} inputIndex Index of input element that changed
*/
this.handleInputChange = function(inputIndex) {

// If feedback is shown, hide it:
if (this.feedbackShown) {
this.feedbackElements.forEach(element => { element.remove() });
this.feedbackElements = [];
this.feedbackShown = false;

this.trigger('allow-finish-changed');
}

this.state = this.state.map((alt, j) => {
let checked = j === inputIndex;
if (inputType !== 'radio') {
Expand Down Expand Up @@ -125,9 +153,10 @@ export default class SimpleMultiChoice extends H5P.EventDispatcher {
label.appendChild(input);
label.innerHTML += text;


listItem.appendChild(label);
altList.appendChild(listItem);

this.listItems.push(listItem);
});

return altList;
Expand Down Expand Up @@ -156,6 +185,52 @@ export default class SimpleMultiChoice extends H5P.EventDispatcher {
})
};

/**
* If question alternatives have feedback, those have to be shown before
* user should be allowed to finish question.
*
* @return {number}
*/
this.allowFinish = function () {
if (this.hasFeedback) {
return (this.hasFeedback && this.feedbackShown) ? ALLOW_FINISH_ALLOW : ALLOW_FINISH_DENY;
}

return ALLOW_FINISH_ALWAYS;
};

/**
* Function invoked when user is finished. MC Need this to be able to
* give feedback if it has any
*
* @return {boolean} true if it had any feedback to give, false otherwise
*/
this.finish = function () {
alternatives.forEach((alt, index) => {
if (alt.feedback) {
let feedback;
const checked = this.state[index].checked;
if (checked && alt.feedback.chosenFeedback) {
feedback = alt.feedback.chosenFeedback;
}
else if (!checked && alt.feedback.notChosenFeedback) {
feedback = alt.feedback.notChosenFeedback;
}

if (feedback) {
const feedbackElement = document.createElement('div');
feedbackElement.className = 'h5p-simple-multiple-choice-alternative-feedback ' + (checked ? 'chosen' : 'not-chosen');
feedbackElement.innerHTML = feedback;
this.feedbackElements.push(feedbackElement);
this.listItems[index].appendChild(feedbackElement);
}
}
});

this.feedbackShown = true;
return (this.feedbackElements.length === 0);
};

this.restorePreviousState();
}
}
30 changes: 30 additions & 0 deletions src/scripts/styles/simple-multiple-choice.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,33 @@
top: 0.35em;
vertical-align: middle;
}

.h5p-simple-multiple-choice-alternative-feedback {
position: relative;
font-size: 1em;
padding: 0.7em 2.2em;
margin-top: .5em;
margin-left: -0.4em;
margin-right: -0.4em;
}

.h5p-simple-multiple-choice-alternative-feedback:before {
content: "";
position: absolute;
left: 0.8em;
top: -0.25em;
width: 0.5em;
height: 0.5em;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}

.h5p-simple-multiple-choice-alternative-feedback.chosen,
.h5p-simple-multiple-choice-alternative-feedback.chosen:before {
background: #ebf2f8;
}

.h5p-simple-multiple-choice-alternative-feedback.not-chosen,
.h5p-simple-multiple-choice-alternative-feedback.not-chosen:before {
background: #faebf2;
}
23 changes: 23 additions & 0 deletions upgrades.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var H5PUpgrades = H5PUpgrades || {};

H5PUpgrades['H5P.SimpleMultiChoice'] = (function ($) {
return {
1: {
1: function (params, finished) {
if (params && params.alternatives) {
for (var i = 0 ; i < params.alternatives.length; i++) {
params.alternatives[i] = {
text: params.alternatives[i],
feedback: {
chosenFeedback: '',
notChosenFeedback: ''
}
}
}
}
// Send it back
finished(null, params);
}
}
};
})(H5P.jQuery);

0 comments on commit 795851c

Please sign in to comment.