diff --git a/corsscripts/stacksortable.js b/corsscripts/stacksortable.js index 248a0a8001f361e4bedae3ff26ecddaa9bc535ff..8043c78bedfbf566e64786fe47839cb59831323d 100644 --- a/corsscripts/stacksortable.js +++ b/corsscripts/stacksortable.js @@ -525,9 +525,11 @@ export const stack_sortable = class stack_sortable { { var colDiv = document.createElement("ul"); colDiv.id = id; + // In matching mode, we need to add rigid styles to colDivs if orientation === "row" colDiv.classList.add(...usedClassList); container.append(colDiv); }); + // if rows are specified then add the row divs if (this.rows !== "") { this.colIds.forEach((colId) => { @@ -536,7 +538,12 @@ export const stack_sortable = class stack_sortable { this.rowColIds[colId].forEach((rowColId) => { var divRowCol = document.createElement("li"); divRowCol.id = rowColId; - divRowCol.classList.add(...itemClassList); + // In matching mode, we need to add rigid styles to colDivs if orientation === "row" + if (this.orientation === "row") { + divRowCol.classList.add(...itemClassList, ...["col-rigid"]); + } else { + divRowCol.classList.add(...itemClassList); + } colDiv.append(divRowCol); }) }) diff --git a/corsscripts/stacksortable.min.js b/corsscripts/stacksortable.min.js index 78794e9c28d4492c40b00f29405aff76187e4699..a6211622495424789aef421ac3422a6a3f08ba2f 100644 --- a/corsscripts/stacksortable.min.js +++ b/corsscripts/stacksortable.min.js @@ -25,7 +25,8 @@ add_index(index){for(const[i,value]of index.entries()){if(i===0){var idx=this._c document.getElementById("index").append(idx);}} add_reorientation_button(){var btn=document.createElement("button");btn.id="orientation";btn.setAttribute("class","parsons-button");var icon=document.createElement("i");icon.setAttribute("class","fa fa-refresh");btn.append(icon);btn.addEventListener("click",()=>this._flip_orientation());document.body.insertBefore(btn,document.getElementById("containerRow"));} create_row_col_divs(){var usedClassList=(!this.grid||this.orientation==="col")?(["list-group",this.orientation,"usedList"]):([this.orientation,"usedList"]);var itemClass=(this.orientation==="col")?"row":"col";var itemClassList=[itemClass,"usedList"];var availClassList=(!this.grid||this.orientation==="col")?["list-group",this.orientation]:[this.orientation];var container=document.getElementById("containerRow");if(this.use_index){var indexCol=document.createElement("div");indexCol.id="index";indexCol.classList.add(...usedClassList);container.append(indexCol);} -this.colIds.forEach((id)=>{var colDiv=document.createElement("ul");colDiv.id=id;colDiv.classList.add(...usedClassList);container.append(colDiv);});if(this.rows!==""){this.colIds.forEach((colId)=>{var colDiv=document.getElementById(colId);colDiv.classList.add("container");this.rowColIds[colId].forEach((rowColId)=>{var divRowCol=document.createElement("li");divRowCol.id=rowColId;divRowCol.classList.add(...itemClassList);colDiv.append(divRowCol);})})};var availDiv=document.createElement("ul");availDiv.id=this.ids.available;availDiv.classList.add(...availClassList);if(this.orientation==="col"){container.append(availDiv);}else{container.insertBefore(availDiv,container.firstChild);} +this.colIds.forEach((id)=>{var colDiv=document.createElement("ul");colDiv.id=id;colDiv.classList.add(...usedClassList);container.append(colDiv);});if(this.rows!==""){this.colIds.forEach((colId)=>{var colDiv=document.getElementById(colId);colDiv.classList.add("container");this.rowColIds[colId].forEach((rowColId)=>{var divRowCol=document.createElement("li");divRowCol.id=rowColId;if(this.orientation==="row"){divRowCol.classList.add(...itemClassList,...["col-rigid"]);}else{divRowCol.classList.add(...itemClassList);} +colDiv.append(divRowCol);})})};var availDiv=document.createElement("ul");availDiv.id=this.ids.available;availDiv.classList.add(...availClassList);if(this.orientation==="col"){container.append(availDiv);}else{container.insertBefore(availDiv,container.firstChild);} this.used=this.usedId.map(idList=>idList.map(id=>document.getElementById(id)));this.available=document.getElementById(this.availableId);} generate_available(){this.state.available.forEach(key=>this.available.append(this._create_li(key,this.item_height_width)));} generate_used(){for(const[i,value]of this.state.used.entries()){if(this.rows!==""&&this.columns!==""){for(const[j,val]of value.entries()){this._apply_attrs(this.used[i][j],this.container_height_width);val.forEach(key=>this.used[i][j].append(this._create_li(key,this.item_height_width)));}}else{value[0].forEach(key=>this.used[i][0].append(this._create_li(key,this.item_height_width)));}}} diff --git a/lang/en/qtype_stack.php b/lang/en/qtype_stack.php index 73917204f50e46844c437a27156dad23f63f6ba7..0ef0872ec48b2c0716184692bebd17286afe57c8 100644 --- a/lang/en/qtype_stack.php +++ b/lang/en/qtype_stack.php @@ -949,7 +949,7 @@ $string['stackBlock_parsons_unknown_named_version'] = 'The Parson\'s block only $string['stackBlock_parsons_unknown_mathjax_version'] = 'The Parson\'s block only supports MathJax versions {$a->mjversion} for the mathjax parameter.'; $string['stackBlock_parsons_ref'] = 'The Parson\'s block only supports referencing inputs present in the same CASText section \'{$a->var}\' does not exist here.'; $string['stackBlock_parsons_param'] = 'The Parson\'s block supports only these parameters in this context: \'{$a->param}\'.'; -$string['stackBlock_parsons_contents'] = 'The contents of a Parson\'s block must be a either a JSON of the form {#stackjson_stringify(steps)#}, where `steps` is the two-dimensional Maxima array containing key, value pairs of items, or of the form {\'steps\' : {#stackjson_stringify(steps)#}, \'options\' : {JSON containing Sortable options}, \'header\' : [List of headers], \'available_header\' : \'string containing header for the available list\', \'index\' : [List containing the index]}, where the \'options\', \'header\', \'available_header\', and \'index\' keys are optional. Alternatively, the contents of the Parsons block may contain raw JSON equivalents. Make sure that the `steps` Maxima variable is of the correct format. Note that all steps must be strings. See the https://docs.stack-assessment.org/en/Authoring/Parsons/ for details.'; +$string['stackBlock_parsons_contents'] = 'The contents of a Parson\'s block must be a either a JSON of the form {#stackjson_stringify(steps)#}, where `steps` is the two-dimensional Maxima array containing key, value pairs of items, or of the form {\'steps\' : {#stackjson_stringify(steps)#}, \'options\' : {JSON containing Sortable options}, \'header\' : [List of headers], \'available_header\' : \'string containing header for the available list\', \'index\' : [List containing the index]}, where the \'options\', \'header\', \'available_header\', and \'index\' keys are optional. Alternatively, the contents of the Parsons block may contain raw JSON equivalents. Make sure that the `steps` Maxima variable is of the correct format. Note that all steps must be strings. See https://docs.stack-assessment.org/en/Authoring/Parsons/ for details.'; $string['stackBlock_incorrect_header_length'] = 'The list of headers should have the same length as the number of columns passed to the block header.'; $string['stackBlock_incorrect_available_header_type'] = 'The header for the available list should be passed as a string or a list of length one.'; $string['stackBlock_incorrect_index_length'] = 'The length of the index should be one more than the number of rows passed to the block header. An item in the top-left corner should always go in the index'; diff --git a/stack/cas/castext2/blocks/parsons.block.php b/stack/cas/castext2/blocks/parsons.block.php index 0d6080a23a7750b8cb0096292d0eac817fed4d92..0c17c8e4537e2feeeb2db3553492f20455dfe198 100644 --- a/stack/cas/castext2/blocks/parsons.block.php +++ b/stack/cas/castext2/blocks/parsons.block.php @@ -302,8 +302,10 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { $code .= 'var possibleOptionKeys = Object.keys(sortableUsed[0][0].options).concat(SUPPORTED_CALLBACK_FUNCTIONS);' . "\n"; // Now set appropriate options. - $code .= 'sortableUsed.forEach((usedList) => Object.entries(stackSortable.options.used).forEach( - ([key, val]) => usedList[0].option(key, val)));' . "\n"; + $code .= 'sortableUsed.forEach((sortableList) => + sortableList.forEach((sortable) => + Object.entries(stackSortable.options.used).forEach( + ([key, val]) => sortable.option(key, val))));' . "\n"; $code .= 'var sortableAvailable = Sortable.create(availableList, stackSortable.options.available);' . "\n"; // Add the onSort option in order to link up to input and overwrite user onSort if passed. $code .= 'sortableUsed.forEach((sortableList) =>