From 924565f64a442c9b1d64f844ba38f3cc0fe069d1 Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Wed, 8 Nov 2023 16:11:44 +0800 Subject: [PATCH] MDL-80041 gradereport_singleview: Implement grade validation Implement grade validation for numeric grade overrides by setting the type attribute for the grade input to number and setting a min and max attribute values. Submitting the form with invalid values will trigger built-in validation of the inputs. --- .../classes/local/ui/finalgrade.php | 23 +++++++- .../classes/local/ui/text_attribute.php | 58 +++++++++++++++++++ grade/report/singleview/js/singleview.js | 2 +- .../templates/text_attribute.mustache | 9 ++- 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/grade/report/singleview/classes/local/ui/finalgrade.php b/grade/report/singleview/classes/local/ui/finalgrade.php index 6ec1d28a0e0..075f56b4c8d 100644 --- a/grade/report/singleview/classes/local/ui/finalgrade.php +++ b/grade/report/singleview/classes/local/ui/finalgrade.php @@ -131,13 +131,34 @@ class finalgrade extends grade_attribute_format implements unique_value, be_disa $this->is_readonly() ); } else { - return new text_attribute( + $textattribute = new text_attribute( $this->get_name(), $this->get_value(), $this->get_label(), $this->is_disabled(), $this->is_readonly() ); + + // Set min/max attributes, if applicable. + $textattribute->set_type('number'); + $gradeitem = $this->grade->grade_item; + $decimals = $gradeitem->get_decimals(); + + // Min attribute. + $minvalue = null; + if (isset($gradeitem->grademin)) { + $minvalue = format_float($gradeitem->grademin, $decimals); + } + $textattribute->set_min($minvalue); + + // Max attribute. + $maxvalue = null; + if (isset($gradeitem->grademax)) { + $maxvalue = format_float($gradeitem->grademax, $decimals); + } + $textattribute->set_max($maxvalue); + + return $textattribute; } } diff --git a/grade/report/singleview/classes/local/ui/text_attribute.php b/grade/report/singleview/classes/local/ui/text_attribute.php index 164f1ec4e94..9aeeb85fa45 100644 --- a/grade/report/singleview/classes/local/ui/text_attribute.php +++ b/grade/report/singleview/classes/local/ui/text_attribute.php @@ -44,6 +44,24 @@ class text_attribute extends element { /** @var bool If this is a read-only input. */ private bool $isreadonly; + /** + * @var string|null The input type to pass to the template. + * This defaults to text but can be overridden to number for grade inputs. + */ + private $type = null; + + /** + * @var string|null The value to set for the input's `min` attribute. + * This is set if a minimum grade is provided for the grade input field. + */ + private $min = null; + + /** + * @var string|null The value to set for the input's `max` attribute. + * This is set if a maximum grade is provided for the grade input field. + */ + private $max = null; + /** * Constructor * @@ -89,6 +107,46 @@ class text_attribute extends element { $context->label = get_string('gradefor', 'gradereport_singleview', $this->label); } + // Set this input field with type="number" if the decimal separator for current language is set to a period. + // Other decimal separators may not be recognised by browsers yet which may cause issues when entering grades. + $decsep = get_string('decsep', 'core_langconfig'); + $context->isnumeric = $this->type === 'number' && $decsep === '.'; + if ($context->isnumeric) { + $context->type = $this->type; + $context->min = $this->min; + $context->max = $this->max; + } + return $OUTPUT->render_from_template('gradereport_singleview/text_attribute', $context); } + + /** + * Input type setter. + * + * @param string|null $type + * @return void + */ + public function set_type(?string $type): void { + $this->type = $type; + } + + /** + * Min attribute setter. + * + * @param string|null $min + * @return void + */ + public function set_min(?string $min): void { + $this->min = $min; + } + + /** + * Max attribute setter. + * + * @param string|null $max + * @return void + */ + public function set_max(?string $max): void { + $this->max = $max; + } } diff --git a/grade/report/singleview/js/singleview.js b/grade/report/singleview/js/singleview.js index aa983ab394a..7878426fe03 100644 --- a/grade/report/singleview/js/singleview.js +++ b/grade/report/singleview/js/singleview.js @@ -107,7 +107,7 @@ M.gradereport_singleview.init = function(Y) { var interest = '_' + itemid + '_' + userid; - Y.all('input[name$=' + interest + ']').filter('input[type=text]').each(function(text) { + Y.all('input[name$=' + interest + ']').filter('input[data-uielement=text]').each(function(text) { text.getDOMNode().disabled = !checked; }); // deal with scales that are not text... UCSB diff --git a/grade/report/singleview/templates/text_attribute.mustache b/grade/report/singleview/templates/text_attribute.mustache index 008e238c08a..ff687248549 100644 --- a/grade/report/singleview/templates/text_attribute.mustache +++ b/grade/report/singleview/templates/text_attribute.mustache @@ -24,7 +24,11 @@ "name": "Awesome-report", "label": "Text label", "value": "Text information", - "disabled": "true" + "disabled": false, + "type": "number", + "isnumeric": true, + "min": "0", + "max": "100" } }} {{#readonly}} @@ -32,6 +36,7 @@ {{/readonly}} {{^readonly}} {{#label}}{{/label}} - + {{/readonly}}