芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/public_html/media/system/js/showon.js
/** * @copyright (C) 2018 Open Source Matters, Inc.
* @license GNU General Public License version 2 or later; see LICENSE.txt */ (document => { /* * JField 'showon' class */ class Showon { /* * Constructor * * @param {HTMLElement} cont Container element */ constructor(cont) { const self = this; this.container = cont || document; this.fields = {// origin-field-name: { // origin: ['collection of all the trigger nodes'], // targets: ['collection of nodes to be controlled control'] // } }; this.showonFields = [].slice.call(this.container.querySelectorAll('[data-showon]')); // Populate the fields data if (this.showonFields.length) { // @todo refactor this, dry this.showonFields.forEach(field => { // Set up only once if (field.hasAttribute('data-showon-initialised')) { return; } field.setAttribute('data-showon-initialised', ''); const jsondata = field.getAttribute('data-showon') || ''; const showonData = JSON.parse(jsondata); let localFields; if (showonData.length) { localFields = [].slice.call(self.container.querySelectorAll(`[name="${showonData[0].field}"], [name="${showonData[0].field}[]"]`)); if (!this.fields[showonData[0].field]) { this.fields[showonData[0].field] = { origin: [], targets: [] }; } // Add trigger elements localFields.forEach(cField => { if (this.fields[showonData[0].field].origin.indexOf(cField) === -1) { this.fields[showonData[0].field].origin.push(cField); } }); // Add target elements this.fields[showonData[0].field].targets.push(field); // Data showon can have multiple values if (showonData.length > 1) { showonData.forEach((value, index) => { if (index === 0) { return; } localFields = [].slice.call(self.container.querySelectorAll(`[name="${value.field}"], [name="${value.field}[]"]`)); if (!this.fields[showonData[0].field]) { this.fields[showonData[0].field] = { origin: [], targets: [] }; } // Add trigger elements localFields.forEach(cField => { if (this.fields[showonData[0].field].origin.indexOf(cField) === -1) { this.fields[showonData[0].field].origin.push(cField); } }); // Add target elements if (this.fields[showonData[0].field].targets.indexOf(field) === -1) { this.fields[showonData[0].field].targets.push(field); } }); } } }); // Do some binding this.linkedOptions = this.linkedOptions.bind(this); // Attach events to referenced element, to check condition on change and keyup Object.keys(this.fields).forEach(key => { if (this.fields[key].origin.length) { this.fields[key].origin.forEach(elem => { // Initialize the showon behaviour for the given HTMLElement self.linkedOptions(key); // Setup listeners elem.addEventListener('change', () => { self.linkedOptions(key); }); elem.addEventListener('keyup', () => { self.linkedOptions(key); }); elem.addEventListener('click', () => { self.linkedOptions(key); }); }); } }); } } /** * * @param key */ linkedOptions(key) { // Loop through the elements that need to be either shown or hidden this.fields[key].targets.forEach(field => { const elementShowonDatas = JSON.parse(field.getAttribute('data-showon')) || []; let showfield = true; let itemval; // Check if target conditions are satisfied elementShowonDatas.forEach((elementShowonData, index) => { const condition = elementShowonData || {}; condition.valid = 0; // Test in each of the elements in the field array if condition is valid this.fields[key].origin.forEach(originField => { if (originField.name !== elementShowonData.field) { return; } const originId = originField.id; // If checkbox or radio box the value is read from properties if (originField.getAttribute('type') && ['checkbox', 'radio'].indexOf(originField.getAttribute('type').toLowerCase()) !== -1) { if (!originField.checked) { // Unchecked fields will return a blank and so always match // a != condition so we skip them return; } itemval = document.getElementById(originId).value; } else { // Select lists, text-area etc. Note that multiple-select list returns // an Array here s0 we can always treat 'itemval' as an array itemval = document.getElementById(originId).value; // A multi-select
$field will return null when no elements are // selected so we need to define itemval accordingly if (itemval === null && originField.tagName.toLowerCase() === 'select') { itemval = []; } } // Convert to array to allow multiple values in the field (e.g. type=list multiple) // and normalize as string if (!(typeof itemval === 'object')) { itemval = JSON.parse(`["${itemval}"]`); } // Test if any of the values of the field exists in showon conditions itemval.forEach(val => { // ":" Equal to one or more of the values condition if (condition.sign === '=' && condition.values.indexOf(val) !== -1) { condition.valid = 1; } // "!:" Not equal to one or more of the values condition if (condition.sign === '!=' && condition.values.indexOf(val) === -1) { condition.valid = 1; } }); }); // Verify conditions // First condition (no operator): current condition must be valid if (condition.op === '') { if (condition.valid === 0) { showfield = false; } } else { // Other conditions (if exists) // AND operator: both the previous and current conditions must be valid if (condition.op === 'AND' && condition.valid + elementShowonDatas[index - 1].valid < 2) { showfield = false; condition.valid = 0; } // OR operator: one of the previous and current conditions must be valid if (condition.op === 'OR' && condition.valid + elementShowonDatas[index - 1].valid > 0) { showfield = true; condition.valid = 1; } } }); // If conditions are satisfied show the target field(s), else hide if (field.tagName !== 'option') { if (showfield) { field.classList.remove('hidden'); } else { field.classList.add('hidden'); } } else { // TODO: If chosen or choices.js is active we should update them field.disabled = !showfield; } }); } } // Provide a public API window.Joomla = window.Joomla || {}; if (!Joomla.Showon) { Joomla.Showon = { initialise: container => new Showon(container) }; } /** * Initialize 'showon' feature at an initial page load */ document.addEventListener('DOMContentLoaded', () => { Joomla.Showon.initialise(document); }); /** * Initialize 'showon' feature when part of the page was updated */ document.addEventListener('joomla:updated', ({ target }) => { // Check is it subform, then wee need to fix some "showon" config if (target.classList.contains('subform-repeatable-group')) { const elements = [].slice.call(target.querySelectorAll('[data-showon]')); const search = new RegExp(`\\[${target.dataset.baseName}X\\]`, 'g'); const replace = `[${target.dataset.group}]`; // Fix showon field names in a current group elements.forEach(element => { const showon = element.dataset.showon.replace(search, replace); element.dataset.showon = showon; }); } Joomla.Showon.initialise(target); }); })(document);