[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/system/js/ -> showon-es5.js (source)

   1  (function () {
   2    'use strict';
   3  
   4    /**
   5     * @copyright  (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
   6     * @license    GNU General Public License version 2 or later; see LICENSE.txt
   7     */
   8  
   9    /**
  10     * JField 'showon' class
  11     */
  12    var Showon = /*#__PURE__*/function () {
  13      /**
  14       * Constructor
  15       *
  16       * @param {HTMLElement} cont Container element
  17       */
  18      function Showon(cont) {
  19        var _this = this;
  20  
  21        var self = this;
  22        this.container = cont || document;
  23        this.fields = {// origin-field-name: {
  24          //   origin:  ['collection of all the trigger nodes'],
  25          //   targets: ['collection of nodes to be controlled control']
  26          // }
  27        };
  28        this.showonFields = [].slice.call(this.container.querySelectorAll('[data-showon]')); // Populate the fields data
  29  
  30        if (this.showonFields.length) {
  31          // @todo refactor this, dry
  32          this.showonFields.forEach(function (field) {
  33            // Set up only once
  34            if (field.hasAttribute('data-showon-initialised')) {
  35              return;
  36            }
  37  
  38            field.setAttribute('data-showon-initialised', '');
  39            var jsondata = field.getAttribute('data-showon') || '';
  40            var showonData = JSON.parse(jsondata);
  41            var localFields;
  42  
  43            if (showonData.length) {
  44              localFields = [].slice.call(self.container.querySelectorAll("[name=\"" + showonData[0].field + "\"], [name=\"" + showonData[0].field + "[]\"]"));
  45  
  46              if (!_this.fields[showonData[0].field]) {
  47                _this.fields[showonData[0].field] = {
  48                  origin: [],
  49                  targets: []
  50                };
  51              } // Add trigger elements
  52  
  53  
  54              localFields.forEach(function (cField) {
  55                if (_this.fields[showonData[0].field].origin.indexOf(cField) === -1) {
  56                  _this.fields[showonData[0].field].origin.push(cField);
  57                }
  58              }); // Add target elements
  59  
  60              _this.fields[showonData[0].field].targets.push(field); // Data showon can have multiple values
  61  
  62  
  63              if (showonData.length > 1) {
  64                showonData.forEach(function (value, index) {
  65                  if (index === 0) {
  66                    return;
  67                  }
  68  
  69                  localFields = [].slice.call(self.container.querySelectorAll("[name=\"" + value.field + "\"], [name=\"" + value.field + "[]\"]"));
  70  
  71                  if (!_this.fields[showonData[0].field]) {
  72                    _this.fields[showonData[0].field] = {
  73                      origin: [],
  74                      targets: []
  75                    };
  76                  } // Add trigger elements
  77  
  78  
  79                  localFields.forEach(function (cField) {
  80                    if (_this.fields[showonData[0].field].origin.indexOf(cField) === -1) {
  81                      _this.fields[showonData[0].field].origin.push(cField);
  82                    }
  83                  }); // Add target elements
  84  
  85                  if (_this.fields[showonData[0].field].targets.indexOf(field) === -1) {
  86                    _this.fields[showonData[0].field].targets.push(field);
  87                  }
  88                });
  89              }
  90            }
  91          }); // Do some binding
  92  
  93          this.linkedOptions = this.linkedOptions.bind(this); // Attach events to referenced element, to check condition on change and keyup
  94  
  95          Object.keys(this.fields).forEach(function (key) {
  96            if (_this.fields[key].origin.length) {
  97              _this.fields[key].origin.forEach(function (elem) {
  98                // Initialize the showon behaviour for the given HTMLElement
  99                self.linkedOptions(key); // Setup listeners
 100  
 101                elem.addEventListener('change', function () {
 102                  self.linkedOptions(key);
 103                });
 104                elem.addEventListener('keyup', function () {
 105                  self.linkedOptions(key);
 106                });
 107                elem.addEventListener('click', function () {
 108                  self.linkedOptions(key);
 109                });
 110              });
 111            }
 112          });
 113        }
 114      }
 115      /**
 116       *
 117       * @param key
 118       */
 119  
 120  
 121      var _proto = Showon.prototype;
 122  
 123      _proto.linkedOptions = function linkedOptions(key) {
 124        var _this2 = this;
 125  
 126        // Loop through the elements that need to be either shown or hidden
 127        this.fields[key].targets.forEach(function (field) {
 128          var elementShowonDatas = JSON.parse(field.getAttribute('data-showon')) || [];
 129          var showfield = true;
 130          var itemval; // Check if target conditions are satisfied
 131  
 132          elementShowonDatas.forEach(function (elementShowonData, index) {
 133            var condition = elementShowonData || {};
 134            condition.valid = 0; // Test in each of the elements in the field array if condition is valid
 135  
 136            _this2.fields[key].origin.forEach(function (originField) {
 137              if (originField.name.replace('[]', '') !== elementShowonData.field) {
 138                return;
 139              }
 140  
 141              var originId = originField.id; // If checkbox or radio box the value is read from properties
 142  
 143              if (originField.getAttribute('type') && ['checkbox', 'radio'].includes(originField.getAttribute('type').toLowerCase())) {
 144                if (!originField.checked) {
 145                  // Unchecked fields will return a blank and so always match
 146                  // a != condition so we skip them
 147                  return;
 148                }
 149  
 150                itemval = document.getElementById(originId).value;
 151              } else if (originField.nodeName === 'SELECT' && originField.hasAttribute('multiple')) {
 152                itemval = Array.from(originField.querySelectorAll('option:checked')).map(function (el) {
 153                  return el.value;
 154                });
 155              } else {
 156                // Select lists, text-area etc. Note that multiple-select list returns
 157                // an Array here s0 we can always treat 'itemval' as an array
 158                itemval = document.getElementById(originId).value; // A multi-select <select> $field  will return null when no elements are
 159                // selected so we need to define itemval accordingly
 160  
 161                if (itemval === null && originField.tagName.toLowerCase() === 'select') {
 162                  itemval = [];
 163                }
 164              } // Convert to array to allow multiple values in the field (e.g. type=list multiple)
 165              // and normalize as string
 166  
 167  
 168              if (!(typeof itemval === 'object')) {
 169                itemval = JSON.parse("[\"" + itemval + "\"]");
 170              } // Test if any of the values of the field exists in showon conditions
 171  
 172  
 173              itemval.forEach(function (val) {
 174                // ":" Equal to one or more of the values condition
 175                if (condition.sign === '=' && condition.values.indexOf(val) !== -1) {
 176                  condition.valid = 1;
 177                } // "!:" Not equal to one or more of the values condition
 178  
 179  
 180                if (condition.sign === '!=' && condition.values.indexOf(val) === -1) {
 181                  condition.valid = 1;
 182                }
 183              });
 184            }); // Verify conditions
 185            // First condition (no operator): current condition must be valid
 186  
 187  
 188            if (condition.op === '') {
 189              if (condition.valid === 0) {
 190                showfield = false;
 191              }
 192            } else {
 193              // Other conditions (if exists)
 194              // AND operator: both the previous and current conditions must be valid
 195              if (condition.op === 'AND' && condition.valid + elementShowonDatas[index - 1].valid < 2) {
 196                showfield = false;
 197                condition.valid = 0;
 198              } // OR operator: one of the previous and current conditions must be valid
 199  
 200  
 201              if (condition.op === 'OR' && condition.valid + elementShowonDatas[index - 1].valid > 0) {
 202                showfield = true;
 203                condition.valid = 1;
 204              }
 205            }
 206          }); // If conditions are satisfied show the target field(s), else hide
 207  
 208          if (field.tagName !== 'option') {
 209            if (showfield) {
 210              field.classList.remove('hidden');
 211              field.dispatchEvent(new CustomEvent('joomla:showon-show', {
 212                bubbles: true
 213              }));
 214            } else {
 215              field.classList.add('hidden');
 216              field.dispatchEvent(new CustomEvent('joomla:showon-hide', {
 217                bubbles: true
 218              }));
 219            }
 220          } else {
 221            // @todo: If chosen or choices.js is active we should update them
 222            field.disabled = !showfield;
 223          }
 224        });
 225      };
 226  
 227      return Showon;
 228    }();
 229  
 230    if (!window.Joomla) {
 231      throw new Error('Joomla API is not properly initialized');
 232    } // Provide a public API
 233  
 234  
 235    if (!Joomla.Showon) {
 236      Joomla.Showon = {
 237        initialise: function initialise(container) {
 238          return new Showon(container);
 239        }
 240      };
 241    }
 242    /**
 243     * Initialize 'showon' feature at an initial page load
 244     */
 245  
 246  
 247    Joomla.Showon.initialise(document);
 248    /**
 249     * Search for matching parents
 250     *
 251     * @param {HTMLElement} $child
 252     * @param {String} selector
 253     * @returns {HTMLElement[]}
 254     */
 255  
 256    var getMatchedParents = function getMatchedParents($child, selector) {
 257      var $parent = $child;
 258      var $matchingParent;
 259      var parents = [];
 260  
 261      while ($parent) {
 262        $matchingParent = $parent.matches && $parent.matches(selector) ? $parent : null;
 263  
 264        if ($matchingParent) {
 265          parents.unshift($matchingParent);
 266        }
 267  
 268        $parent = $parent.parentNode;
 269      }
 270  
 271      return parents;
 272    };
 273    /**
 274     * Initialize 'showon' feature when part of the page was updated
 275     */
 276  
 277  
 278    document.addEventListener('joomla:updated', function (_ref) {
 279      var target = _ref.target;
 280  
 281      // Check is it subform, then wee need to fix some "showon" config
 282      if (target.classList.contains('subform-repeatable-group')) {
 283        var elements = [].slice.call(target.querySelectorAll('[data-showon]'));
 284  
 285        if (elements.length) {
 286          var search = [];
 287          var replace = []; // Collect all parent groups of changed group
 288  
 289          getMatchedParents(target, '.subform-repeatable-group').forEach(function ($parent) {
 290            search.push(new RegExp("\\[" + $parent.dataset.baseName + "X\\]", 'g'));
 291            replace.push("[" + $parent.dataset.group + "]");
 292          }); // Fix showon field names in a current group
 293  
 294          elements.forEach(function (element) {
 295            var showon = element.dataset.showon;
 296            search.forEach(function (pattern, i) {
 297              showon = showon.replace(pattern, replace[i]);
 298            });
 299            element.dataset.showon = showon;
 300          });
 301        }
 302      }
 303  
 304      Joomla.Showon.initialise(target);
 305    });
 306  
 307  })();


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer