From 1cccb8f8aace836de388c7e64b13a5c0fc801076 Mon Sep 17 00:00:00 2001 From: Oliver Foster Date: Wed, 9 Oct 2024 18:19:37 +0100 Subject: [PATCH] New: _isLocked becomes a lockable attribute (fixes #585) * New: _isLocked becomes a lockable attribute * Do not lock when setting initial default * Ensure locked attributes remain locked after deepClone --- js/models/adaptModel.js | 16 ++++++++++++---- js/models/lockingModel.js | 4 +++- js/models/questionModel.js | 7 ++++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/js/models/adaptModel.js b/js/models/adaptModel.js index 6e852c97..e97387de 100644 --- a/js/models/adaptModel.js +++ b/js/models/adaptModel.js @@ -49,6 +49,12 @@ export default class AdaptModel extends LockingModel { }; } + lockedAttributes() { + return { + _isLocked: true + }; + } + /** * Fetch an array representing the relative location of the model to the nearest _trackingId * @returns {Array} @@ -780,7 +786,7 @@ export default class AdaptModel extends LockingModel { !previousChild.get('_isComplete') && !previousChild.get('_isOptional') ); - child.set('_isLocked', isLockedByPreviousChild); + child.set('_isLocked', isLockedByPreviousChild, { pluginName: 'adapt' }); }, false); } @@ -788,19 +794,19 @@ export default class AdaptModel extends LockingModel { const children = this.getAvailableChildModels(); const firstChild = children.shift(); const isLockedByFirstChild = (!firstChild.get('_isComplete') && !firstChild.get('_isOptional')); - children.forEach(child => child.set('_isLocked', isLockedByFirstChild)); + children.forEach(child => child.set('_isLocked', isLockedByFirstChild, { pluginName: 'adapt' })); } setLockLastLocking() { const children = this.getAvailableChildModels(); const lastChild = children.pop(); const isLockedByChildren = children.some(child => (!child.get('_isComplete') && !child.get('_isOptional'))); - lastChild.set('_isLocked', isLockedByChildren); + lastChild.set('_isLocked', isLockedByChildren, { pluginName: 'adapt' }); } setCustomLocking() { const children = this.getAvailableChildModels(); - children.forEach(child => child.set('_isLocked', this.shouldLock(child))); + children.forEach(child => child.set('_isLocked', this.shouldLock(child), { pluginName: 'adapt' })); } shouldLock(child) { @@ -850,6 +856,8 @@ export default class AdaptModel extends LockingModel { const ModelClass = this.constructor; // Clone the model const clonedModel = new ModelClass(this.toJSON()); + clonedModel._lockedAttributes = { ...this._lockedAttributes }; + clonedModel._lockedAttributesValues = { ...this._lockedAttributesValues }; // Run the custom modifier on the clone if (modifier) { modifier(clonedModel, this); diff --git a/js/models/lockingModel.js b/js/models/lockingModel.js index d990e61b..81f434c1 100644 --- a/js/models/lockingModel.js +++ b/js/models/lockingModel.js @@ -49,7 +49,9 @@ export default class LockingModel extends Backbone.Model { const isAttemptingToLock = (lockingValue === attrVal); if (isAttemptingToLock) { - this.setLockState(attrName, true, { pluginName, skipcheck: true }); + if (!isInitialDefault) { + this.setLockState(attrName, true, { pluginName, skipcheck: true }); + } newValues[attrName] = lockingValue; continue; } diff --git a/js/models/questionModel.js b/js/models/questionModel.js index b42ec1a7..704cdc1c 100644 --- a/js/models/questionModel.js +++ b/js/models/questionModel.js @@ -50,6 +50,12 @@ class QuestionModel extends ComponentModel { ]); } + lockedAttributes() { + return ComponentModel.resultExtend('lockedAttributes', { + _canSubmit: true + }); + } + /** * Returns a string of the model type group. * @returns {string} @@ -60,7 +66,6 @@ class QuestionModel extends ComponentModel { init() { this.setupDefaultSettings(); - this.setLocking('_canSubmit', true); this.updateRawScore(); super.init(); }