bootstrap-italia
Version:
Bootstrap Italia è un tema Bootstrap 5 per la creazione di applicazioni web nel pieno rispetto delle linee guida di design per i siti internet e i servizi digitali della PA
152 lines (123 loc) • 4.28 kB
JavaScript
import BaseComponent from './base-component.js';
import EventHandler from './dom/event-handler.js';
import InputLabel from './input-label.js';
/**
* --------------------------------------------------------------------------
* Bootstrap Italia (https://italia.github.io/bootstrap-italia/)
* Authors: https://github.com/italia/bootstrap-italia/blob/main/AUTHORS
* Licensed under BSD-3-Clause license (https://github.com/italia/bootstrap-italia/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const NAME = 'inputsearchautocomplete';
const DATA_KEY = 'bs.inputsearchautocomplete';
const EVENT_KEY = `.${DATA_KEY}`;
const Default = {
autocomplete: [],
};
const EVENT_KEYUP = `keyup${EVENT_KEY}`;
const CLASS_NAME_SHOW = 'autocomplete-list-show';
const CLASS_NAME_AUTOCOMPLETE = 'autocomplete';
const DATA_AUTOCOMPLETE = 'data-bs-autocomplete';
const SELECTOR_SEARCH = 'input[' + DATA_AUTOCOMPLETE + '][type="search"]';
class InputSearch extends BaseComponent {
constructor(element, config) {
super(element);
this._config = this._getConfig(config);
this._items = [];
this._autocompleteElement = null;
this._label = new InputLabel(element);
this._init();
this._bindEvents();
}
// Getters
static get NAME() {
return NAME
}
// Public
search() {
const value = this._element.value;
//!!! $autocomplete.empty()
this._autocompleteElement.innerHTML = '';
if (value) {
this._items.forEach((item) => {
let markText = new RegExp('(' + value + ')', 'gi');
let optionText = item.text.replace(markText, '<mark>$1</mark>');
let optionLabel = item.label ? '<em>' + item.label + '</em>' : '';
let optionIcon = item.icon ? item.icon : '';
let optionLink = item.link ? item.link : '#';
if (optionText.toLowerCase().indexOf(value.toLowerCase()) !== -1) {
this._autocompleteElement.classList.add(CLASS_NAME_SHOW);
this._autocompleteElement.appendChild(this._createOption(optionLink, optionText, optionLabel, optionIcon));
}
});
} else {
this._autocompleteElement.classList.remove(CLASS_NAME_SHOW);
}
}
// Private
_getConfig(config) {
config = {
...Default,
...(typeof config === 'object' ? config : {}),
};
return config
}
_getItems() {
try {
return JSON.parse(this._element.getAttribute(DATA_AUTOCOMPLETE))
} catch (error) {
console.error('[InputSearchAutocomplete] invalid data provided for ' + DATA_AUTOCOMPLETE + ' attribute', error);
return []
}
}
_init() {
if (this._element.classList.contains(CLASS_NAME_AUTOCOMPLETE)) {
if (typeof document === 'undefined') {
return
}
this._items = this._getItems();
this._autocompleteElement = document.createElement('ul');
this._autocompleteElement.classList.add('autocomplete-list');
this._element.parentNode.insertBefore(this._autocompleteElement, this._element.nextSibling);
}
}
_bindEvents() {
EventHandler.on(this._element, EVENT_KEYUP, () => this.search());
}
_createOption(link, text, label, icon) {
if (typeof document === 'undefined') {
return
}
const option = document.createElement('li');
option.innerHTML = `<a href="${link}">
${icon}
<span class="autocomplete-list-text">
<span>${text}</span>
${label}
</span>
</a>`;
return option
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
const createInput = (element) => {
if (element && element.matches(SELECTOR_SEARCH)) {
return InputSearch.getOrCreateInstance(element)
}
return null
};
if (typeof document !== 'undefined') {
document.addEventListener('DOMContentLoaded', function () {
var frmel = document.querySelectorAll(SELECTOR_SEARCH + ', label');
frmel.forEach(function (item) {
const target = InputLabel.getInputFromLabel(item) || item;
createInput(target);
});
});
}
export { InputSearch as default };
//# sourceMappingURL=input-search-autocomplete.js.map