admin/tool/monitor/amd/src/dropdown.js

  1. // This file is part of Moodle - http://moodle.org/
  2. //
  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.
  7. //
  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.
  12. //
  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/>.
  15. /**
  16. * Dropdown handler for the Event monitor tool.
  17. *
  18. * @module tool_monitor/dropdown
  19. * @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
  20. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21. */
  22. export const init = () => {
  23. const componentSelector = document.querySelector('[data-field="component"]');
  24. const eventSelector = document.querySelector('[data-field="eventname"]');
  25. const matchesComponent = (component, event) => event.startsWith(`\\${component}\\`);
  26. // Helper to fetch events for a component.
  27. const getEventsForComponent = (component) => {
  28. const events = Object.entries(JSON.parse(eventSelector.dataset.eventlist));
  29. return events.filter(([eventName], index) => {
  30. // Always return the Choose... option.
  31. if (index === 0) {
  32. return true;
  33. }
  34. return matchesComponent(component, eventName);
  35. });
  36. };
  37. // Helper to fetch the <option> elements for a compoment.
  38. const getEventOptionsForComponent = (component) => {
  39. return getEventsForComponent(component).map(([name, description]) => {
  40. const option = document.createElement('option');
  41. option.value = name;
  42. option.text = description;
  43. return option;
  44. });
  45. };
  46. // Change handler for the component selector.
  47. componentSelector.addEventListener('change', () => {
  48. eventSelector.innerHTML = '';
  49. getEventOptionsForComponent(componentSelector.value).forEach((option) => {
  50. eventSelector.options.add(option);
  51. });
  52. eventSelector.options.value = '';
  53. });
  54. // Set the initial value.
  55. // Rather than emptying the list and re-adding as the change handler does, remove any options that don't match.
  56. // This means that the current selection (when editing) is maintained.
  57. const initialCount = eventSelector.options.length;
  58. [...eventSelector.options].reverse().forEach((option, index) => {
  59. if (option.value === '') {
  60. // The first value is the "Choose..." pseudo-option.
  61. return;
  62. }
  63. if (!matchesComponent(componentSelector.value, option.value)) {
  64. eventSelector.options.remove(initialCount - index - 1);
  65. }
  66. });
  67. };