diff --git a/corsscripts/stacksortable.js b/corsscripts/stacksortable.js index 463c5ef2029..a431ccc4d19 100644 --- a/corsscripts/stacksortable.js +++ b/corsscripts/stacksortable.js @@ -7,13 +7,21 @@ export const stack_sortable = class { - constructor(state, inputId, availableId, options = {animation: 50}) { + constructor(state, inputId, availableId, options = null) { this.state = state; this.inputId = inputId; this.input = document.getElementById(this.inputId); this.availableId = availableId; this.available = document.getElementById(this.availableId); - this.options = {...{ghostClass: "list-group-item-info", group: "shared"}, ...options}; + // TODO : additional default options? + this.defaultOptions = {animation: 50}; + if (options == null) { + this.userOptions = this.defaultOptions; + } else { + this.userOptions = Object.assign(this.defaultOptions, options); + }; + // do not allow a user to replace ghostClass or group + this.options = Object.assign(this.userOptions, {ghostClass: "list-group-item-info", group: "shared"}); } generate_available(proofSteps) { diff --git a/corsscripts/stacksortable.min.js b/corsscripts/stacksortable.min.js index 045e305e854..49dbd593135 100644 --- a/corsscripts/stacksortable.min.js +++ b/corsscripts/stacksortable.min.js @@ -1,4 +1,4 @@ -export const stack_sortable=class{constructor(state,inputId,availableId,options={animation:50}){this.state=state;this.inputId=inputId;this.input=document.getElementById(this.inputId);this.availableId=availableId;this.available=document.getElementById(this.availableId);this.options={...{ghostClass:"list-group-item-info",group:"shared"},...options};} +export const stack_sortable=class{constructor(state,inputId,availableId,options=null){this.state=state;this.inputId=inputId;this.input=document.getElementById(this.inputId);this.availableId=availableId;this.available=document.getElementById(this.availableId);this.defaultOptions={animation:50};if(options==null){this.userOptions=this.defaultOptions;}else{this.userOptions=Object.assign(this.defaultOptions,options);};this.options=Object.assign(this.userOptions,{ghostClass:"list-group-item-info",group:"shared"});} generate_available(proofSteps){for(const key in this.state.available){let li=document.createElement("li");li.innerText=proofSteps[this.state.available[key]];li.setAttribute("data-id",key);li.className="list-group-item";this.available.append(li);};this.input.value=JSON.stringify(this.state);this.input.dispatchEvent(new Event("change"));} update_state(newUsed,newAvailable){var newState={used:[],available:[]};newState.used=newUsed.toArray();newState.available=newAvailable.toArray();this.input.value=JSON.stringify(newState);this.input.dispatchEvent(new Event('change'));this.state=newState;}};export default{stack_sortable}; \ No newline at end of file diff --git a/doc/en/Topics/Parsons.md b/doc/en/Topics/Parsons.md index 1ac835b5019..06eca0cefe7 100644 --- a/doc/en/Topics/Parsons.md +++ b/doc/en/Topics/Parsons.md @@ -71,7 +71,7 @@ The Parson's drag and drop lists are created using the Sortable JavaScript libra "animation": 50, } ```` -Currently, these cannot be toggled, but shortly one will be able to pass any Sortable option to the lists by having a JSON that is structured as follows in the Parson's block: +Most Sortable options can be toggled by passing a JSON that is structured as follows in the Parson's block: ```` [[ parsons input="ans1" height="360px" width="100%"]] { @@ -89,11 +89,12 @@ Currently, these cannot be toggled, but shortly one will be able to pass any Sor } [[/parsons]] ```` - +However, note that some options cannot be toggled as they are required for the proper functioning of the Sortable lists. Hence, any user-defined options for `ghostClass` and `group` are overwritten. ## Input: ans1 -The _Input type_ field should be **String**. The _Model answer_ field should be the Maxima representation of the proof solution. For the above example this should be `proof(1, 2, 3, 4)`. +The _Input type_ field should be **String**. The _Model answer_ field should be the Maxima representation of the proof solution. +For the above example this should be `proof(1, 2, 3, 4)`. ## Potential response tree: prt1 diff --git a/stack/cas/castext2/blocks/parsons.block.php b/stack/cas/castext2/blocks/parsons.block.php index e7eeb7f1bfe..fc1a3368e95 100644 --- a/stack/cas/castext2/blocks/parsons.block.php +++ b/stack/cas/castext2/blocks/parsons.block.php @@ -162,6 +162,13 @@ public function compile($format, $options): ? MP_Node { } } + // parse steps and options separately if they exist + $code .= 'var userOpts;' . "\n"; + $code .= 'if (JSON.stringify(Object.keys(proofSteps)) === JSON.stringify([ "steps", "options" ])) {' . "\n"; + $code .= 'userOpts = proofSteps["options"];' . "\n"; + $code .= 'proofSteps = proofSteps["steps"];' . "\n"; + $code .= '}' . "\n"; + // Link up to STACK inputs $code .= 'var inputPromise = stack_js.request_access_to_input("' . $this->params['input'] . '", true);' . "\n"; $code .= 'inputPromise.then((id) => {' . "\n"; @@ -171,7 +178,7 @@ public function compile($format, $options): ? MP_Node { $code .= 'state = {used: [], available: [...Object.keys(proofSteps)]};' . "\n"; // Create the sortable objects by filling in the container div - $code .= 'const sortable = new stack_sortable(state, id, "availableList");' . "\n"; + $code .= 'const sortable = new stack_sortable(state, id, "availableList", userOpts);' . "\n"; $code .= 'sortable.generate_available(proofSteps);' . "\n"; $code .= 'MathJax.typesetPromise();' . "\n"; $code .= 'var opts = {...sortable.options, ...{onSort: () => {sortable.update_state(sortableUsed, sortableAvailable);}}}' . "\n";