From b44e7f2a9fec3c3e96e2865a7e0154009ac6b449 Mon Sep 17 00:00:00 2001 From: PMKuipers Date: Tue, 24 Oct 2023 21:55:53 +0200 Subject: [PATCH] Reworked form bases and added integer text field --- amd/build/util/formfields.min.js | 2 +- amd/build/util/formfields.min.js.map | 2 +- amd/src/util/formfields.js | 27 ++++-- classes/{local/forms => form}/formbase.php | 2 +- .../forms => form}/studyplan_editform.php | 12 +-- classes/form/text_integer.php | 89 +++++++++++++++++++ classes/local/form_elements/text_integer.php | 40 --------- classes/utilityservice.php | 17 ++-- templates/form/element_text_integer.mustache | 22 +++++ version.php | 2 +- 10 files changed, 154 insertions(+), 61 deletions(-) rename classes/{local/forms => form}/formbase.php (98%) rename classes/{local/forms => form}/studyplan_editform.php (98%) create mode 100644 classes/form/text_integer.php delete mode 100644 classes/local/form_elements/text_integer.php create mode 100644 templates/form/element_text_integer.mustache diff --git a/amd/build/util/formfields.min.js b/amd/build/util/formfields.min.js index 195405e..88e51a7 100644 --- a/amd/build/util/formfields.min.js +++ b/amd/build/util/formfields.min.js @@ -1,3 +1,3 @@ -define("local_treestudyplan/util/formfields",["exports","./debugger"],(function(_exports,_debugger){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.text_integer=function(id){var element=document.getElementById(id);debug.warn("Initializing form element text_integer on ",id,element)};var debug=new(_debugger=(obj=_debugger)&&obj.__esModule?obj:{default:obj}).default("formfields")})); +define("local_treestudyplan/util/formfields",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.text_integer=function(id){var unsigned=arguments.length>1&&void 0!==arguments[1]&&arguments[1],element=document.getElementById(id);element&&element.addEventListener("input",(function(){var val=element.value;if(""!=val)return!(isNaN(val)&&(unsigned||"-"!=val)||unsigned&&val<0)||(element.value=unsigned?val.replace(/[^0-9]/g,""):val.replace(/[^0-9-]/g,"").replace(/(.{1})(-)/g,"$1"),!1)}))}})); //# sourceMappingURL=formfields.min.js.map \ No newline at end of file diff --git a/amd/build/util/formfields.min.js.map b/amd/build/util/formfields.min.js.map index da7180a..f050646 100644 --- a/amd/build/util/formfields.min.js.map +++ b/amd/build/util/formfields.min.js.map @@ -1 +1 @@ -{"version":3,"file":"formfields.min.js","sources":["../../src/util/formfields.js"],"sourcesContent":["import Debugger from './debugger';\nconst debug = new Debugger(\"formfields\");\n/**\n * convert a text field into an integer only text field\n * @param {Date|string} id The Id of the form field\n */\nexport function text_integer(id){\n const element = document.getElementById(id);\n debug.warn(\"Initializing form element text_integer on \",id,element);\n}"],"names":["id","element","document","getElementById","debug","warn"],"mappings":"mMAM6BA,QACnBC,QAAUC,SAASC,eAAeH,IACxCI,MAAMC,KAAK,6CAA6CL,GAAGC,cAPzDG,MAAQ,yEAAa"} \ No newline at end of file +{"version":3,"file":"formfields.min.js","sources":["../../src/util/formfields.js"],"sourcesContent":["/**\n * convert a text field into an integer only text field\n * @param {string} id The Id of the form field\n * @param {bool} unsigned Allow only unsigned values\n */\nexport function text_integer(id,unsigned=false){\n const element = document.getElementById(id);\n\n if (element) {\n element.addEventListener(\"input\",() => {\n var val = element.value;\n if (val != '') {\n if ((isNaN(val) && !(!unsigned && val == '-')) || (unsigned && val < 0)) {\n // Set input value empty\n if (unsigned) {\n element.value = val.replace(/[^0-9]/g,'');\n } else {\n element.value = val.replace(/[^0-9-]/g,'').replace(/(.{1})(-)/g,'$1');\n }\n return false;\n } else {\n return true;\n }\n }\n });\n }\n}"],"names":["id","unsigned","element","document","getElementById","addEventListener","val","value","isNaN","replace"],"mappings":"oKAK6BA,QAAGC,iEACtBC,QAAUC,SAASC,eAAeJ,IAEpCE,SACAA,QAAQG,iBAAiB,SAAQ,eACzBC,IAAMJ,QAAQK,SACP,IAAPD,YACKE,MAAMF,OAAWL,UAAmB,KAAPK,MAAiBL,UAAYK,IAAM,KAG7DJ,QAAQK,MADRN,SACgBK,IAAIG,QAAQ,UAAU,IAEtBH,IAAIG,QAAQ,WAAW,IAAIA,QAAQ,aAAa,OAE7D"} \ No newline at end of file diff --git a/amd/src/util/formfields.js b/amd/src/util/formfields.js index b072421..aaadf25 100644 --- a/amd/src/util/formfields.js +++ b/amd/src/util/formfields.js @@ -1,10 +1,27 @@ -import Debugger from './debugger'; -const debug = new Debugger("formfields"); /** * convert a text field into an integer only text field - * @param {Date|string} id The Id of the form field + * @param {string} id The Id of the form field + * @param {bool} unsigned Allow only unsigned values */ -export function text_integer(id){ +export function text_integer(id,unsigned=false){ const element = document.getElementById(id); - debug.warn("Initializing form element text_integer on ",id,element); + + if (element) { + element.addEventListener("input",() => { + var val = element.value; + if (val != '') { + if ((isNaN(val) && !(!unsigned && val == '-')) || (unsigned && val < 0)) { + // Set input value empty + if (unsigned) { + element.value = val.replace(/[^0-9]/g,''); + } else { + element.value = val.replace(/[^0-9-]/g,'').replace(/(.{1})(-)/g,'$1'); + } + return false; + } else { + return true; + } + } + }); + } } \ No newline at end of file diff --git a/classes/local/forms/formbase.php b/classes/form/formbase.php similarity index 98% rename from classes/local/forms/formbase.php rename to classes/form/formbase.php index 6eb636d..4e13c5a 100644 --- a/classes/local/forms/formbase.php +++ b/classes/form/formbase.php @@ -1,6 +1,6 @@ dirroot."/lib/formslib.php"); abstract class formbase extends \moodleform { diff --git a/classes/local/forms/studyplan_editform.php b/classes/form/studyplan_editform.php similarity index 98% rename from classes/local/forms/studyplan_editform.php rename to classes/form/studyplan_editform.php index 0015e6e..b10fc53 100644 --- a/classes/local/forms/studyplan_editform.php +++ b/classes/form/studyplan_editform.php @@ -1,11 +1,11 @@ addElement('text_integer',$field, get_string('studyplan_slots','local_treestudyplan'), - []); + ["unsigned" => true]); $mform->setType($field, PARAM_INT); $mform->addRule($field, null, 'required', null, 'client'); @@ -223,7 +223,7 @@ class studyplan_editform extends formbase { $field = 'bistate_thresh_excellent'; $mform->addElement('text_integer',$field, get_string('setting_bistate_thresh_excellent','local_treestudyplan'), - [], + ["unsigned" => false], ); $mform->setType($field, PARAM_INT); $mform->hideIf($field, "aggregation", "neq", "bistate"); @@ -231,7 +231,7 @@ class studyplan_editform extends formbase { $field = 'bistate_thresh_good'; $mform->addElement('text_integer',$field, get_string('setting_bistate_thresh_good','local_treestudyplan'), - [], + ["unsigned" => true], ); $mform->setType($field, PARAM_INT); $mform->hideIf($field, "aggregation", "neq", "bistate"); @@ -239,7 +239,7 @@ class studyplan_editform extends formbase { $field = 'bistate_thresh_completed'; $mform->addElement('text_integer',$field, get_string('setting_bistate_thresh_completed','local_treestudyplan'), - [], + ["unsigned" => true], ); $mform->setType($field, PARAM_INT); $mform->hideIf($field, "aggregation", "neq", "bistate"); diff --git a/classes/form/text_integer.php b/classes/form/text_integer.php new file mode 100644 index 0000000..687811b --- /dev/null +++ b/classes/form/text_integer.php @@ -0,0 +1,89 @@ +libdir . "/form/text.php"); + + +class text_integer extends MoodleQuickForm_text { +/** + * Accepts a renderer + * + * @param object $renderer An HTML_QuickForm_Renderer object + * @param bool $required Whether an element is required + * @param string $error An error message associated with an element + * @return void + */ + public function accept(&$renderer, $required = false, $error = null) { + global $OUTPUT; + $elementname = $this->getName(); + // Make sure the element has an id. + $this->_generateId(); + $advanced = isset($renderer->_advancedElements[$elementname]); + $elementcontext = $this->export_for_template($OUTPUT); + + $helpbutton = ''; + if (method_exists($this, 'getHelpButton')) { + $helpbutton = $this->getHelpButton(); + } + $label = $this->getLabel(); + + /* + $text = ''; + if (method_exists($this, 'getText')) { + // There currently exists code that adds a form element with an empty label. + // If this is the case then set the label to the description. + if (empty($label)) { + $label = $this->getText(); + } else { + $text = $this->getText(); + } + }*/ + + $unsigned = (isset($this->_attributes['unsigned']) && $this->_attributes['unsigned']); + $context = array( + 'element' => $elementcontext, + 'label' => $label, + 'unsigned' => ($unsigned)?true:false , + 'required' => $required, + 'advanced' => $advanced, + 'helpbutton' => $helpbutton, + 'error' => $error, + ); + $html = $OUTPUT->render_from_template('local_treestudyplan/form/element_text_integer', $context); + if ($renderer->_inGroup) { + $this->_groupElementTemplate = $html; + } + if (($renderer->_inGroup) && !empty($renderer->_groupElementTemplate)) { + $renderer->_groupElementTemplate = $html; + } else if (!isset($renderer->_templates[$elementname])) { + $renderer->_templates[$elementname] = $html; + } + + if (in_array($elementname, $renderer->_stopFieldsetElements) && $renderer->_fieldsetsOpen > 0) { + $renderer->_html .= $renderer->_closeFieldsetTemplate; + $renderer->_fieldsetsOpen--; + } + $renderer->_html .= $html; + } + + public static function Register() { + global $CFG; + MoodleQuickForm::registerElementType( + // The custom element is named `course_competency_rule`. + // This is the element name used in the `addElement()` function. + 'text_integer', + + // This is where it's definition is defined. + // This does not currently support class auto-loading. + "$CFG->dirroot/local/treestudyplan/classes/form/text_integer.php", + + // The class name of the element. + 'local_treestudyplan\form\text_integer' + ); + } +} \ No newline at end of file diff --git a/classes/local/form_elements/text_integer.php b/classes/local/form_elements/text_integer.php deleted file mode 100644 index d901518..0000000 --- a/classes/local/form_elements/text_integer.php +++ /dev/null @@ -1,40 +0,0 @@ -libdir . "/form/text.php"); - - -class text_integer extends MoodleQuickForm_text { - public function toHtml() - { - global $PAGE; - // Add number type attribute - $this->_attributes['type'] = 'number'; - - $html = parent::toHtml(); - // Add javascript call to handle stuff - $PAGE->requires->js_call_amd('local_treestudyplan/util/formfields', 'text_integer', ['id' => $this->getAttribute('id')]); - return $html; - } - - public static function Register() { - global $CFG; - MoodleQuickForm::registerElementType( - // The custom element is named `course_competency_rule`. - // This is the element name used in the `addElement()` function. - 'text_integer', - - // This is where it's definition is defined. - // This does not currently support class auto-loading. - "$CFG->dirroot/local/treestudyplan/classes/local/form_elements/text_integer.php", - - // The class name of the element. - 'local_treestudyplan\local\form_elements\text_integer' - ); - } -} \ No newline at end of file diff --git a/classes/utilityservice.php b/classes/utilityservice.php index fad8b9e..08d2cca 100644 --- a/classes/utilityservice.php +++ b/classes/utilityservice.php @@ -52,15 +52,20 @@ class utilityservice extends \external_api { but we do need to check it's existence to give a nice developer warning and protect against some forms of hacking */ - $modmoodleform = "$CFG->dirroot/local/treestudyplan/classes/local/forms/{$formname}.php"; + $modmoodleform = "$CFG->dirroot/local/treestudyplan/classes/form/{$formname}.php"; if (!file_exists($modmoodleform)) { - throw new \moodle_exception('noformdesc', 'local_treestudyplan');; + throw new \moodle_exception('noformfile', 'local_treestudyplan'); } - $mformclassname = "\\local_treestudyplan\\local\\forms\\{$formname}"; - $jsonparams = json_decode($params); - $mform = new $mformclassname( $jsonparams, $ajaxformdata); - return $mform; + $mformclassname = "\\local_treestudyplan\\form\\{$formname}"; + // Check if the form is a subclass of formbase. + if ( is_a($mformclassname,"\\local_treestudyplan\\form\\formbase",true)) { + $jsonparams = json_decode($params); + $mform = new $mformclassname( $jsonparams, $ajaxformdata); + return $mform; + } else { + throw new \moodle_exception('notformbase', 'local_treestudyplan'); + } } /** diff --git a/templates/form/element_text_integer.mustache b/templates/form/element_text_integer.mustache new file mode 100644 index 0000000..3b161e9 --- /dev/null +++ b/templates/form/element_text_integer.mustache @@ -0,0 +1,22 @@ +{{< core_form/element-template }} + {{$element}} + + {{/element}} +{{/ core_form/element-template }} +{{#js}} +require(['local_treestudyplan/util/formfields'], function(formfields) { + formfields.text_integer({{#quote}}{{element.id}}{{/quote}},{{unsigned}}); +}); +{{/js}} \ No newline at end of file diff --git a/version.php b/version.php index c9780bb..2a5f54c 100644 --- a/version.php +++ b/version.php @@ -22,7 +22,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494). -$plugin->version = 2023102300; // YYYYMMDDHH (year, month, day, iteration). +$plugin->version = 2023102401; // YYYYMMDDHH (year, month, day, iteration). $plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11). $plugin->release = "1.1.0-b";