Current File : /home/pacjaorg/wpt.pacja.org/km/media/system/js/showon-es5.js |
(function () {
'use strict';
/**
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
/**
* JField 'showon' class
*/
var Showon = /*#__PURE__*/function () {
/**
* Constructor
*
* @param {HTMLElement} cont Container element
*/
function Showon(cont) {
var _this = this;
var 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(function (field) {
// Set up only once
if (field.hasAttribute('data-showon-initialised')) {
return;
}
field.setAttribute('data-showon-initialised', '');
var jsondata = field.getAttribute('data-showon') || '';
var showonData = JSON.parse(jsondata);
var 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(function (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(function (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(function (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(function (key) {
if (_this.fields[key].origin.length) {
_this.fields[key].origin.forEach(function (elem) {
// Initialize the showon behaviour for the given HTMLElement
self.linkedOptions(key);
// Setup listeners
elem.addEventListener('change', function () {
self.linkedOptions(key);
});
elem.addEventListener('keyup', function () {
self.linkedOptions(key);
});
elem.addEventListener('click', function () {
self.linkedOptions(key);
});
});
}
});
}
}
/**
*
* @param key
*/
var _proto = Showon.prototype;
_proto.linkedOptions = function linkedOptions(key) {
var _this2 = this;
// Loop through the elements that need to be either shown or hidden
this.fields[key].targets.forEach(function (field) {
var elementShowonDatas = JSON.parse(field.getAttribute('data-showon')) || [];
var showfield = true;
var itemval;
// Check if target conditions are satisfied
elementShowonDatas.forEach(function (elementShowonData, index) {
var condition = elementShowonData || {};
condition.valid = 0;
// Test in each of the elements in the field array if condition is valid
_this2.fields[key].origin.forEach(function (originField) {
if (originField.name.replace('[]', '') !== elementShowonData.field) {
return;
}
var originId = originField.id;
// If checkbox or radio box the value is read from properties
if (originField.getAttribute('type') && ['checkbox', 'radio'].includes(originField.getAttribute('type').toLowerCase())) {
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 if (originField.nodeName === 'SELECT' && originField.hasAttribute('multiple')) {
itemval = Array.from(originField.querySelectorAll('option:checked')).map(function (el) {
return el.value;
});
} else {
// Select lists, text-area etc. Note that multiple-select list returns
// an Array here so we can always treat 'itemval' as an array
itemval = document.getElementById(originId).value;
// A multi-select <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(function (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');
field.dispatchEvent(new CustomEvent('joomla:showon-show', {
bubbles: true
}));
} else {
field.classList.add('hidden');
field.dispatchEvent(new CustomEvent('joomla:showon-hide', {
bubbles: true
}));
}
} else {
// @todo: If chosen or choices.js is active we should update them
field.disabled = !showfield;
}
});
};
return Showon;
}();
if (!window.Joomla) {
throw new Error('Joomla API is not properly initialized');
}
// Provide a public API
if (!Joomla.Showon) {
Joomla.Showon = {
initialise: function initialise(container) {
return new Showon(container);
}
};
}
/**
* Initialize 'showon' feature at an initial page load
*/
Joomla.Showon.initialise(document);
/**
* Search for matching parents
*
* @param {HTMLElement} $child
* @param {String} selector
* @returns {HTMLElement[]}
*/
var getMatchedParents = function getMatchedParents($child, selector) {
var $parent = $child;
var $matchingParent;
var parents = [];
while ($parent) {
$matchingParent = $parent.matches && $parent.matches(selector) ? $parent : null;
if ($matchingParent) {
parents.unshift($matchingParent);
}
$parent = $parent.parentNode;
}
return parents;
};
/**
* Initialize 'showon' feature when part of the page was updated
*/
document.addEventListener('joomla:updated', function (_ref) {
var target = _ref.target;
// Check is it subform, then wee need to fix some "showon" config
if (target.classList.contains('subform-repeatable-group')) {
var elements = [].slice.call(target.querySelectorAll('[data-showon]'));
if (elements.length) {
var search = [];
var replace = [];
// Collect all parent groups of changed group
getMatchedParents(target, '.subform-repeatable-group').forEach(function ($parent) {
search.push(new RegExp("\\[" + $parent.dataset.baseName + "X\\]", 'g'));
replace.push("[" + $parent.dataset.group + "]");
});
// Fix showon field names in a current group
elements.forEach(function (element) {
var showon = element.dataset.showon;
search.forEach(function (pattern, i) {
showon = showon.replace(pattern, replace[i]);
});
element.dataset.showon = showon;
});
}
}
Joomla.Showon.initialise(target);
});
})();