[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

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

   1  (function () {
   2    'use strict';
   3  
   4    Joomla = window.Joomla || {};
   5  
   6    (function (Joomla) {
   7      /**
   8       * Method that resets the filter inputs and submits the relative form
   9       *
  10       * @param {HTMLElement}  element  The element that initiates the call
  11       * @returns {void}
  12       * @since   4.0.0
  13       */
  14      Joomla.resetFilters = function (element) {
  15        var form = element.form;
  16  
  17        if (!form) {
  18          throw new Error('Element must be inside a form!');
  19        }
  20  
  21        var elementsArray = [].slice.call(form.elements);
  22  
  23        if (elementsArray.length) {
  24          var newElementsArray = [];
  25          elementsArray.forEach(function (elem) {
  26            // Skip the token, the task, the boxchecked and the calling element
  27            if (elem.getAttribute('name') === 'task' || elem.getAttribute('name') === 'boxchecked' || elem.value === '1' && /^[0-9A-F]{32}$/i.test(elem.name) || elem === element) {
  28              return;
  29            }
  30  
  31            newElementsArray.push(elem);
  32          }); // Reset all filters
  33  
  34          newElementsArray.forEach(function (elem) {
  35            elem.value = '';
  36          });
  37          form.submit();
  38        }
  39      };
  40  
  41      var Searchtools = /*#__PURE__*/function () {
  42        function Searchtools(elem, options) {
  43          var defaults = {
  44            // Form options
  45            formSelector: '.js-stools-form',
  46            // Search
  47            searchFieldSelector: '.js-stools-field-search',
  48            clearBtnSelector: '.js-stools-btn-clear',
  49            // Global container
  50            mainContainerSelector: '.js-stools',
  51            // Filter fields
  52            searchBtnSelector: '.js-stools-btn-search',
  53            filterBtnSelector: '.js-stools-btn-filter',
  54            filterContainerSelector: '.js-stools-container-filters',
  55            filtersHidden: true,
  56            // List fields
  57            listBtnSelector: '.js-stools-btn-list',
  58            listContainerSelector: '.js-stools-container-list',
  59            listHidden: true,
  60            // Ordering specific
  61            orderColumnSelector: '.js-stools-column-order',
  62            orderBtnSelector: '.js-stools-btn-order',
  63            orderFieldSelector: '.js-stools-field-order',
  64            orderFieldName: 'list[fullordering]',
  65            limitFieldSelector: '.js-stools-field-limit',
  66            defaultLimit: 20,
  67            activeOrder: null,
  68            activeDirection: 'ASC',
  69            // Extra
  70            clearListOptions: false
  71          };
  72          this.element = elem;
  73          this.options = Joomla.extend(defaults, options); // Initialise selectors
  74  
  75          this.theForm = document.querySelector(this.options.formSelector); // Filters
  76  
  77          this.filterButton = document.querySelector(this.options.formSelector + " " + this.options.filterBtnSelector);
  78          this.filterContainer = document.querySelector(this.options.formSelector + " " + this.options.filterContainerSelector) ? document.querySelector(this.options.formSelector + " " + this.options.filterContainerSelector) : '';
  79          this.filtersHidden = this.options.filtersHidden; // List fields
  80  
  81          this.listButton = document.querySelector(this.options.listBtnSelector);
  82          this.listContainer = document.querySelector(this.options.formSelector + " " + this.options.listContainerSelector);
  83          this.listHidden = this.options.listHidden; // Main container
  84  
  85          this.mainContainer = document.querySelector(this.options.mainContainerSelector); // Search
  86  
  87          this.searchButton = document.querySelector(this.options.formSelector + " " + this.options.searchBtnSelector);
  88          this.searchField = document.querySelector(this.options.formSelector + " " + this.options.searchFieldSelector);
  89          this.searchString = null;
  90          this.clearButton = document.querySelector(this.options.clearBtnSelector); // Ordering
  91  
  92          this.orderCols = Array.prototype.slice.call(document.querySelectorAll(this.options.formSelector + " " + this.options.orderColumnSelector));
  93          this.orderField = document.querySelector(this.options.formSelector + " " + this.options.orderFieldSelector); // Limit
  94  
  95          this.limitField = document.querySelector(this.options.formSelector + " " + this.options.limitFieldSelector); // Init trackers
  96  
  97          this.activeColumn = null;
  98          this.activeDirection = this.options.activeDirection;
  99          this.activeOrder = this.options.activeOrder;
 100          this.activeLimit = null; // Extra options
 101  
 102          this.clearListOptions = this.options.clearListOptions;
 103          var self = this; // Get values
 104  
 105          this.searchString = this.searchField ? this.searchField.value : ''; // Do some binding
 106  
 107          this.showFilters = this.showFilters.bind(this);
 108          this.hideFilters = this.hideFilters.bind(this);
 109          this.showList = this.showList.bind(this);
 110          this.hideList = this.hideList.bind(this);
 111          this.toggleFilters = this.toggleFilters.bind(this);
 112          this.toggleList = this.toggleList.bind(this);
 113          this.checkFilter = this.checkFilter.bind(this);
 114          this.clear = this.clear.bind(this);
 115          this.createOrderField = this.createOrderField.bind(this);
 116          this.checkActiveStatus = this.checkActiveStatus.bind(this);
 117          this.activeFilter = this.activeFilter.bind(this);
 118          this.deactiveFilter = this.deactiveFilter.bind(this);
 119          this.getFilterFields = this.getFilterFields.bind(this);
 120          this.getListFields = this.getListFields.bind(this);
 121          this.hideContainer = this.hideContainer.bind(this);
 122          this.showContainer = this.showContainer.bind(this);
 123          this.toggleContainer = this.toggleContainer.bind(this);
 124          this.toggleDirection = this.toggleDirection.bind(this);
 125          this.updateFieldValue = this.updateFieldValue.bind(this);
 126          this.findOption = this.findOption.bind(this);
 127  
 128          if (this.filterContainer && this.filterContainer.classList.contains('js-stools-container-filters-visible')) {
 129            this.showFilters();
 130            this.showList();
 131          } else {
 132            this.hideFilters();
 133            this.hideList();
 134          }
 135  
 136          if (this.filterButton) {
 137            this.filterButton.addEventListener('click', function (e) {
 138              self.toggleFilters();
 139              e.stopPropagation();
 140              e.preventDefault();
 141            });
 142          }
 143  
 144          if (this.listButton) {
 145            this.listButton.addEventListener('click', function (e) {
 146              self.toggleList();
 147              e.stopPropagation();
 148              e.preventDefault();
 149            });
 150          } // Do we need to add to mark filter as enabled?
 151  
 152  
 153          this.getFilterFields().forEach(function (i) {
 154            self.checkFilter(i);
 155            i.addEventListener('change', function () {
 156              self.checkFilter(i);
 157            });
 158          });
 159  
 160          if (this.clearButton) {
 161            this.clearButton.addEventListener('click', self.clear);
 162          } // Check/create ordering field
 163  
 164  
 165          this.createOrderField();
 166          this.orderCols.forEach(function (item) {
 167            item.addEventListener('click', function (_ref) {
 168              var target = _ref.target;
 169              var element = target.tagName.toLowerCase() === 'span' ? target.parentNode : target; // Order to set
 170  
 171              var newOrderCol = element.getAttribute('data-order');
 172              var newDirection = element.getAttribute('data-direction');
 173              var newOrdering = newOrderCol + " " + newDirection; // The data-order attribute is required
 174  
 175              if (newOrderCol.length) {
 176                self.activeColumn = newOrderCol;
 177  
 178                if (newOrdering !== self.activeOrder) {
 179                  self.activeDirection = newDirection;
 180                  self.activeOrder = newOrdering; // Update the order field
 181  
 182                  self.updateFieldValue(self.orderField, newOrdering);
 183                } else {
 184                  self.toggleDirection();
 185                }
 186  
 187                self.theForm.submit();
 188              }
 189            });
 190          });
 191          this.checkActiveStatus(this);
 192        }
 193  
 194        var _proto = Searchtools.prototype;
 195  
 196        _proto.checkFilter = function checkFilter(element) {
 197          if (element.tagName.toLowerCase() === 'select') {
 198            var option = element.querySelector('option:checked');
 199  
 200            if (option) {
 201              if (option.value !== '') {
 202                this.activeFilter(element, this);
 203              } else {
 204                this.deactiveFilter(element, this);
 205              }
 206            }
 207          } else if (element.value !== '') {
 208            this.activeFilter(element, this);
 209          } else {
 210            this.deactiveFilter(element, this);
 211          }
 212        };
 213  
 214        _proto.clear = function clear() {
 215          var self = this;
 216  
 217          if (self.searchField) {
 218            self.searchField.value = '';
 219          }
 220  
 221          self.getFilterFields().forEach(function (i) {
 222            i.value = '';
 223            self.checkFilter(i);
 224  
 225            if (window.jQuery && window.jQuery.chosen) {
 226              window.jQuery(i).trigger('chosen:updated');
 227            }
 228          });
 229  
 230          if (self.clearListOptions) {
 231            self.getListFields().forEach(function (i) {
 232              i.value = '';
 233              self.checkFilter(i);
 234  
 235              if (window.jQuery && window.jQuery.chosen) {
 236                window.jQuery(i).trigger('chosen:updated');
 237              }
 238            }); // Special case to limit box to the default config limit
 239  
 240            document.querySelector('#list_limit').value = self.options.defaultLimit;
 241  
 242            if (window.jQuery && window.jQuery.chosen) {
 243              window.jQuery('#list_limit').trigger('chosen:updated');
 244            }
 245          }
 246  
 247          self.theForm.submit();
 248        } // eslint-disable-next-line class-methods-use-this
 249        ;
 250  
 251        _proto.updateFilterCount = function updateFilterCount(count) {
 252          if (this.clearButton) {
 253            this.clearButton.disabled = count === 0 && !this.searchString.length;
 254          }
 255        } // eslint-disable-next-line class-methods-use-this
 256        ;
 257  
 258        _proto.checkActiveStatus = function checkActiveStatus(cont) {
 259          var activeFilterCount = 0;
 260          this.getFilterFields().forEach(function (item) {
 261            if (item.classList.contains('active')) {
 262              activeFilterCount += 1;
 263              cont.filterButton.classList.remove('btn-secondary');
 264              cont.filterButton.classList.add('btn-primary');
 265            }
 266          }); // If there are no active filters - remove the filtered caption area from the table
 267  
 268          if (activeFilterCount === 0) {
 269            var filteredByCaption = document.getElementById('filteredBy');
 270  
 271            if (filteredByCaption) {
 272              filteredByCaption.parentNode.removeChild(filteredByCaption);
 273            }
 274          } // Disable clear button when no filter is active and search is empty
 275  
 276  
 277          if (this.clearButton) {
 278            this.clearButton.disabled = activeFilterCount === 0 && !this.searchString.length;
 279          }
 280        } // eslint-disable-next-line class-methods-use-this
 281        ;
 282  
 283        _proto.activeFilter = function activeFilter(element) {
 284          element.classList.add('active');
 285          var chosenId = "#" + element.getAttribute('id');
 286          var tmpEl = element.querySelector(chosenId);
 287  
 288          if (tmpEl) {
 289            tmpEl.classList.add('active');
 290          } // Add all active filters to the table caption for screen-readers
 291  
 292  
 293          var filteredByCaption = document.getElementById('filteredBy');
 294          var 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
 295  
 296          if (filteredByCaption && !isHidden) {
 297            var captionContent = '';
 298  
 299            if (element.tagName.toLowerCase() === 'select') {
 300              if (element.multiple === true) {
 301                var selectedOptions = element.querySelectorAll('option:checked');
 302                var selectedTextValues = [].slice.call(selectedOptions).map(function (el) {
 303                  return el.text;
 304                });
 305                captionContent = element.labels[0].textContent + " - " + selectedTextValues.join();
 306              } else {
 307                captionContent = element.labels[0].textContent + " - " + element.options[element.selectedIndex].text;
 308              }
 309            } else {
 310              captionContent = element.labels[0].textContent + " - " + element.value;
 311            }
 312  
 313            filteredByCaption.textContent += captionContent;
 314          }
 315        } // eslint-disable-next-line class-methods-use-this
 316        ;
 317  
 318        _proto.deactiveFilter = function deactiveFilter(element) {
 319          element.classList.remove('active');
 320          var chosenId = "#" + element.getAttribute('id');
 321          var tmpEl = element.querySelector(chosenId);
 322  
 323          if (tmpEl) {
 324            tmpEl.classList.remove('active');
 325          }
 326        } // eslint-disable-next-line consistent-return
 327        ;
 328  
 329        _proto.getFilterFields = function getFilterFields() {
 330          if (this.filterContainer) {
 331            return Array.prototype.slice.call(this.filterContainer.querySelectorAll('select,input'));
 332          }
 333  
 334          return [];
 335        };
 336  
 337        _proto.getListFields = function getListFields() {
 338          return Array.prototype.slice.call(this.listContainer.querySelectorAll('select'));
 339        } // Common container functions
 340        // eslint-disable-next-line class-methods-use-this
 341        ;
 342  
 343        _proto.hideContainer = function hideContainer(container) {
 344          if (container) {
 345            container.classList.remove('js-stools-container-filters-visible');
 346            document.body.classList.remove('filters-shown');
 347          }
 348        } // eslint-disable-next-line class-methods-use-this
 349        ;
 350  
 351        _proto.showContainer = function showContainer(container) {
 352          container.classList.add('js-stools-container-filters-visible');
 353          document.body.classList.add('filters-shown');
 354        };
 355  
 356        _proto.toggleContainer = function toggleContainer(container) {
 357          if (container.classList.contains('js-stools-container-filters-visible')) {
 358            this.hideContainer(container);
 359          } else {
 360            this.showContainer(container);
 361          }
 362        } // List container management
 363        ;
 364  
 365        _proto.hideList = function hideList() {
 366          this.hideContainer(this.filterContainer);
 367        };
 368  
 369        _proto.showList = function showList() {
 370          this.showContainer(this.filterContainer);
 371        };
 372  
 373        _proto.toggleList = function toggleList() {
 374          this.toggleContainer(this.filterContainer);
 375        } // Filters container management
 376        ;
 377  
 378        _proto.hideFilters = function hideFilters() {
 379          this.hideContainer(this.filterContainer);
 380        };
 381  
 382        _proto.showFilters = function showFilters() {
 383          this.showContainer(this.filterContainer);
 384        };
 385  
 386        _proto.toggleFilters = function toggleFilters() {
 387          this.toggleContainer(this.filterContainer);
 388        };
 389  
 390        _proto.toggleDirection = function toggleDirection() {
 391          var self = this;
 392          var newDirection = 'ASC';
 393  
 394          if (self.activeDirection.toUpperCase() === 'ASC') {
 395            newDirection = 'DESC';
 396          }
 397  
 398          self.activeDirection = newDirection;
 399          self.activeOrder = self.activeColumn + " " + newDirection;
 400          self.updateFieldValue(self.orderField, self.activeOrder);
 401        };
 402  
 403        _proto.createOrderField = function createOrderField() {
 404          var _this = this;
 405  
 406          var self = this;
 407  
 408          if (!this.orderField) {
 409            this.orderField = document.createElement('input');
 410            this.orderField.setAttribute('type', 'hidden');
 411            this.orderField.setAttribute('id', 'js-stools-field-order');
 412            this.orderField.setAttribute('class', 'js-stools-field-order');
 413            this.orderField.setAttribute('name', self.options.orderFieldName);
 414            this.orderField.setAttribute('value', self.activeOrder + " " + this.activeDirection);
 415            this.theForm.append(this.orderField);
 416          } // Add missing columns to the order select
 417  
 418  
 419          if (this.orderField.tagName.toLowerCase() === 'select') {
 420            var allOptions = [].slice.call(this.orderField.options);
 421            allOptions.forEach(function (option) {
 422              var value = option.getAttribute('data-order');
 423              var name = option.getAttribute('data-name');
 424              var direction = option.getAttribute('data-direction');
 425  
 426              if (value && value.length) {
 427                value = value + " " + direction;
 428                var $option = self.findOption(self.orderField, value);
 429  
 430                if (!$option.length) {
 431                  $option = document.createElement('option');
 432                  $option.text = name;
 433                  $option.value = value; // If it is the active option select it
 434  
 435                  if (option.classList.contains('active')) {
 436                    $option.setAttribute('selected', 'selected');
 437                  } // Append the option and repopulate the chosen field
 438  
 439  
 440                  _this.orderFieldName.innerHTML += Joomla.sanitizeHtml($option);
 441                }
 442              }
 443            });
 444  
 445            if (window.jQuery && window.jQuery.chosen) {
 446              window.jQuery(this.orderField).trigger('chosen:updated');
 447            }
 448          }
 449  
 450          this.activeOrder = this.orderField.value;
 451        } // eslint-disable-next-line class-methods-use-this
 452        ;
 453  
 454        _proto.updateFieldValue = function updateFieldValue(field, newValue) {
 455          var type = field.getAttribute('type');
 456  
 457          if (type === 'hidden' || type === 'text') {
 458            field.setAttribute('value', newValue);
 459          } else if (field.tagName.toLowerCase() === 'select') {
 460            var allOptions = [].slice.call(field.options);
 461            var desiredOption; // Select the option result
 462  
 463            allOptions.forEach(function (option) {
 464              if (option.value === newValue) {
 465                desiredOption = option;
 466              }
 467            });
 468  
 469            if (desiredOption && desiredOption.length) {
 470              desiredOption.setAttribute('selected', 'selected');
 471            } else {
 472              // If the option does not exist create it on the fly
 473              var option = document.createElement('option');
 474              option.text = newValue;
 475              option.value = newValue;
 476              option.setAttribute('selected', 'selected'); // Append the option and repopulate the chosen field
 477  
 478              field.appendChild(option);
 479            }
 480  
 481            field.value = newValue; // Trigger the chosen update
 482  
 483            if (window.jQuery && window.jQuery.chosen) {
 484              field.trigger('chosen:updated');
 485            }
 486          }
 487        } // eslint-disable-next-line class-methods-use-this,consistent-return
 488        ;
 489  
 490        _proto.findOption = function findOption(select, value) {
 491          // eslint-disable-next-line no-plusplus
 492          for (var i = 0, l = select.length; l > i; i++) {
 493            if (select[i].value === value) {
 494              return select[i];
 495            }
 496          }
 497        };
 498  
 499        return Searchtools;
 500      }();
 501  
 502      var onBoot = function onBoot() {
 503        if (Joomla.getOptions('searchtools')) {
 504          var options = Joomla.getOptions('searchtools');
 505          var element = document.querySelector(options.selector); // eslint-disable-next-line no-new
 506  
 507          new Searchtools(element, options);
 508        }
 509  
 510        var sort = document.getElementById('sorted');
 511        var order = document.getElementById('orderedBy');
 512  
 513        if (sort && sort.hasAttribute('data-caption') && order) {
 514          var orderedBy = sort.getAttribute('data-caption');
 515          order.textContent += orderedBy;
 516        }
 517  
 518        if (sort && sort.hasAttribute('data-sort')) {
 519          var ariasort = sort.getAttribute('data-sort');
 520          sort.parentNode.setAttribute('aria-sort', ariasort);
 521        } // Cleanup
 522  
 523  
 524        document.removeEventListener('DOMContentLoaded', onBoot);
 525      }; // Execute on DOM Loaded Event
 526  
 527  
 528      document.addEventListener('DOMContentLoaded', onBoot);
 529    })(Joomla);
 530  
 531  })();


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