UNPKG

@oat-sa/tao-item-runner-qti

Version:
280 lines (245 loc) 11.7 kB
define(['jquery', 'lodash', 'handlebars', 'lib/handlebars/helpers', 'taoQtiItem/qtiCommonRenderer/helpers/container', 'taoQtiItem/qtiCommonRenderer/helpers/instructions/instructionManager', 'taoQtiItem/qtiCommonRenderer/helpers/PciResponse'], function ($$1, _, Handlebars, Helpers0, containerHelper, instructionMgr, pciResponse) { 'use strict'; $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1; _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _; Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars; Helpers0 = Helpers0 && Object.prototype.hasOwnProperty.call(Helpers0, 'default') ? Helpers0['default'] : Helpers0; containerHelper = containerHelper && Object.prototype.hasOwnProperty.call(containerHelper, 'default') ? containerHelper['default'] : containerHelper; instructionMgr = instructionMgr && Object.prototype.hasOwnProperty.call(instructionMgr, 'default') ? instructionMgr['default'] : instructionMgr; pciResponse = pciResponse && Object.prototype.hasOwnProperty.call(pciResponse, 'default') ? pciResponse['default'] : pciResponse; if (!Helpers0.__initialized) { Helpers0(Handlebars); Helpers0.__initialized = true; } var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { this.compilerInfo = [4,'>= 1.0.0']; helpers = this.merge(helpers, Handlebars.helpers); data = data || {}; var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression, self=this; function program1(depth0,data) { var buffer = "", stack1; buffer += "id=\"" + escapeExpression(((stack1 = ((stack1 = (depth0 && depth0.attributes)),stack1 == null || stack1 === false ? stack1 : stack1.id)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) + "\""; return buffer; } function program3(depth0,data) { var buffer = "", stack1; buffer += " " + escapeExpression(((stack1 = ((stack1 = (depth0 && depth0.attributes)),stack1 == null || stack1 === false ? stack1 : stack1['class'])),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)); return buffer; } function program5(depth0,data) { var buffer = "", stack1; buffer += " lang=\"" + escapeExpression(((stack1 = ((stack1 = (depth0 && depth0.attributes)),stack1 == null || stack1 === false ? stack1 : stack1['xml:lang'])),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) + "\""; return buffer; } function program7(depth0,data) { var stack1, helper; if (helper = helpers.prompt) { stack1 = helper.call(depth0, {hash:{},data:data}); } else { helper = (depth0 && depth0.prompt); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; } if(stack1 || stack1 === 0) { return stack1; } else { return ''; } } buffer += "<div "; stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.attributes)),stack1 == null || stack1 === false ? stack1 : stack1.id), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); if(stack1 || stack1 === 0) { buffer += stack1; } buffer += " class=\"qti-interaction qti-blockInteraction qti-hottextInteraction"; stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.attributes)),stack1 == null || stack1 === false ? stack1 : stack1['class']), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}); if(stack1 || stack1 === 0) { buffer += stack1; } buffer += "\" data-serial=\""; if (helper = helpers.serial) { stack1 = helper.call(depth0, {hash:{},data:data}); } else { helper = (depth0 && depth0.serial); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; } buffer += escapeExpression(stack1) + "\" data-qti-class=\"hottextInteraction\""; stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.attributes)),stack1 == null || stack1 === false ? stack1 : stack1['xml:lang']), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data}); if(stack1 || stack1 === 0) { buffer += stack1; } buffer += ">\n "; stack1 = helpers['if'].call(depth0, (depth0 && depth0.prompt), {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data}); if(stack1 || stack1 === 0) { buffer += stack1; } buffer += "\n <div class=\"instruction-container\"></div>\n <div class=\"qti-flow-container\">"; if (helper = helpers.body) { stack1 = helper.call(depth0, {hash:{},data:data}); } else { helper = (depth0 && depth0.body); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; } if(stack1 || stack1 === 0) { buffer += stack1; } buffer += "</div>\n</div>\n"; return buffer; }); function tpl(data, options, asString) { var html = Template(data, options); return (asString || true) ? html : $(html); } /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; under version 2 * of the License (non-upgradable). * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2014 (original work) Open Assessment Technlogies SA (under the project TAO-PRODUCT); * */ /** * 'pseudo-label' is technically a div that behaves like a label. * This allows the usage of block elements inside the fake label */ var pseudoLabel = function (interaction) { var $container = containerHelper.get(interaction); var setChoice = function ($choice, interaction) { var $inupt = $choice.find('input'); if ($inupt.prop('checked') || $inupt.hasClass('disabled')) { $inupt.prop('checked', false); } else { var maxChoices = parseInt(interaction.attr('maxChoices')); var currentChoices = _.values(_getRawResponse(interaction)).length; if (currentChoices < maxChoices || maxChoices === 0) { $inupt.prop('checked', true); } } containerHelper.triggerResponseChangeEvent(interaction); instructionMgr.validateInstructions(interaction, { choice: $choice }); }; $$1('.hottext', $container).on('click', function (e) { e.preventDefault(); setChoice($$1(this), interaction); }); }; /** * Init rendering, called after template injected into the DOM * All options are listed in the QTI v2.1 information model: * http://www.imsglobal.org/question/qtiv2p1/imsqti_infov2p1.html#element10278 * * @param {object} interaction */ var render = function (interaction) { pseudoLabel(interaction); //set up the constraints instructions instructionMgr.minMaxChoiceInstructions(interaction, { min: interaction.attr('minChoices'), max: interaction.attr('maxChoices'), getResponse: _getRawResponse, onError: function (data) { var $input, $choice, $icon; if (data.choice && data.choice.length) { $choice = data.choice.addClass('error'); $input = $choice.find('input'); $icon = $choice.find(' > label > span').addClass('error cross'); setTimeout(function () { $input.prop('checked', false); $choice.removeClass('error'); $icon.removeClass('error cross'); }, 350); } } }); }; var resetResponse = function (interaction) { var $container = containerHelper.get(interaction); $$1('input', $container).prop('checked', false); }; /** * Set the response to the rendered interaction. * * The response format follows the IMS PCI recommendation : * http://www.imsglobal.org/assessment/pciv1p0cf/imsPCIv1p0cf.html#_Toc353965343 * * Available base types are defined in the QTI v2.1 information model: * http://www.imsglobal.org/question/qtiv2p1/imsqti_infov2p1.html#element10333 * * @param {object} interaction * @param {object} response */ var setResponse = function (interaction, response) { var $container = containerHelper.get(interaction); try { _.forEach(pciResponse.unserialize(response, interaction), function (identifier) { $container.find('input[value="' + identifier + '"]').prop('checked', true); }); instructionMgr.validateInstructions(interaction); } catch (e) { throw new Error('wrong response format in argument : ' + e); } }; var _getRawResponse = function (interaction) { var values = []; var $container = containerHelper.get(interaction); $$1('input:checked', $container).each(function () { values.push($$1(this).val()); }); return values; }; /** * Return the response of the rendered interaction * * The response format follows the IMS PCI recommendation : * http://www.imsglobal.org/assessment/pciv1p0cf/imsPCIv1p0cf.html#_Toc353965343 * * Available base types are defined in the QTI v2.1 information model: * http://www.imsglobal.org/question/qtiv2p1/imsqti_infov2p1.html#element10333 * * @param {object} interaction * @returns {object} */ var getResponse = function (interaction) { return pciResponse.serialize(_getRawResponse(interaction), interaction); }; /** * Clean interaction destroy * @param {Object} interaction */ var destroy = function destroy(interaction) { var $container = containerHelper.get(interaction); //restore selected choices: $container.find('.hottext').off('click'); //remove all references to a cache container containerHelper.reset(interaction); }; /** * Set the interaction state. It could be done anytime with any state. * * @param {Object} interaction - the interaction instance * @param {Object} state - the interaction state */ var setState = function setState(interaction, state) { if (_.isObject(state)) { if (state.response) { interaction.resetResponse(); interaction.setResponse(state.response); } } }; /** * Get the interaction state. * * @param {Object} interaction - the interaction instance * @returns {Object} the interaction current state */ var getState = function getState(interaction) { var state = {}; var response = interaction.getResponse(); if (response) { state.response = response; } return state; }; var HottextInteraction = { qtiClass: 'hottextInteraction', template: tpl, render: render, getContainer: containerHelper.get, setResponse: setResponse, getResponse: getResponse, resetResponse: resetResponse, destroy: destroy, setState: setState, getState: getState }; return HottextInteraction; });