/** * @copyright (C) 2018 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ /** * Fancy select field, which use Choices.js * * Example: * * * * * Possible attributes: * * allow-custom Whether allow User to dynamically add a new value. * new-item-prefix="" Prefix for a dynamically added value. * * remote-search Enable remote search. * url="" Url for remote search. * term-key="term" Variable key name for searched term, will be appended to Url. * * min-term-length="1" The minimum length a search value should be before choices are searched. * placeholder="" The value of the inputs placeholder. * search-placeholder="" The value of the search inputs placeholder. * * data-max-results="30" The maximum amount of search results to be displayed. * data-max-render="30" The maximum amount of items to be rendered, critical for large lists. */ window.customElements.define('joomla-field-fancy-select', class extends HTMLElement { // Attributes to monitor get allowCustom() { return this.hasAttribute('allow-custom'); } get remoteSearch() { return this.hasAttribute('remote-search'); } get url() { return this.getAttribute('url'); } get termKey() { return this.getAttribute('term-key') || 'term'; } get minTermLength() { return parseInt(this.getAttribute('min-term-length'), 10) || 1; } get newItemPrefix() { return this.getAttribute('new-item-prefix') || ''; } get placeholder() { return this.getAttribute('placeholder'); } get searchPlaceholder() { return this.getAttribute('search-placeholder'); } get value() { return this.choicesInstance.getValue(true); } set value($val) { this.choicesInstance.setChoiceByValue($val); } /** * Lifecycle */ constructor() { super(); // Keycodes this.keyCode = { ENTER: 13 }; if (!Joomla) { throw new Error('Joomla API is not properly initiated'); } if (!window.Choices) { throw new Error('JoomlaFieldFancySelect requires Choices.js to work'); } this.choicesCache = {}; this.activeXHR = null; this.choicesInstance = null; this.isDisconnected = false; } /** * Lifecycle */ connectedCallback() { // Make sure Choices are loaded if (window.Choices || document.readyState === 'complete') { this.doConnect(); } else { const callback = () => { this.doConnect(); window.removeEventListener('load', callback); }; window.addEventListener('load', callback); } } doConnect() { // Get a element to work'); } // The element was already initialised previously and perhaps was detached from DOM if (this.choicesInstance) { if (this.isDisconnected) { // Re init previous instance this.choicesInstance.init(); this.isDisconnected = false; } return; } this.isDisconnected = false; // Add placeholder option for multiple mode, // Because it not supported as parameter by Choices for