From 4ac81d6a66e4eed387a9f72be06aa17bff396df6 Mon Sep 17 00:00:00 2001 From: Trisha Milan Date: Wed, 16 Oct 2024 16:58:34 +1100 Subject: [PATCH] MDL-82625 navigation: Add disableactive flag to combobox widget - Introduced disableactive flag to prevent setting active state on combobox items when a page redirect occurs. This resolves the issue where incorrect checkmarks remain after using the browser's back button due to bfcache. - Added Behat test cases to verify correct checkmark behaviour in tertiary navigation when navigating and using the browser's back/forward buttons. --- backup/util/helper/backup_helper.class.php | 2 +- .../classes/output/completion_action_bar.php | 3 +- grade/classes/output/export_action_bar.php | 2 +- grade/classes/output/general_action_bar.php | 2 +- grade/classes/output/import_action_bar.php | 2 +- .../report/user/classes/output/action_bar.php | 2 +- grade/report/user/renderer.php | 2 +- .../output/participants_action_bar.php | 2 +- lib/classes/output/select_menu.php | 16 +- lib/classes/report_helper.php | 2 +- lib/templates/select_menu.mustache | 12 +- lib/tests/behat/behat_navigation.php | 48 ++++++ .../select_menu_disableactive_testpage.php | 54 ++++++ .../classes/output/grading_actionmenu.php | 2 +- mod/data/classes/output/action_bar.php | 2 +- theme/boost/amd/build/aria.min.js | 2 +- theme/boost/amd/build/aria.min.js.map | 2 +- theme/boost/amd/src/aria.js | 20 ++- .../behat_theme_boost_behat_navigation.php | 83 ++++++++- .../tertiary_navigation_activestate.feature | 159 ++++++++++++++++++ 20 files changed, 392 insertions(+), 27 deletions(-) create mode 100644 lib/tests/behat/fixtures/select_menu_disableactive_testpage.php create mode 100644 theme/boost/tests/behat/tertiary_navigation_activestate.feature diff --git a/backup/util/helper/backup_helper.class.php b/backup/util/helper/backup_helper.class.php index 65901635d2c..7b3435f8f35 100644 --- a/backup/util/helper/backup_helper.class.php +++ b/backup/util/helper/backup_helper.class.php @@ -411,7 +411,7 @@ abstract class backup_helper { } - $selectmenu = new \core\output\select_menu('coursereusetype', $menuarray, $activeurl); + $selectmenu = new \core\output\select_menu('coursereusetype', $menuarray, $activeurl, true); $selectmenu->set_label(get_string('coursereusenavigationmenu'), ['class' => 'visually-hidden']); $options = \html_writer::tag( 'div', diff --git a/course/classes/output/completion_action_bar.php b/course/classes/output/completion_action_bar.php index 97c00e38552..c486f3086cd 100644 --- a/course/classes/output/completion_action_bar.php +++ b/course/classes/output/completion_action_bar.php @@ -61,7 +61,8 @@ class completion_action_bar implements templatable, renderable { $selectmenu = new select_menu( 'coursecompletionnavigation', manager::get_available_completion_options($this->courseid), - $this->currenturl->out(false) + $this->currenturl->out(false), + true ); $selectmenu->set_label( get_string('coursecompletionnavigation', 'completion'), diff --git a/grade/classes/output/export_action_bar.php b/grade/classes/output/export_action_bar.php index da513904001..939b26f989c 100644 --- a/grade/classes/output/export_action_bar.php +++ b/grade/classes/output/export_action_bar.php @@ -94,7 +94,7 @@ class export_action_bar extends action_bar { } // This navigation selector menu will contain the links to all available grade export plugin pages. - $exportsurlselect = new \core\output\select_menu('exportas', $exportsmenu, $exportactiveurl); + $exportsurlselect = new \core\output\select_menu('exportas', $exportsmenu, $exportactiveurl, true); $exportsurlselect->set_label(get_string('exportas', 'grades')); $data['exportselector'] = $exportsurlselect->export_for_template($output); diff --git a/grade/classes/output/general_action_bar.php b/grade/classes/output/general_action_bar.php index 421109973f9..5874543ab7b 100644 --- a/grade/classes/output/general_action_bar.php +++ b/grade/classes/output/general_action_bar.php @@ -187,7 +187,7 @@ class general_action_bar extends action_bar { $menu[][get_string('moremenu')] = $moregroup; } - $selectmenu = new select_menu('gradesactionselect', $menu, $this->activeurl->out(false)); + $selectmenu = new select_menu('gradesactionselect', $menu, $this->activeurl->out(false), true); $selectmenu->set_label(get_string('gradebooknavigationmenu', 'grades'), ['class' => 'visually-hidden']); return $selectmenu; diff --git a/grade/classes/output/import_action_bar.php b/grade/classes/output/import_action_bar.php index f96bb57ee1d..bd1a50fedb1 100644 --- a/grade/classes/output/import_action_bar.php +++ b/grade/classes/output/import_action_bar.php @@ -94,7 +94,7 @@ class import_action_bar extends action_bar { } // This navigation selector menu will contain the links to all available grade export plugin pages. - $importsurlselect = new \core\output\select_menu('importas', $importsmenu, $importactiveurl); + $importsurlselect = new \core\output\select_menu('importas', $importsmenu, $importactiveurl, true); $importsurlselect->set_label(get_string('importas', 'grades')); $data['importselector'] = $importsurlselect->export_for_template($output); diff --git a/grade/report/user/classes/output/action_bar.php b/grade/report/user/classes/output/action_bar.php index 7908045c70e..3f98a06d089 100644 --- a/grade/report/user/classes/output/action_bar.php +++ b/grade/report/user/classes/output/action_bar.php @@ -127,7 +127,7 @@ class action_bar extends \core_grades\output\action_bar { $selectoractiveurl = $this->userview === GRADE_REPORT_USER_VIEW_USER ? $viewasotheruser : $viewasmyself; - $viewasselect = new \core\output\select_menu('viewas', $selectoroptions, $selectoractiveurl->out(false)); + $viewasselect = new \core\output\select_menu('viewas', $selectoroptions, $selectoractiveurl->out(false), true); $viewasselect->set_label(get_string('viewas', 'core_grades')); $data['viewasselector'] = $viewasselect->export_for_template($output); diff --git a/grade/report/user/renderer.php b/grade/report/user/renderer.php index a53109d9d49..027bddb9a44 100644 --- a/grade/report/user/renderer.php +++ b/grade/report/user/renderer.php @@ -190,7 +190,7 @@ class gradereport_user_renderer extends plugin_renderer_base { $selectoractiveurl = $userview === GRADE_REPORT_USER_VIEW_USER ? $viewasotheruser : $viewasmyself; - $viewasselect = new \core\output\select_menu('viewas', $selectoroptions, $selectoractiveurl->out(false)); + $viewasselect = new \core\output\select_menu('viewas', $selectoroptions, $selectoractiveurl->out(false), true); $viewasselect->set_label(get_string('viewas', 'core_grades')); return $this->render_from_template('gradereport_user/view_mode_selector', diff --git a/lib/classes/output/participants_action_bar.php b/lib/classes/output/participants_action_bar.php index fa15c275579..fcc5251ae93 100644 --- a/lib/classes/output/participants_action_bar.php +++ b/lib/classes/output/participants_action_bar.php @@ -206,7 +206,7 @@ class participants_action_bar implements renderable { $activeurl = $this->find_active_page($urlselectcontent); $activeurl = $activeurl ?: $this->find_active_page($urlselectcontent, URL_MATCH_BASE); - $selectmenu = new select_menu('participantsnavigation', $urlselectcontent, $activeurl); + $selectmenu = new select_menu('participantsnavigation', $urlselectcontent, $activeurl, true); $selectmenu->set_label(get_string('participantsnavigation', 'course'), ['class' => 'visually-hidden']); return $selectmenu->export_for_template($output); diff --git a/lib/classes/output/select_menu.php b/lib/classes/output/select_menu.php index 5944152b5f6..97bc5c1d1f9 100644 --- a/lib/classes/output/select_menu.php +++ b/lib/classes/output/select_menu.php @@ -45,6 +45,9 @@ class select_menu implements renderable, templatable { /** @var string Name of the combobox element */ protected $name; + /** @var bool A flag indicating whether the active state should be disabled in the dropdown. */ + protected $disableactive; + /** * select_menu constructor. * @@ -52,11 +55,19 @@ class select_menu implements renderable, templatable { * @param array $options List of options in an associative array format like ['val' => 'Option']. * Supports grouped options as well. Empty string or null values will be rendered as dividers. * @param string|null $selected The value of the preselected option. + * @param bool $disableactive A flag that indicates whether the active state should be disabled in the dropdown. + * This is useful when the dropdown items result in navigation to another page, + * as it makes it unnecessary to mark the selected item as active. If the flag + * is set to true, the checkmark indicating the active menu item will not be displayed, + * as the user is redirected. However, in cases where no redirection occurs and + * it is valid to display the active state, this flag should remain false, + * allowing the checkmark to appear beside the active item. */ - public function __construct(string $name, array $options, ?string $selected = null) { + public function __construct(string $name, array $options, ?string $selected = null, bool $disableactive = false) { $this->name = $name; $this->options = $options; $this->selected = $selected; + $this->disableactive = $disableactive; } /** @@ -100,6 +111,7 @@ class select_menu implements renderable, templatable { 'value' => $optvalue, 'selected' => $this->selected == $optvalue, 'id' => \html_writer::random_id('select-menu-option'), + 'disableactive' => $this->disableactive, ]; } } @@ -113,6 +125,7 @@ class select_menu implements renderable, templatable { 'value' => $value, 'selected' => $this->selected == $value, 'id' => \html_writer::random_id('select-menu-option'), + 'disableactive' => $this->disableactive, ]; } } @@ -171,6 +184,7 @@ class select_menu implements renderable, templatable { $data->selectedoption = $this->get_selected_option(); $data->name = $this->name; $data->value = $this->selected; + $data->disableactive = $this->disableactive; // Label attributes. $data->labelattributes = []; diff --git a/lib/classes/report_helper.php b/lib/classes/report_helper.php index 6275cdf2743..11f6d1b15f3 100644 --- a/lib/classes/report_helper.php +++ b/lib/classes/report_helper.php @@ -69,7 +69,7 @@ class report_helper { } } - $selectmenu = new \core\output\select_menu('reporttype', $menuarray, $activeurl); + $selectmenu = new \core\output\select_menu('reporttype', $menuarray, $activeurl, true); $selectmenu->set_label(get_string('reporttype'), ['class' => 'visually-hidden']); $options = \html_writer::tag( 'div', diff --git a/lib/templates/select_menu.mustache b/lib/templates/select_menu.mustache index b4ac2c2bb2f..77c50a3b2bb 100644 --- a/lib/templates/select_menu.mustache +++ b/lib/templates/select_menu.mustache @@ -27,6 +27,7 @@ * labelattributes - Label attributes. * selectedoption - Text of the selected option * options - Array of options for the select with value, name, selected, isgroup and id properites. + * disableactive - A flag indicating whether the active state should be disabled in the dropdown. Example context (json): { @@ -82,7 +83,8 @@ "id": "select-menu-option5", "selected": false } - ] + ], + "disableactive": false } }}