From b6715a7dda8086b3d0a0ef907a455511dbd94c85 Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Tue, 22 Aug 2023 12:28:34 +0200 Subject: [PATCH] MDL-79102 forms: Add uniqueid var to avoid duplicated ids A new static variable, $uniqueid, has been introduced to the moodleform class. This enhancement allows for the simultaneous presence of multiple forms with distinct IDs for action buttons on a single page, thereby mitigating the accessibility concern associated with duplicated IDs. --- .../bulk_activity_completion_renderer.php | 16 +++++--- course/defaultcompletion.php | 5 ++- lib/formslib.php | 37 ++++++++++++++----- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/course/classes/output/bulk_activity_completion_renderer.php b/course/classes/output/bulk_activity_completion_renderer.php index f923baa333f..1b9de5b0fe3 100644 --- a/course/classes/output/bulk_activity_completion_renderer.php +++ b/course/classes/output/bulk_activity_completion_renderer.php @@ -83,13 +83,17 @@ class core_course_bulk_activity_completion_renderer extends plugin_renderer_base // Only create the form if it's different from the one that has been sent. $modform = $form; if (empty($form) || !in_array($module->id, array_keys($modules))) { - $modform = new \core_completion_defaultedit_form(null, [ - 'course' => $course, - 'modules' => [ - $module->id => $module, + $modform = new \core_completion_defaultedit_form( + null, + [ + 'course' => $course, + 'modules' => [ + $module->id => $module, + ], + 'displaycancel' => false, + 'forceuniqueid' => true, ], - 'displaycancel' => false, - ]); + ); $module->modulecollapsed = true; } $module->formhtml = $modform->render(); diff --git a/course/defaultcompletion.php b/course/defaultcompletion.php index cc443214a40..88e68370466 100644 --- a/course/defaultcompletion.php +++ b/course/defaultcompletion.php @@ -69,7 +69,10 @@ foreach ($allmodules->modules as $module) { $form = null; if (!empty($modules)) { - $form = new core_completion_defaultedit_form(null, ['course' => $course, 'modules' => $modules, 'displaycancel' => false]); + $form = new core_completion_defaultedit_form( + null, + ['course' => $course, 'modules' => $modules, 'displaycancel' => false, 'forceuniqueid' => true] + ); if (!$form->is_cancelled() && $data = $form->get_data()) { $data->modules = $modules; $manager->apply_default_completion($data, $form->has_custom_completion_rules(), $form->get_suffix()); diff --git a/lib/formslib.php b/lib/formslib.php index 2eb2f78bd0d..30abf663dad 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -146,6 +146,9 @@ abstract class moodleform { /** @var bool|null stores the validation result of this form or null if not yet validated */ protected $_validated = null; + /** @var int Unique identifier to be used for action buttons. */ + static protected $uniqueid = 0; + /** * The constructor function calls the abstract function definition() and it will then * process and clean and attempt to validate incoming data. @@ -1359,22 +1362,36 @@ abstract class moodleform { * @param string $submitlabel label for submit button, defaults to get_string('savechanges') */ public function add_action_buttons($cancel = true, $submitlabel = null) { - if (is_null($submitlabel)){ + if (is_null($submitlabel)) { $submitlabel = get_string('savechanges'); } - $mform =& $this->_form; - if ($cancel){ - //when two elements we need a group - $buttonarray=array(); - $buttonarray[] = &$mform->createElement('submit', 'submitbutton', $submitlabel); - $buttonarray[] = &$mform->createElement('cancel'); - $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); + $mform = $this->_form; + // Only use uniqueid if the form defines it needs to be used. + $forceuniqueid = false; + if (is_array($this->_customdata)) { + $forceuniqueid = $this->_customdata['forceuniqueid'] ?? false; + } + // Keep the first action button as submitbutton (without uniqueid) because single forms pages expect this to happen. + $submitbuttonname = $forceuniqueid && $this::$uniqueid > 0 ? 'submitbutton_' . $this::$uniqueid : 'submitbutton'; + if ($cancel) { + // When two elements we need a group. + $buttonarray = [ + $mform->createElement('submit', $submitbuttonname, $submitlabel), + $mform->createElement('cancel'), + ]; + $buttonarname = $forceuniqueid && $this::$uniqueid > 0 ? 'buttonar_' . $this::$uniqueid : 'buttonar'; + $mform->addGroup($buttonarray, $buttonarname, '', [' '], false); $mform->closeHeaderBefore('buttonar'); } else { - //no group needed - $mform->addElement('submit', 'submitbutton', $submitlabel); + // No group needed. + $mform->addElement('submit', $submitbuttonname, $submitlabel); $mform->closeHeaderBefore('submitbutton'); } + + // Increase the uniqueid so that we can have multiple forms with different ids for the action buttons on the same page. + if ($forceuniqueid) { + $this::$uniqueid++; + } } /**