AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"status.min.js","sources":["../../../src/local/dropdown/status.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Dropdown status JS controls.\n *\n * The status controls enable extra configurarions for the dropdown like:\n * - Sync the button text with the selected option.\n * - Update the status of the button when the s
elected option changes. This will\n * trigger a \"change\" event when the status changes.\n *\n * @module core/local/dropdown/status\n * @copyright 2023 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {DropdownDialog} from 'core/local/dropdown/dialog';\n\nconst Selectors = {\n checkedIcon: '[data-for=\"checkedIcon\"]',\n option: '[role=\"option\"]',\n optionItem: '[data-optionnumber]',\n optionIcon: '.option-icon',\n selectedOption: '[role=\"option\"][aria-selected=\"true\"]',\n uncheckedIcon: '[data-for=\"uncheckedIcon\"]',\n};\n\nconst Classes = {\n selected: 'selected',\n disabled: 'disabled',\n hidden: 'd-none',\n};\n\n/**\n * Dropdown dialog class.\n * @private\n */\nexport class DropdownStatus extends DropdownDialog {\n /**\n * Constructor.\n * @param {HTMLElement} element The element to initialize.\n */\n constructor(element) {\n super(element);\n this.buttonSyn
c = element.dataset.buttonSync == 'true';\n this.updateStatus = element.dataset.updateStatus == 'true';\n }\n\n /**\n * Initialize the subpanel element.\n *\n * This method adds the event listeners to the subpanel and the position classes.\n * @private\n */\n init() {\n super.init();\n\n if (this.element.dataset.dropdownStatusInitialized) {\n return;\n }\n\n this.panel.addEventListener('click', this._contentClickHandler.bind(this));\n\n if (this.element.dataset.buttonSync == 'true') {\n this.setButtonSyncEnabled(true);\n }\n if (this.element.dataset.updateStatus == 'true') {\n this.setUpdateStatusEnabled(true);\n }\n\n this.element.dataset.dropdownStatusInitialized = true;\n }\n\n /**\n * Handle click events on the status content.\n * @param {Event} event The event.\n * @private\n */\n _contentClickHandler(event) {\n const option = event.target.cl
osest(Selectors.option);\n if (!option) {\n return;\n }\n if (option.getAttribute('aria-disabled') === 'true') {\n return;\n }\n if (option.getAttribute('aria-selected') === 'true') {\n return;\n }\n if (this.isUpdateStatusEnabled()) {\n this.setSelectedValue(option.dataset.value);\n }\n }\n\n /**\n * Sets the selected value.\n * @param {string} value The value to set.\n */\n setSelectedValue(value) {\n const selected = this.panel.querySelector(Selectors.selectedOption);\n if (selected && selected.dataset.value === value) {\n return;\n }\n if (selected) {\n this._updateOptionChecked(selected, false);\n }\n const option = this.panel.querySelector(`${Selectors.option}[data-value=\"${value}\"]`);\n if (option) {\n this._updateOptionChecked(option, true);\n }\n if (this.isButtonSyncEnabled()) {\n
this.syncButtonText();\n }\n // Emit standard radio button event with the selected option.\n this.element.dispatchEvent(new Event('change'));\n }\n\n /**\n * Update the option checked content.\n * @private\n * @param {HTMLElement} option the option element to set\n * @param {Boolean} checked the new checked value\n */\n _updateOptionChecked(option, checked) {\n option.setAttribute('aria-selected', checked.toString());\n option.classList.toggle(Classes.selected, checked);\n option.classList.toggle(Classes.disabled, checked);\n\n const optionItem = option.closest(Selectors.optionItem);\n if (optionItem) {\n this._updateOptionItemChecked(optionItem, checked);\n }\n\n if (checked) {\n this.element.dataset.value = option.dataset.value;\n } else if (this.element.dataset.value === option.dataset.value) {\n delete this.element.dataset.value;\n }\n }\n\n /**\
n * Update the option item checked content.\n * @private\n * @param {HTMLElement} optionItem\n * @param {Boolean} checked\n */\n _updateOptionItemChecked(optionItem, checked) {\n const selectedClasses = optionItem.dataset.selectedClasses ?? Classes.selected;\n for (const selectedClass of selectedClasses.split(' ')) {\n optionItem.classList.toggle(selectedClass, checked);\n }\n if (checked) {\n optionItem.dataset.selected = checked;\n } else {\n delete optionItem?.dataset.selected;\n }\n const checkedIcon = optionItem.querySelector(Selectors.checkedIcon);\n if (checkedIcon) {\n checkedIcon.classList.toggle(Classes.hidden, !checked);\n }\n const uncheckedIcon = optionItem.querySelector(Selectors.uncheckedIcon);\n if (uncheckedIcon) {\n uncheckedIcon.classList.toggle(Classes.hidden, checked);\n }\n }\n\n\n /**\n * Return the selected value.\n
* @returns {string|null} The selected value.\n */\n getSelectedValue() {\n const selected = this.panel.querySelector(Selectors.selectedOption);\n return selected?.dataset.value ?? null;\n }\n\n /**\n * Set the button sync value.\n *\n * If the sync is enabled, the button text will show the selected option.\n *\n * @param {Boolean} value The value to set.\n */\n setButtonSyncEnabled(value) {\n if (value) {\n this.element.dataset.buttonSync = 'true';\n } else {\n delete this.element.dataset.buttonSync;\n }\n if (value) {\n this.syncButtonText();\n }\n }\n\n /**\n * Return if the button sync is enabled.\n * @returns {Boolean} The button sync value.\n */\n isButtonSyncEnabled() {\n return this.element.dataset.buttonSync == 'true';\n }\n\n /**\n * Sync the button text with the selected option.\n */\n syncButtonText() {\n const selected =
this.panel.querySelector(Selectors.selectedOption);\n if (!selected) {\n return;\n }\n let newText = selected.textContent;\n const optionIcon = this._getOptionIcon(selected);\n if (optionIcon) {\n newText = optionIcon.innerHTML + newText;\n }\n this.button.innerHTML = newText;\n }\n\n /**\n * Set the update status value.\n *\n * @param {Boolean} value The value to set.\n */\n setUpdateStatusEnabled(value) {\n if (value) {\n this.element.dataset.updateStatus = 'true';\n } else {\n delete this.element.dataset.updateStatus;\n }\n }\n\n /**\n * Return if the update status is enabled.\n * @returns {Boolean} The update status value.\n */\n isUpdateStatusEnabled() {\n return this.element.dataset.updateStatus == 'true';\n }\n\n _getOptionIcon(option) {\n const optionItem = option.closest(Selectors.optionItem);\n if (!optionItem) {\
n return null;\n }\n return optionItem.querySelector(Selectors.optionIcon);\n }\n\n}\n\n/**\n * Get the dropdown dialog instance form a selector.\n * @param {string} selector The query selector to init.\n * @returns {DropdownStatus|null} The dropdown dialog instance if any.\n */\nexport const getDropdownStatus = (selector) => {\n const dropdownElement = document.querySelector(selector);\n if (!dropdownElement) {\n return null;\n }\n return new DropdownStatus(dropdownElement);\n};\n\n/**\n * Initialize module.\n *\n * @method\n * @param {string} selector The query selector to init.\n */\nexport const init = (selector) => {\n const dropdown = getDropdownStatus(selector);\n if (!dropdown) {\n throw new Error(`Dopdown status element not found: ${selector}`);\n }\n dropdown.init();\n};\n"],"names":["Selectors","Classes","DropdownStatus","DropdownDialog","constructor","element","buttonSync","dataset","updateStatus","init","this","dropdownStatusIniti
alized","panel","addEventListener","_contentClickHandler","bind","setButtonSyncEnabled","setUpdateStatusEnabled","event","option","target","closest","getAttribute","isUpdateStatusEnabled","setSelectedValue","value","selected","querySelector","_updateOptionChecked","isButtonSyncEnabled","syncButtonText","dispatchEvent","Event","checked","setAttribute","toString","classList","toggle","optionItem","_updateOptionItemChecked","selectedClasses","selectedClass","split","checkedIcon","uncheckedIcon","getSelectedValue","newText","textContent","optionIcon","_getOptionIcon","innerHTML","button","getDropdownStatus","selector","dropdownElement","document","dropdown","Error"],"mappings":"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"}