diff --git a/stack/cas/castext2/blocks/parsons.block.php b/stack/cas/castext2/blocks/parsons.block.php index 26faee724adf7de8ea59be6eea4d5d9b425f082f..231e7c2224b2eddc0c4fc3d25684180104c6b1af 100644 --- a/stack/cas/castext2/blocks/parsons.block.php +++ b/stack/cas/castext2/blocks/parsons.block.php @@ -34,7 +34,7 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ], 'local' => [ 'css' => 'cors://sortable.min.css', - 'js' => 'cors://sortable.min.js', + 'js' => 'cors://sortablecore.min.js', ], ]; @@ -43,15 +43,15 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { // Define iframe params. $xpars = []; - + // Input identifiers. - $inputs = []; + $inputs = []; // Whether to have all keys in available list cloned. - $clone = 'false'; + $clone = 'false'; // MathJax version (either "2" or "3"). - $mathjaxversion = '2'; + $mathjaxversion = '2'; // Number of available columns. $columns = null; @@ -59,14 +59,14 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { // Number of available rows. $rows = null; - // Tranpose + // Tranpose. $transpose = false; - // Item height - $item_height = null; + // Item height. + $itemheight = null; - // Item width - $item_width = null; + // Item width. + $itemwidth = null; foreach ($this->params as $key => $value) { if ($key === 'clone') { @@ -78,9 +78,9 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { } else if ($key === 'transpose') { $transpose = ($value === 'true'); } else if ($key === 'item-height') { - $item_height = $value; + $itemheight = $value; } else if ($key === 'item-width') { - $item_width = $value; + $itemwidth = $value; } else if ($key !== 'input') { $xpars[$key] = $value; } else { @@ -156,25 +156,17 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { } // Identify default proof mode based on block header params - // Note that proof mode behaves the same as the general mode, but we just - // need to redefine columns + // Note that proof mode behaves the same as the general mode, but we just + // need to redefine columns. $proofmode = ($columns === null && $rows === null); $gridmode = !$proofmode; - $fixedgridmode = ($columns !== null && $rows !== null); $columns = $proofmode ? '1' : $columns; // Add correctly oriented container divs for the proof lists to be accessed by sortable. $orientation = $transpose ? 'row' : 'col'; $tmprows = $transpose ? $columns : $rows; $columns = $transpose ? $rows : $columns; $rows = $tmprows; - /*$outer = $orientation === 'horizontal' ? 'row' : 'col'; - $inner = $orientation === 'horizontal' ? 'col' : 'row'; - $innerui = '<ul class="list-group ' . $inner . '" id="usedList"></ul> - <ul class="list-group ' . $inner . '" id="availableList"></ul>'; - - $r->items[] = new MP_String("<button type='button' class='parsons-button' id='orientation'> - <i class='fa fa-refresh'></i></button>"); - */ + $r->items[] = new MP_String("<button type='button' class='parsons-button' id='resize'> <i class='fa fa-expand'></i></button>"); if ($clone === 'true') { @@ -184,11 +176,6 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { <i class="fa fa-times-circle "></i></div>'); } - /*$r->items[] = new MP_String('<div class="container" id="sortableContainer" style="' . $astyle . '"> - <div class=row>' . $innerui . ' - </div> - </div>');*/ - $r->items[] = new MP_String('<div class="container row" id="containerRow" style="' . $astyle . '"></div>'); // JS script. @@ -204,9 +191,6 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { stack_cors_link('stacksortable.min.js') . "';\n"; $r->items[] = new MP_String($importcode); - // Add flip orientation listener to the orientation button. - // TO-DO: automatically set orientation based on device? - //$r->items[] = new MP_String('add_orientation_listener("orientation", "usedList", "availableList");' . "\n"); // Add the resize button listener. $r->items[] = new MP_String('document.getElementById("resize").addEventListener( "click", () => {stack_js.resize_containing_frame("' . $width . '", get_iframe_height() + "px");});' . "\n"); @@ -230,21 +214,24 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { } $r->items[] = new MP_String(";\n"); - // Parse steps and Sortable options separately if they exist. Invalid JSON will be identified by preprocess_steps function. + // Define default headers. if ($proofmode) { $code = 'var headers = ["' . stack_string('stackBlock_parsons_used_header') . '"];' . "\n"; } else { $code = 'var headers = [' . implode(', ', range(1, intval($columns))) . '];' . "\n"; } $code .= 'var available_header = "' . stack_string('stackBlock_parsons_available_header') . '";' . "\n"; + + // Parse steps, Sortable options, headers and index separately if they exist. + // Invalid JSON will be identified by preprocess_steps function. $code .= 'var sortableUserOpts = {};' . "\n"; $code .= 'var valid, index;' . "\n"; - $code .= '[proofSteps, sortableUserOpts, headers, available_header, index, valid] = + $code .= '[proofSteps, sortableUserOpts, headers, available_header, index, valid] = preprocess_steps(proofSteps, sortableUserOpts, headers, available_header, index);' . "\n"; // If the author's JSON has invalid format throw an error. - //$code .= 'if (valid === false) - // {stack_js.display_error("' . stack_string('stackBlock_parsons_contents') . '");}' . "\n"; + $code .= 'if (valid === false) + {stack_js.display_error("' . stack_string('stackBlock_parsons_contents') . '");}' . "\n"; // Link up to STACK inputs. if (count($inputs) > 0) { @@ -257,9 +244,9 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { // Instantiate STACK sortable helper class. $code .= 'const stackSortable = new stack_sortable(proofSteps, id, sortableUserOpts, "' . - $clone .'", "' . $columns .'", "' . $rows . '", "' . $orientation . '", index, "' . $gridmode . '", "' . $item_height . '", - "' . $item_width . '");' . "\n"; - // Generate the two lists in HTML. + $clone .'", "' . $columns .'", "' . $rows . '", "' . $orientation . '", index, "' . $gridmode . '", + "' . $itemheight . '", "' . $itemwidth . '");' . "\n"; + // Generate the two lists, headers and index in HTML. $code .= 'stackSortable.add_reorientation_button();' . "\n"; $code .= 'stackSortable.create_row_col_divs();' . "\n"; $code .= 'if (index !== undefined) {stackSortable.add_index(index);};' . "\n"; @@ -269,16 +256,18 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { // Create the Sortable objects. // First, instantiate with default options first in order to extract all possible options for validation. - $code .= 'var sortableUsed = - stackSortable.ids.used.map((idList) => idList.map((usedId) => Sortable.create(document.getElementById(usedId), stackSortable.options.used)));' . "\n"; + $code .= 'var sortableUsed = + stackSortable.ids.used.map((idList) => + idList.map((usedId) => Sortable.create(document.getElementById(usedId), stackSortable.options.used)));' . "\n"; $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((usedList) => Object.entries(stackSortable.options.used).forEach( + ([key, val]) => usedList[0].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) => - sortableList.forEach((sortable) => + $code .= 'sortableUsed.forEach((sortableList) => + sortableList.forEach((sortable) => sortable.option("onSort", () => { stackSortable.update_state(sortableUsed, sortableAvailable);}) ) @@ -299,9 +288,9 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { } // Add double-click events for proof. - //if ($proofmode) { - // $code .= 'stackSortable.add_dblclick_listeners(sortableUsed, sortableAvailable);' . "\n"; - //} + if ($proofmode) { + $code .= 'stackSortable.add_dblclick_listeners(sortableUsed, sortableAvailable);' . "\n"; + } // Typeset MathJax. MathJax 2 uses Queue, whereas 3 works with promises. $code .= ($mathjaxversion === "2") ? @@ -343,9 +332,10 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { &$errors = [], $options = [] ): bool { - // TO-DO : matching validations: (1) check values of transpose ('true' or 'false'); (2) check values of rows/columns + // TO-DO : matching validations: (1) check values of transpose ('true' or 'false'); (2) check values of rows/columns // (only string containing ints); (3) check rows is not passed without columns; (4) check length of headers - // matches columns (think this has to be in js); (5) check index length matches length of rows if rows passed (again js probably). + // matches columns (think this has to be in js); (5) check index length matches length of rows if rows passed + // (again js probably). // Basically, check that the dimensions have units we know. // Also that the references make sense. @@ -436,16 +426,16 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { $valids = null; foreach ($this->params as $key => $value) { if ($key !== 'width' && $key !== 'height' && $key !== 'aspect-ratio' && - $key !== 'version' && $key !== 'overridecss' && $key !== 'input' - && $key !== 'clone' && $key !== 'columns' && $key !== 'rows' && + $key !== 'version' && $key !== 'overridecss' && $key !== 'input' + && $key !== 'clone' && $key !== 'columns' && $key !== 'rows' && $key !== 'transpose' && $key !== 'item-height' && $key !== 'item-width') { $err[] = "Unknown parameter '$key' for Parson's block."; $valid = false; if ($valids === null) { $valids = [ 'width', 'height', 'aspect-ratio', 'version', 'overridecss', - 'overridejs', 'input', 'clone', 'columns', 'rows', 'transpose', 'item-height', - 'item-width' + 'overridejs', 'input', 'clone', 'columns', 'rows', 'transpose', 'item-height', + 'item-width', ]; $err[] = stack_string('stackBlock_parsons_param', [ 'param' => implode(', ', $valids),