[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 (function () { 2 'use strict'; 3 4 function _defineProperties(target, props) { 5 for (var i = 0; i < props.length; i++) { 6 var descriptor = props[i]; 7 descriptor.enumerable = descriptor.enumerable || false; 8 descriptor.configurable = true; 9 if ("value" in descriptor) descriptor.writable = true; 10 Object.defineProperty(target, descriptor.key, descriptor); 11 } 12 } 13 14 function _createClass(Constructor, protoProps, staticProps) { 15 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 16 if (staticProps) _defineProperties(Constructor, staticProps); 17 Object.defineProperty(Constructor, "prototype", { 18 writable: false 19 }); 20 return Constructor; 21 } 22 23 function _inheritsLoose(subClass, superClass) { 24 subClass.prototype = Object.create(superClass.prototype); 25 subClass.prototype.constructor = subClass; 26 27 _setPrototypeOf(subClass, superClass); 28 } 29 30 function _getPrototypeOf(o) { 31 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { 32 return o.__proto__ || Object.getPrototypeOf(o); 33 }; 34 return _getPrototypeOf(o); 35 } 36 37 function _setPrototypeOf(o, p) { 38 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { 39 o.__proto__ = p; 40 return o; 41 }; 42 43 return _setPrototypeOf(o, p); 44 } 45 46 function _isNativeReflectConstruct() { 47 if (typeof Reflect === "undefined" || !Reflect.construct) return false; 48 if (Reflect.construct.sham) return false; 49 if (typeof Proxy === "function") return true; 50 51 try { 52 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); 53 return true; 54 } catch (e) { 55 return false; 56 } 57 } 58 59 function _construct(Parent, args, Class) { 60 if (_isNativeReflectConstruct()) { 61 _construct = Reflect.construct; 62 } else { 63 _construct = function _construct(Parent, args, Class) { 64 var a = [null]; 65 a.push.apply(a, args); 66 var Constructor = Function.bind.apply(Parent, a); 67 var instance = new Constructor(); 68 if (Class) _setPrototypeOf(instance, Class.prototype); 69 return instance; 70 }; 71 } 72 73 return _construct.apply(null, arguments); 74 } 75 76 function _isNativeFunction(fn) { 77 return Function.toString.call(fn).indexOf("[native code]") !== -1; 78 } 79 80 function _wrapNativeSuper(Class) { 81 var _cache = typeof Map === "function" ? new Map() : undefined; 82 83 _wrapNativeSuper = function _wrapNativeSuper(Class) { 84 if (Class === null || !_isNativeFunction(Class)) return Class; 85 86 if (typeof Class !== "function") { 87 throw new TypeError("Super expression must either be null or a function"); 88 } 89 90 if (typeof _cache !== "undefined") { 91 if (_cache.has(Class)) return _cache.get(Class); 92 93 _cache.set(Class, Wrapper); 94 } 95 96 function Wrapper() { 97 return _construct(Class, arguments, _getPrototypeOf(this).constructor); 98 } 99 100 Wrapper.prototype = Object.create(Class.prototype, { 101 constructor: { 102 value: Wrapper, 103 enumerable: false, 104 writable: true, 105 configurable: true 106 } 107 }); 108 return _setPrototypeOf(Wrapper, Class); 109 }; 110 111 return _wrapNativeSuper(Class); 112 } 113 114 /** 115 * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> 116 * @license GNU General Public License version 2 or later; see LICENSE.txt 117 */ 118 119 /** 120 * Fancy select field, which use Choices.js 121 * 122 * Example: 123 * <joomla-field-fancy-select ...attributes> 124 * <select>...</select> 125 * </joomla-field-fancy-select> 126 * 127 * Possible attributes: 128 * 129 * allow-custom Whether allow User to dynamically add a new value. 130 * new-item-prefix="" Prefix for a dynamically added value. 131 * 132 * remote-search Enable remote search. 133 * url="" Url for remote search. 134 * term-key="term" Variable key name for searched term, will be appended to Url. 135 * 136 * min-term-length="1" The minimum length a search value should be before choices are searched. 137 * placeholder="" The value of the inputs placeholder. 138 * search-placeholder="" The value of the search inputs placeholder. 139 * 140 * data-max-results="30" The maximum amount of search results to be displayed. 141 * data-max-render="30" The maximum amount of items to be rendered, critical for large lists. 142 */ 143 window.customElements.define('joomla-field-fancy-select', /*#__PURE__*/function (_HTMLElement) { 144 _inheritsLoose(_class, _HTMLElement); 145 146 /** 147 * Lifecycle 148 */ 149 function _class() { 150 var _this; 151 152 _this = _HTMLElement.call(this) || this; // Keycodes 153 154 _this.keyCode = { 155 ENTER: 13 156 }; 157 158 if (!Joomla) { 159 throw new Error('Joomla API is not properly initiated'); 160 } 161 162 if (!window.Choices) { 163 throw new Error('JoomlaFieldFancySelect requires Choices.js to work'); 164 } 165 166 _this.choicesCache = {}; 167 _this.activeXHR = null; 168 _this.choicesInstance = null; 169 _this.isDisconnected = false; 170 return _this; 171 } 172 /** 173 * Lifecycle 174 */ 175 176 177 var _proto = _class.prototype; 178 179 _proto.connectedCallback = function connectedCallback() { 180 var _this2 = this; 181 182 // Make sure Choices are loaded 183 if (window.Choices || document.readyState === 'complete') { 184 this.doConnect(); 185 } else { 186 var callback = function callback() { 187 _this2.doConnect(); 188 189 window.removeEventListener('load', callback); 190 }; 191 192 window.addEventListener('load', callback); 193 } 194 }; 195 196 _proto.doConnect = function doConnect() { 197 var _this3 = this; 198 199 // Get a <select> element 200 this.select = this.querySelector('select'); 201 202 if (!this.select) { 203 throw new Error('JoomlaFieldFancySelect requires <select> element to work'); 204 } // The element was already initialised previously and perhaps was detached from DOM 205 206 207 if (this.choicesInstance) { 208 if (this.isDisconnected) { 209 // Re init previous instance 210 this.choicesInstance.init(); 211 this.isDisconnected = false; 212 } 213 214 return; 215 } 216 217 this.isDisconnected = false; // Add placeholder option for multiple mode, 218 // Because it not supported as parameter by Choices for <select> https://github.com/jshjohnson/Choices#placeholder 219 220 if (this.select.multiple && this.placeholder) { 221 var option = document.createElement('option'); 222 option.setAttribute('placeholder', ''); 223 option.textContent = this.placeholder; 224 this.select.appendChild(option); 225 } // Init Choices 226 // eslint-disable-next-line no-undef 227 228 229 this.choicesInstance = new Choices(this.select, { 230 placeholderValue: this.placeholder, 231 searchPlaceholderValue: this.searchPlaceholder, 232 removeItemButton: true, 233 searchFloor: this.minTermLength, 234 searchResultLimit: parseInt(this.select.dataset.maxResults, 10) || 10, 235 renderChoiceLimit: parseInt(this.select.dataset.maxRender, 10) || -1, 236 shouldSort: false, 237 fuseOptions: { 238 threshold: 0.3 // Strict search 239 240 }, 241 noResultsText: Joomla.Text._('JGLOBAL_SELECT_NO_RESULTS_MATCH', 'No results found'), 242 noChoicesText: Joomla.Text._('JGLOBAL_SELECT_NO_RESULTS_MATCH', 'No results found'), 243 itemSelectText: Joomla.Text._('JGLOBAL_SELECT_PRESS_TO_SELECT', 'Press to select'), 244 // Redefine some classes 245 classNames: { 246 button: 'choices__button_joomla' // It is need because an original styling use unavailable Icon.svg file 247 248 } 249 }); // Handle typing of custom Term 250 251 if (this.allowCustom) { 252 // START Work around for issue https://github.com/joomla/joomla-cms/issues/29459 253 // The choices.js always auto-highlights the first element 254 // in the dropdown that not allow to add a custom Term. 255 // 256 // This workaround can be removed when choices.js 257 // will have an option that allow to disable it. 258 // eslint-disable-next-line no-underscore-dangle, prefer-destructuring 259 var _highlightChoice = this.choicesInstance._highlightChoice; // eslint-disable-next-line no-underscore-dangle 260 261 this.choicesInstance._highlightChoice = function (el) { 262 // Prevent auto-highlight of first element, if nothing actually highlighted 263 if (!el) return; // Call original highlighter 264 265 _highlightChoice.call(_this3.choicesInstance, el); 266 }; // Unhighlight any highlighted items, when mouse leave the dropdown 267 268 269 this.addEventListener('mouseleave', function () { 270 if (!_this3.choicesInstance.dropdown.isActive) { 271 return; 272 } 273 274 var highlighted = Array.from(_this3.choicesInstance.dropdown.element.querySelectorAll("." + _this3.choicesInstance.config.classNames.highlightedState)); 275 highlighted.forEach(function (choice) { 276 choice.classList.remove(_this3.choicesInstance.config.classNames.highlightedState); 277 choice.setAttribute('aria-selected', 'false'); 278 }); // eslint-disable-next-line no-underscore-dangle 279 280 _this3.choicesInstance._highlightPosition = 0; 281 }); // END workaround for issue #29459 282 // Add custom term on ENTER keydown 283 284 this.addEventListener('keydown', function (event) { 285 if (event.keyCode !== _this3.keyCode.ENTER || event.target !== _this3.choicesInstance.input.element) { 286 return; 287 } 288 289 event.preventDefault(); // eslint-disable-next-line no-underscore-dangle 290 291 if (_this3.choicesInstance._highlightPosition || !event.target.value) { 292 return; 293 } // Make sure nothing is highlighted 294 295 296 var highlighted = _this3.choicesInstance.dropdown.element.querySelector("." + _this3.choicesInstance.config.classNames.highlightedState); 297 298 if (highlighted) { 299 return; 300 } // Check if value already exist 301 302 303 var lowerValue = event.target.value.toLowerCase(); 304 var valueInCache = false; // Check if value in existing choices 305 306 _this3.choicesInstance.config.choices.some(function (choiceItem) { 307 if (choiceItem.value.toLowerCase() === lowerValue || choiceItem.label.toLowerCase() === lowerValue) { 308 valueInCache = choiceItem.value; 309 return true; 310 } 311 312 return false; 313 }); 314 315 if (valueInCache === false) { 316 // Check if value in cache 317 Object.keys(_this3.choicesCache).some(function (key) { 318 if (key.toLowerCase() === lowerValue || _this3.choicesCache[key].toLowerCase() === lowerValue) { 319 valueInCache = key; 320 return true; 321 } 322 323 return false; 324 }); 325 } // Make choice based on existing value 326 327 328 if (valueInCache !== false) { 329 _this3.choicesInstance.setChoiceByValue(valueInCache); 330 331 event.target.value = null; 332 333 _this3.choicesInstance.hideDropdown(); 334 335 return; 336 } // Create and add new 337 338 339 _this3.choicesInstance.setChoices([{ 340 value: _this3.newItemPrefix + event.target.value, 341 label: event.target.value, 342 selected: true, 343 customProperties: { 344 value: event.target.value // Store real value, just in case 345 346 } 347 }], 'value', 'label', false); 348 349 _this3.choicesCache[event.target.value] = event.target.value; 350 event.target.value = null; 351 352 _this3.choicesInstance.hideDropdown(); 353 }); 354 } // Handle remote search 355 356 357 if (this.remoteSearch && this.url) { 358 // Cache existing 359 this.choicesInstance.config.choices.forEach(function (choiceItem) { 360 _this3.choicesCache[choiceItem.value] = choiceItem.label; 361 }); 362 var lookupDelay = 300; 363 var lookupTimeout = null; 364 this.select.addEventListener('search', function () { 365 clearTimeout(lookupTimeout); 366 lookupTimeout = setTimeout(_this3.requestLookup.bind(_this3), lookupDelay); 367 }); 368 } 369 } 370 /** 371 * Lifecycle 372 */ 373 ; 374 375 _proto.disconnectedCallback = function disconnectedCallback() { 376 // Destroy Choices instance, to unbind event listeners 377 if (this.choicesInstance) { 378 this.choicesInstance.destroy(); 379 this.isDisconnected = true; 380 } 381 382 if (this.activeXHR) { 383 this.activeXHR.abort(); 384 this.activeXHR = null; 385 } 386 }; 387 388 _proto.requestLookup = function requestLookup() { 389 var _this4 = this; 390 391 var url = this.url; 392 url += url.indexOf('?') === -1 ? '?' : '&'; 393 url += encodeURIComponent(this.termKey) + "=" + encodeURIComponent(this.choicesInstance.input.value); // Stop previous request if any 394 395 if (this.activeXHR) { 396 this.activeXHR.abort(); 397 } 398 399 this.activeXHR = Joomla.request({ 400 url: url, 401 onSuccess: function onSuccess(response) { 402 _this4.activeXHR = null; 403 var items = response ? JSON.parse(response) : []; 404 405 if (!items.length) { 406 return; 407 } // Remove duplications 408 409 410 var item; // eslint-disable-next-line no-plusplus 411 412 for (var i = items.length - 1; i >= 0; i--) { 413 // The loop must be form the end !!! 414 item = items[i]; // eslint-disable-next-line prefer-template 415 416 item.value = '' + item.value; // Make sure the value is a string, choices.js expect a string. 417 418 if (_this4.choicesCache[item.value]) { 419 items.splice(i, 1); 420 } else { 421 _this4.choicesCache[item.value] = item.text; 422 } 423 } // Add new options to field, assume that each item is object, eg {value: "foo", text: "bar"} 424 425 426 if (items.length) { 427 _this4.choicesInstance.setChoices(items, 'value', 'text', false); 428 } 429 }, 430 onError: function onError() { 431 _this4.activeXHR = null; 432 } 433 }); 434 }; 435 436 _proto.disableAllOptions = function disableAllOptions() { 437 // Choices.js does not offer a public API for accessing the choices 438 // So we have to access the private store => don't eslint 439 // eslint-disable-next-line no-underscore-dangle 440 var choices = this.choicesInstance._store.choices; 441 choices.forEach(function (elem, index) { 442 choices[index].disabled = true; 443 choices[index].selected = false; 444 }); 445 this.choicesInstance.clearStore(); 446 this.choicesInstance.setChoices(choices, 'value', 'label', true); 447 }; 448 449 _proto.enableAllOptions = function enableAllOptions() { 450 // Choices.js does not offer a public API for accessing the choices 451 // So we have to access the private store => don't eslint 452 // eslint-disable-next-line no-underscore-dangle 453 var choices = this.choicesInstance._store.choices; 454 var values = this.choicesInstance.getValue(true); 455 choices.forEach(function (elem, index) { 456 choices[index].disabled = false; 457 }); 458 this.choicesInstance.clearStore(); 459 this.choicesInstance.setChoices(choices, 'value', 'label', true); 460 this.value = values; 461 }; 462 463 _proto.disableByValue = function disableByValue($val) { 464 // Choices.js does not offer a public API for accessing the choices 465 // So we have to access the private store => don't eslint 466 // eslint-disable-next-line no-underscore-dangle 467 var choices = this.choicesInstance._store.choices; 468 var values = this.choicesInstance.getValue(true); 469 choices.forEach(function (elem, index) { 470 if (elem.value === $val) { 471 choices[index].disabled = true; 472 choices[index].selected = false; 473 } 474 }); 475 var index = values.indexOf($val); 476 477 if (index > -1) { 478 values.slice(index, 1); 479 } 480 481 this.choicesInstance.clearStore(); 482 this.choicesInstance.setChoices(choices, 'value', 'label', true); 483 this.value = values; 484 }; 485 486 _proto.enableByValue = function enableByValue($val) { 487 // Choices.js does not offer a public API for accessing the choices 488 // So we have to access the private store => don't eslint 489 // eslint-disable-next-line no-underscore-dangle 490 var choices = this.choicesInstance._store.choices; 491 var values = this.choicesInstance.getValue(true); 492 choices.forEach(function (elem, index) { 493 if (elem.value === $val) { 494 choices[index].disabled = false; 495 } 496 }); 497 this.choicesInstance.clearStore(); 498 this.choicesInstance.setChoices(choices, 'value', 'label', true); 499 this.value = values; 500 }; 501 502 _createClass(_class, [{ 503 key: "allowCustom", 504 get: // Attributes to monitor 505 function get() { 506 return this.hasAttribute('allow-custom'); 507 } 508 }, { 509 key: "remoteSearch", 510 get: function get() { 511 return this.hasAttribute('remote-search'); 512 } 513 }, { 514 key: "url", 515 get: function get() { 516 return this.getAttribute('url'); 517 } 518 }, { 519 key: "termKey", 520 get: function get() { 521 return this.getAttribute('term-key') || 'term'; 522 } 523 }, { 524 key: "minTermLength", 525 get: function get() { 526 return parseInt(this.getAttribute('min-term-length'), 10) || 1; 527 } 528 }, { 529 key: "newItemPrefix", 530 get: function get() { 531 return this.getAttribute('new-item-prefix') || ''; 532 } 533 }, { 534 key: "placeholder", 535 get: function get() { 536 return this.getAttribute('placeholder'); 537 } 538 }, { 539 key: "searchPlaceholder", 540 get: function get() { 541 return this.getAttribute('search-placeholder'); 542 } 543 }, { 544 key: "value", 545 get: function get() { 546 return this.choicesInstance.getValue(true); 547 }, 548 set: function set($val) { 549 this.choicesInstance.setChoiceByValue($val); 550 } 551 }]); 552 553 return _class; 554 }( /*#__PURE__*/_wrapNativeSuper(HTMLElement))); 555 556 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |