Skip to content
Snippets Groups Projects
Commit 6cef1384 authored by Eliott Sammier's avatar Eliott Sammier
Browse files

Add gapfill-open question with example

parent 25d029a8
No related tags found
No related merge requests found
Pipeline #1964 passed
......@@ -42,7 +42,9 @@ p#gapfill-container {
line-height: 3em;
}
select.sd-dropdown.inline-dropdown {
// Tweak the existing SurveyJS styles to have "inline" dropdown menus
// and text fields that don't take too much space
select.sd-dropdown.inline-dropdown, input.sd-input.inline-input {
display: inline-block;
width: fit-content;
padding: 8px;
......
/**
* Custom SurveyJS question type for a "fill-in-the-gaps" text,
* with an open-ended text input for each gap
*/
export const gapfillOpenWidget = {
name: "gapfill-open",
title: "Gap-Fill Text (Open)",
/**
* This function should return true when the widget and all needed resources
* are loaded
*/
widgetIsLoaded: function () {
return true;
},
/**
* This function should return true if the widget should be applied to the question */
isFit: function (question) {
return question.getType() === this.name;
},
init() {
//Register a new type using the empty question as the base.
Survey.Serializer.addClass(this.name, [], null, "empty");
},
/** Static HTML template rendered by SurveyJS */
htmlTemplate: '<p id="gapfill-container"><template id="template-gap"><input type="text" class="sd-input inline-input"/></template></p>',
/**
* Function called after the HTML template is rendered. This time we actually have the `question` object
* and the `el` element, to build the question according to the JSON
*/
afterRender: function (question, el) {
// The gap-fill text is made of segments, which are either plain pieces
// of text (strings) or "gaps" (objects).
// We append these to build the text, turning strings into <span>s and
// gaps into <input> text fields
let nbGaps = 0;
const segmentElems = new DocumentFragment(); // a bit faster than mutating the DOM all the time
const gapTemplate = document.getElementById("template-gap").content.firstChild;
for (const segment of question.jsonObj.segments) {
let segmentElem;
if (typeof segment === 'string' || segment instanceof String) {
segmentElem = document.createElement("span");
segmentElem.innerText = segment;
} else {
// It's a gap
// Create the <input> element
segmentElem = gapTemplate.cloneNode(true);
// Add the size attribute if present
if (segment.hasOwnProperty("size")) {
segmentElem.setAttribute("size", segment.size);
}
segmentElem.setAttribute("data-index", nbGaps); // The node knows its index
// Add callback to update the question's value when the input value changes
segmentElem.addEventListener("change", (e) => {
// The input node knows its index, therefore is able to update the question value at the correct index
question.value[parseInt(e.target.getAttribute("data-index"))] = e.target.value;
});
// Add callback to update the DOM nodes when the question's value changes
question.valueChangedCallback = () => {
const gaps = question.wrapperElement.querySelectorAll("#gapfill-container input");
if (question.value instanceof Array && question.value.length === gaps.length) {
for (const i in question.value) {
gaps[i].value = question.value[i];
}
} else {
// Unknown value -> reset all fields
for (const gap of gaps) {
gap.value = "";
}
}
}
nbGaps++;
}
// Add segment
segmentElems.appendChild(segmentElem);
}
// Initialize question value array
question.value = new Array(nbGaps);
// Finally add everything to the DOM
el.appendChild(segmentElems);
},
};
\ No newline at end of file
......@@ -32,6 +32,7 @@ $(function () {
// Register our custom question types
Survey.CustomWidgetCollection.Instance.add(gapfillSelectWidget, gapfillSelectWidget.name);
Survey.CustomWidgetCollection.Instance.add(gapfillOpenWidget, gapfillOpenWidget.name);
// Register custom properties for quiz correction comments
Survey.Serializer.addProperty("question", {
......
+++
title = "Texte à trous (libre)"
weight = 30
+++
Ceci est un exemple d'activité de type "texte à trous"
Ecoutez et complétez :
{{< quiz >}}
{
"elements": [
{
"type": "gapfill-open",
"name": "exemple-tat-libre",
"title": "Exemple",
"segments": [
"You must phone Mr Williams if you have a problem. He's ",
{},
" boss."
],
"correctAnswer": [
"the"
]
}
]
}
\ No newline at end of file
+++
title = "Texte à trous"
title = "Texte à trous (choix)"
weight = 30
+++
# Texte à trous (choix)
Ceci est un exemple d'activité de type "texte à trous"
{{< quiz >}}
......
......@@ -12,6 +12,7 @@
{{- $quizjs := slice -}}
{{- $quizjs = $quizjs | append (resources.Get "quiz.js") -}}
{{- $quizjs = $quizjs | append (resources.Get "gapfill-select.js") -}}
{{- $quizjs = $quizjs | append (resources.Get "gapfill-open.js") -}}
{{- $quizjs = $quizjs | resources.Concat "quiz.bundle.js" -}}
{{/* {{- $quizjs = $quizjs | resources.Minify -}}*/}}
<script type="module" src="{{- $quizjs.RelPermalink -}}"></script>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment