芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/testcors.sdektun.com/media/system/js/searchtools.js
Joomla = window.Joomla || {}; (Joomla => { /** * Method that resets the filter inputs and submits the relative form * * @param {HTMLElement} element The element that initiates the call * @returns {void} * @since 4.0.0 */ Joomla.resetFilters = element => { const { form } = element; if (!form) { throw new Error('Element must be inside a form!'); } const elementsArray = [].slice.call(form.elements); if (elementsArray.length) { const newElementsArray = []; elementsArray.forEach(elem => { // Skip the token, the task, the boxchecked and the calling element if (elem.getAttribute('name') === 'task' || elem.getAttribute('name') === 'boxchecked' || elem.value === '1' && /^[0-9A-F]{32}$/i.test(elem.name) || elem === element) { return; } newElementsArray.push(elem); }); // Reset all filters newElementsArray.forEach(elem => { elem.value = ''; }); form.submit(); } }; class Searchtools { constructor(elem, options) { const defaults = { // Form options formSelector: '.js-stools-form', // Search searchFieldSelector: '.js-stools-field-search', clearBtnSelector: '.js-stools-btn-clear', // Global container mainContainerSelector: '.js-stools', // Filter fields searchBtnSelector: '.js-stools-btn-search', filterBtnSelector: '.js-stools-btn-filter', filterContainerSelector: '.js-stools-container-filters', filtersHidden: true, // List fields listBtnSelector: '.js-stools-btn-list', listContainerSelector: '.js-stools-container-list', listHidden: true, // Ordering specific orderColumnSelector: '.js-stools-column-order', orderBtnSelector: '.js-stools-btn-order', orderFieldSelector: '.js-stools-field-order', orderFieldName: 'list[fullordering]', limitFieldSelector: '.js-stools-field-limit', defaultLimit: 20, activeOrder: null, activeDirection: 'ASC', // Extra clearListOptions: false }; this.element = elem; this.options = Joomla.extend(defaults, options); // Initialise selectors this.theForm = document.querySelector(this.options.formSelector); // Filters this.filterButton = document.querySelector(`${this.options.formSelector} ${this.options.filterBtnSelector}`); this.filterContainer = document.querySelector(`${this.options.formSelector} ${this.options.filterContainerSelector}`) ? document.querySelector(`${this.options.formSelector} ${this.options.filterContainerSelector}`) : ''; this.filtersHidden = this.options.filtersHidden; // List fields this.listButton = document.querySelector(this.options.listBtnSelector); this.listContainer = document.querySelector(`${this.options.formSelector} ${this.options.listContainerSelector}`); this.listHidden = this.options.listHidden; // Main container this.mainContainer = document.querySelector(this.options.mainContainerSelector); // Search this.searchButton = document.querySelector(`${this.options.formSelector} ${this.options.searchBtnSelector}`); this.searchField = document.querySelector(`${this.options.formSelector} ${this.options.searchFieldSelector}`); this.searchString = null; this.clearButton = document.querySelector(this.options.clearBtnSelector); // Ordering this.orderCols = Array.prototype.slice.call(document.querySelectorAll(`${this.options.formSelector} ${this.options.orderColumnSelector}`)); this.orderField = document.querySelector(`${this.options.formSelector} ${this.options.orderFieldSelector}`); // Limit this.limitField = document.querySelector(`${this.options.formSelector} ${this.options.limitFieldSelector}`); // Init trackers this.activeColumn = null; this.activeDirection = this.options.activeDirection; this.activeOrder = this.options.activeOrder; this.activeLimit = null; // Extra options this.clearListOptions = this.options.clearListOptions; const self = this; // Get values this.searchString = this.searchField.value; // Do some binding this.showFilters = this.showFilters.bind(this); this.hideFilters = this.hideFilters.bind(this); this.showList = this.showList.bind(this); this.hideList = this.hideList.bind(this); this.toggleFilters = this.toggleFilters.bind(this); this.toggleList = this.toggleList.bind(this); this.checkFilter = this.checkFilter.bind(this); this.clear = this.clear.bind(this); this.createOrderField = this.createOrderField.bind(this); this.checkActiveStatus = this.checkActiveStatus.bind(this); this.activeFilter = this.activeFilter.bind(this); this.deactiveFilter = this.deactiveFilter.bind(this); this.getFilterFields = this.getFilterFields.bind(this); this.getListFields = this.getListFields.bind(this); this.hideContainer = this.hideContainer.bind(this); this.showContainer = this.showContainer.bind(this); this.toggleContainer = this.toggleContainer.bind(this); this.toggleDirection = this.toggleDirection.bind(this); this.updateFieldValue = this.updateFieldValue.bind(this); this.findOption = this.findOption.bind(this); if (this.filterContainer && this.filterContainer.classList.contains('js-stools-container-filters-visible')) { this.showFilters(); this.showList(); } else { this.hideFilters(); this.hideList(); } if (this.filterButton) { this.filterButton.addEventListener('click', e => { self.toggleFilters(); e.stopPropagation(); e.preventDefault(); }); } if (this.listButton) { this.listButton.addEventListener('click', e => { self.toggleList(); e.stopPropagation(); e.preventDefault(); }); } // Do we need to add to mark filter as enabled? this.getFilterFields().forEach(i => { self.checkFilter(i); i.addEventListener('change', () => { self.checkFilter(i); }); }); if (this.clearButton) { this.clearButton.addEventListener('click', self.clear); } // Check/create ordering field this.createOrderField(); this.orderCols.forEach(item => { item.addEventListener('click', ({ target }) => { const element = target.tagName.toLowerCase() === 'span' ? target.parentNode : target; // Order to set const newOrderCol = element.getAttribute('data-order'); const newDirection = element.getAttribute('data-direction'); const newOrdering = `${newOrderCol} ${newDirection}`; // The data-order attribute is required if (newOrderCol.length) { self.activeColumn = newOrderCol; if (newOrdering !== self.activeOrder) { self.activeDirection = newDirection; self.activeOrder = newOrdering; // Update the order field self.updateFieldValue(self.orderField, newOrdering); } else { self.toggleDirection(); } self.theForm.submit(); } }); }); this.checkActiveStatus(this); } checkFilter(element) { if (element.tagName.toLowerCase() === 'select') { const option = element.querySelector('option:checked'); if (option) { if (option.value !== '') { this.activeFilter(element, this); } else { this.deactiveFilter(element, this); } } } else if (element.value !== '') { this.activeFilter(element, this); } else { this.deactiveFilter(element, this); } } clear() { const self = this; if (self.searchField) { self.searchField.value = ''; } self.getFilterFields().forEach(i => { i.value = ''; self.checkFilter(i); if (window.jQuery && window.jQuery.chosen) { window.jQuery(i).trigger('chosen:updated'); } }); if (self.clearListOptions) { self.getListFields().forEach(i => { i.value = ''; self.checkFilter(i); if (window.jQuery && window.jQuery.chosen) { window.jQuery(i).trigger('chosen:updated'); } }); // Special case to limit box to the default config limit document.querySelector('#list_limit').value = self.options.defaultLimit; if (window.jQuery && window.jQuery.chosen) { window.jQuery('#list_limit').trigger('chosen:updated'); } } self.theForm.submit(); } // eslint-disable-next-line class-methods-use-this updateFilterCount(count) { if (this.clearButton) { this.clearButton.disabled = count === 0 && !this.searchString.length; } } // eslint-disable-next-line class-methods-use-this checkActiveStatus(cont) { let activeFilterCount = 0; this.getFilterFields().forEach(item => { if (item.classList.contains('active')) { activeFilterCount += 1; cont.filterButton.classList.remove('btn-secondary'); cont.filterButton.classList.add('btn-primary'); } }); // If there are no active filters - remove the filtered caption area from the table if (activeFilterCount === 0) { const filteredByCaption = document.getElementById('filteredBy'); if (filteredByCaption) { filteredByCaption.parentNode.removeChild(filteredByCaption); } } // Disable clear button when no filter is active and search is empty if (this.clearButton) { this.clearButton.disabled = activeFilterCount === 0 && !this.searchString.length; } } // eslint-disable-next-line class-methods-use-this activeFilter(element) { element.classList.add('active'); const chosenId = `#${element.getAttribute('id')}`; const tmpEl = element.querySelector(chosenId); if (tmpEl) { tmpEl.classList.add('active'); } // Add all active filters to the table caption for screen-readers const filteredByCaption = document.getElementById('filteredBy'); const isHidden = Object.prototype.hasOwnProperty.call(element.attributes, 'type') && element.attributes.type.value === 'hidden'; // The caption won't exist if no items match the filters so check for the element first if (filteredByCaption && !isHidden) { let captionContent = ''; if (element.tagName.toLowerCase() === 'select') { if (element.multiple === true) { const selectedOptions = element.querySelectorAll('option:checked'); const selectedTextValues = [].slice.call(selectedOptions).map(el => el.text); captionContent = `${element.labels[0].textContent} - ${selectedTextValues.join()}`; } else { captionContent = `${element.labels[0].textContent} - ${element.options[element.selectedIndex].text}`; } } else { captionContent = `${element.labels[0].textContent} - ${element.value}`; } filteredByCaption.textContent += captionContent; } } // eslint-disable-next-line class-methods-use-this deactiveFilter(element) { element.classList.remove('active'); const chosenId = `#${element.getAttribute('id')}`; const tmpEl = element.querySelector(chosenId); if (tmpEl) { tmpEl.classList.remove('active'); } } // eslint-disable-next-line consistent-return getFilterFields() { if (this.filterContainer) { return Array.prototype.slice.call(this.filterContainer.querySelectorAll('select,input')); } return []; } getListFields() { return Array.prototype.slice.call(this.listContainer.querySelectorAll('select')); } // Common container functions // eslint-disable-next-line class-methods-use-this hideContainer(container) { if (container) { container.classList.remove('js-stools-container-filters-visible'); document.body.classList.remove('filters-shown'); } } // eslint-disable-next-line class-methods-use-this showContainer(container) { container.classList.add('js-stools-container-filters-visible'); document.body.classList.add('filters-shown'); } toggleContainer(container) { if (container.classList.contains('js-stools-container-filters-visible')) { this.hideContainer(container); } else { this.showContainer(container); } } // List container management hideList() { this.hideContainer(this.filterContainer); } showList() { this.showContainer(this.filterContainer); } toggleList() { this.toggleContainer(this.filterContainer); } // Filters container management hideFilters() { this.hideContainer(this.filterContainer); } showFilters() { this.showContainer(this.filterContainer); } toggleFilters() { this.toggleContainer(this.filterContainer); } toggleDirection() { const self = this; let newDirection = 'ASC'; if (self.activeDirection.toUpperCase() === 'ASC') { newDirection = 'DESC'; } self.activeDirection = newDirection; self.activeOrder = `${self.activeColumn} ${newDirection}`; self.updateFieldValue(self.orderField, self.activeOrder); } createOrderField() { const self = this; if (!this.orderField) { this.orderField = document.createElement('input'); this.orderField.setAttribute('type', 'hidden'); this.orderField.setAttribute('id', 'js-stools-field-order'); this.orderField.setAttribute('class', 'js-stools-field-order'); this.orderField.setAttribute('name', self.options.orderFieldName); this.orderField.setAttribute('value', `${self.activeOrder} ${this.activeDirection}`); this.theForm.append(this.orderField); } // Add missing columns to the order select if (this.orderField.tagName.toLowerCase() === 'select') { const allOptions = [].slice.call(this.orderField.options); allOptions.forEach(option => { let value = option.getAttribute('data-order'); const name = option.getAttribute('data-name'); const direction = option.getAttribute('data-direction'); if (value && value.length) { value = `${value} ${direction}`; let $option = self.findOption(self.orderField, value); if (!$option.length) { $option = document.createElement('option'); $option.text = name; $option.value = value; // If it is the active option select it if (option.classList.contains('active')) { $option.setAttribute('selected', 'selected'); } // Append the option and repopulate the chosen field this.orderFieldName.innerHTML += Joomla.sanitizeHtml($option); } } }); if (window.jQuery && window.jQuery.chosen) { window.jQuery(this.orderField).trigger('chosen:updated'); } } this.activeOrder = this.orderField.value; } // eslint-disable-next-line class-methods-use-this updateFieldValue(field, newValue) { const type = field.getAttribute('type'); if (type === 'hidden' || type === 'text') { field.setAttribute('value', newValue); } else if (field.tagName.toLowerCase() === 'select') { const allOptions = [].slice.call(field.options); let desiredOption; // Select the option result allOptions.forEach(option => { if (option.value === newValue) { desiredOption = option; } }); if (desiredOption && desiredOption.length) { desiredOption.setAttribute('selected', 'selected'); } else { // If the option does not exist create it on the fly const option = document.createElement('option'); option.text = newValue; option.value = newValue; option.setAttribute('selected', 'selected'); // Append the option and repopulate the chosen field field.appendChild(option); } field.value = newValue; // Trigger the chosen update if (window.jQuery && window.jQuery.chosen) { field.trigger('chosen:updated'); } } } // eslint-disable-next-line class-methods-use-this,consistent-return findOption(select, value) { // eslint-disable-next-line no-plusplus for (let i = 0, l = select.length; l > i; i++) { if (select[i].value === value) { return select[i]; } } } } const onBoot = () => { if (Joomla.getOptions('searchtools')) { const options = Joomla.getOptions('searchtools'); const element = document.querySelector(options.selector); // eslint-disable-next-line no-new new Searchtools(element, options); } const sort = document.getElementById('sorted'); const order = document.getElementById('orderedBy'); if (sort && sort.hasAttribute('data-caption') && order) { const orderedBy = sort.getAttribute('data-caption'); order.textContent += orderedBy; } if (sort && sort.hasAttribute('data-sort')) { const ariasort = sort.getAttribute('data-sort'); sort.parentNode.setAttribute('aria-sort', ariasort); } // Cleanup document.removeEventListener('DOMContentLoaded', onBoot); }; // Execute on DOM Loaded Event document.addEventListener('DOMContentLoaded', onBoot); })(Joomla);