tao-test/app/taoQtiItem/views/js/qtiCreator/model/mixin/editableInteraction.js

178 lines
6.3 KiB
JavaScript
Raw Normal View History

2022-08-29 20:14:13 +02:00
/*
* 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-2018 (original work) Open Assessment Technologies SA;
*
*/
/**
* Mixins methods for editable interactions
*/
define([
'lodash',
'taoQtiItem/qtiItem/core/Element',
'taoQtiItem/qtiCreator/model/variables/ResponseDeclaration',
'taoQtiItem/qtiCreator/model/helper/event',
'taoQtiItem/qtiCreator/model/helper/response'
], function(_, Element, ResponseDeclaration, event, responseHelper){
'use strict';
var methods = {
/**
* Remove a choice from the interaction
*
* @param {string|choice} choice
* @returns {object} this
*/
removeChoice : function removeChoice(choice){
var serial = '', c;
if(typeof(choice) === 'string'){
serial = choice;
}else if(Element.isA(choice, 'choice')){
serial = choice.getSerial();
}
if(this.choices[serial]){
//remove choice
c = this.choices[serial];
delete this.choices[serial];
//update the response
responseHelper.removeChoice(this.getResponseDeclaration(), c);
//trigger event
event.choiceDeleted(c, this);
}
return this;
},
createOutcomeDeclarationIfNotExists(outcomeIdentifier, buildIdentifier) {
const item = this.getRootElement();
let outcome = item.getOutcomeDeclaration(outcomeIdentifier);
if(!outcome){
outcome = item.createOutcomeDeclaration({
cardinality : 'single',
baseType : 'float'
});
buildIdentifier
? outcome.buildIdentifier(outcomeIdentifier, false)
: outcome.attr('identifier', outcomeIdentifier);
}
},
createResponse : function createResponse(attrs, template){
const response = new ResponseDeclaration();
const responseProcessing = this.rootElement.responseProcessing;
const processingType = responseProcessing && responseProcessing.processingType;
let item, renderer;
if(attrs){
response.attr(attrs);
}
//we assume in the context of edition, every element is created from the api so alwayd bound to an item:
item = this.getRootElement();
item.addResponseDeclaration(response);
const perInteractionRp = item.metaData.widget.options.perInteractionRp;
//assign responseIdentifier only after attaching it to the item to generate a unique id
response.buildIdentifier('RESPONSE', false);
response.setTemplate(
processingType === 'custom'
? 'CUSTOM'
: template || 'MATCH_CORRECT'
);
this.attr('responseIdentifier', response.id());
//adding a response processing template require the outcome SCORE:
this.createOutcomeDeclarationIfNotExists('SCORE', true);
// create interaction response declaration in case of per interaction response processing
if (perInteractionRp) {
const outcomeIdentifier = `SCORE_${response.attributes.identifier}`;
this.createOutcomeDeclarationIfNotExists(outcomeIdentifier);
}
//se the default value for the score default value
response.mappingAttributes.defaultValue = 0;
//set renderer
renderer = this.getRenderer();
if(renderer){
response.setRenderer(renderer);
}
return response;
},
/**
* To be called before deleting the interaction
*/
deleteResponse : function deleteResponse(){
var response = this.getResponseDeclaration();
if(response){
this.getRootElement().deleteResponseDeclaration(response);
}
this.removeAttr('responseIdentifier');
return this;
},
beforeRemove : function beforeRemove(){
const item = this.getRootElement();
const serial = this.serial,
interactions = item.getInteractions();
const perInteractionRp = item.metaData.widget.options.perInteractionRp;
// remove interaction outcome
if (perInteractionRp && this.attributes.responseIdentifier) {
item.removeOutcome(`SCORE_${this.attributes.responseIdentifier}`);
}
//delete its response
this.deleteResponse();
//when there is only one interaction remaining, its reponseIdentifier must be RESPONSE to be able to use one of the standard rp
if(_.size(interactions) === 2){
_.forEach(interactions, (interaction) => {
var response = interaction.getResponseDeclaration();
//find the other interaction, which will be the last remaining one
if(response && interaction.serial !== serial && interaction.qtiClass !== 'endAttemptInteraction'){
// rename interaction outcome
if (perInteractionRp) {
item.removeOutcome(`SCORE_${interaction.attributes.responseIdentifier}`);
this.createOutcomeDeclarationIfNotExists('SCORE_RESPONSE');
}
interaction.attr('responseIdentifier', 'RESPONSE');
response.id('RESPONSE');
}
});
}
}
};
return methods;
});