1 // This file is part of Moodle - http://moodle.org/
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 * Provide global helper code to enhance page elements.
19 * @module core/page_global
21 * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 'core/custom_interaction_events',
37 * Add an event handler for dropdown menus that wish to show their active item
38 * in the dropdown toggle element.
40 * By default the handler will add the "active" class to the selected dropdown
41 * item and set it's text as the HTML for the dropdown toggle.
43 * The behaviour of this handler is controlled by adding data attributes to
44 * the HTML and requires the typically Bootstrap dropdown markup.
46 * data-show-active-item - Add to the .dropdown-menu element to enable default
48 * data-skip-active-class - Add to the .dropdown-menu to prevent this code from
49 * adding the active class to the dropdown items
50 * data-active-item-text - Add to an element within the data-toggle="dropdown" element
51 * to use it as the active option text placeholder otherwise the
52 * data-toggle="dropdown" element itself will be used.
53 * data-active-item-button-aria-label-components - String components to set the aria
54 * lable on the dropdown button. The string will be given the
57 var initActionOptionDropdownHandler = function() {
60 CustomEvents.define(body, [CustomEvents.events.activate]);
61 body.on(CustomEvents.events.activate, '[data-show-active-item]', function(e) {
62 // The dropdown item that the user clicked on.
63 var option = $(e.target).closest('.dropdown-item');
64 // The dropdown menu element.
65 var menuContainer = option.closest('[data-show-active-item]');
67 if (!option.hasClass('dropdown-item')) {
68 // Ignore non Bootstrap dropdowns.
72 if (option.hasClass('active')) {
73 // If it's already active then we don't need to do anything.
77 // Clear the active class from all other options.
78 var dropdownItems = menuContainer.find('.dropdown-item');
79 dropdownItems.removeClass('active');
80 dropdownItems.removeAttr('aria-current');
82 if (!menuContainer.attr('data-skip-active-class')) {
83 // Make this option active unless configured to ignore it.
84 // Some code, for example the Bootstrap tabs, may want to handle
85 // adding the active class itself.
86 option.addClass('active');
89 // Update aria attribute for active item.
90 option.attr('aria-current', true);
92 var activeOptionText = option.text();
93 var dropdownToggle = menuContainer.parent().find('[data-toggle="dropdown"]');
94 var dropdownToggleText = dropdownToggle.find('[data-active-item-text]');
96 if (dropdownToggleText.length) {
97 // We have a specific placeholder for the active item text so
99 dropdownToggleText.html(activeOptionText);
101 // Otherwise just replace all of the toggle text with the active item.
102 dropdownToggle.html(activeOptionText);
105 var activeItemAriaLabelComponent = menuContainer.attr('data-active-item-button-aria-label-components');
106 if (activeItemAriaLabelComponent) {
107 // If we have string components for the aria label then load the string
108 // and set the label on the dropdown toggle.
109 var strParams = activeItemAriaLabelComponent.split(',');
110 strParams.push(activeOptionText);
112 Str.get_string(strParams[0].trim(), strParams[1].trim(), strParams[2].trim())
113 .then(function(string) {
114 dropdownToggle.attr('aria-label', string);
118 // Silently ignore that we couldn't load the string.
126 * Initialise the global helper functions.
128 var init = function() {
129 initActionOptionDropdownHandler();