[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/system/js/ -> table-columns.js (source)

   1  /**
   2   * TableColumns class for toggle visibility of <table> columns.
   3   */
   4  class TableColumns {
   5    constructor($table, tableName) {
   6      this.$table = $table;
   7      this.tableName = tableName;
   8      this.storageKey = `joomla-tablecolumns-$this.tableName}`;
   9      this.$headers = [].slice.call($table.querySelector('thead tr').children);
  10      this.$rows = [].slice.call($table.querySelectorAll('tbody tr'));
  11      this.listOfHidden = []; // Load previous state
  12  
  13      this.loadState(); // Find protected columns
  14  
  15      this.protectedCols = [0];
  16  
  17      if (this.$rows[0]) {
  18        [].slice.call(this.$rows[0].children).forEach(($el, index) => {
  19          if ($el.nodeName === 'TH') {
  20            this.protectedCols.push(index); // Make sure it's not in the list of hidden
  21  
  22            const ih = this.listOfHidden.indexOf(index);
  23  
  24            if (ih !== -1) {
  25              this.listOfHidden.splice(ih, 1);
  26            }
  27          }
  28        });
  29      } // Set up toggle menu
  30  
  31  
  32      this.createControls(); // Restore state
  33  
  34      this.listOfHidden.forEach(index => {
  35        this.toggleColumn(index, true);
  36      });
  37    }
  38    /**
  39     * Create a controls to select visible columns
  40     */
  41  
  42  
  43    createControls() {
  44      const $divouter = document.createElement('div');
  45      $divouter.setAttribute('class', 'dropdown float-end pb-2');
  46      const $divinner = document.createElement('div');
  47      $divinner.setAttribute('class', 'dropdown-menu dropdown-menu-end');
  48      $divinner.setAttribute('data-bs-popper', 'static'); // Create a toggle button
  49  
  50      const $button = document.createElement('button');
  51      $button.type = 'button';
  52      $button.textContent = Joomla.Text._('JGLOBAL_COLUMNS');
  53      $button.classList.add('btn', 'btn-primary', 'btn-sm', 'dropdown-toggle');
  54      $button.setAttribute('data-bs-toggle', 'dropdown');
  55      $button.setAttribute('data-bs-auto-close', 'false');
  56      $button.setAttribute('aria-haspopup', 'true');
  57      $button.setAttribute('aria-expanded', 'false');
  58      const $ul = document.createElement('ul');
  59      $ul.setAttribute('class', 'list-unstyled p-2');
  60      $ul.setAttribute('id', 'columnList'); // Collect a list of headers for dropdown
  61  
  62      this.$headers.forEach(($el, index) => {
  63        // Skip the first column, unless it's a th, as we don't want to display the checkboxes
  64        if (index === 0 && $el.nodeName !== 'TH') return;
  65        const $li = document.createElement('li');
  66        const $label = document.createElement('label');
  67        const $input = document.createElement('input');
  68        $input.classList.add('form-check-input', 'me-1');
  69        $input.type = 'checkbox';
  70        $input.name = 'table[column][]';
  71        $input.checked = this.listOfHidden.indexOf(index) === -1;
  72        $input.disabled = this.protectedCols.indexOf(index) !== -1;
  73        $input.value = index; // Find the header name
  74  
  75        let $titleEl = $el.querySelector('span');
  76        let title = $titleEl ? $titleEl.textContent.trim() : '';
  77  
  78        if (!title) {
  79          $titleEl = $el.querySelector('span.visually-hidden') || $el;
  80          title = $titleEl.textContent.trim();
  81        }
  82  
  83        if (title.includes(':')) {
  84          title = title.split(':', 2)[1].trim();
  85        }
  86  
  87        $label.textContent = title;
  88        $label.insertAdjacentElement('afterbegin', $input);
  89        $li.appendChild($label);
  90        $ul.appendChild($li);
  91      });
  92      this.$table.insertAdjacentElement('beforebegin', $divouter);
  93      $divouter.appendChild($button);
  94      $divouter.appendChild($divinner);
  95      $divinner.appendChild($ul); // Listen to checkboxes change
  96  
  97      $ul.addEventListener('change', event => {
  98        this.toggleColumn(parseInt(event.target.value, 10));
  99        this.saveState();
 100      }); // Remove "media query" classes, which may prevent toggling from working.
 101  
 102      this.$headers.forEach($el => {
 103        $el.classList.remove('d-none', 'd-md-table-cell', 'd-lg-table-cell', 'd-xl-table-cell');
 104      });
 105      this.$rows.forEach($row => {
 106        [].slice.call($row.children).forEach($el => {
 107          $el.classList.remove('d-none', 'd-md-table-cell', 'd-lg-table-cell', 'd-xl-table-cell');
 108        });
 109      });
 110      this.$button = $button;
 111      this.$menu = $ul;
 112      this.updateCounter();
 113    }
 114    /**
 115     * Update button text
 116     */
 117  
 118  
 119    updateCounter() {
 120      // Don't count the checkboxes column in the total
 121      const total = this.$headers.length - 1;
 122      const visible = total - this.listOfHidden.length;
 123      this.$button.textContent = `$visible}/$total} $Joomla.Text._('JGLOBAL_COLUMNS')}`;
 124    }
 125    /**
 126     * Toggle column visibility
 127     *
 128     * @param {Number} index  The column index
 129     * @param {Boolean} force To force hide
 130     */
 131  
 132  
 133    toggleColumn(index, force) {
 134      // Skip incorrect index
 135      if (!this.$headers[index]) return; // Skip the protected columns
 136  
 137      if (this.protectedCols.indexOf(index) !== -1) return;
 138      const i = this.listOfHidden.indexOf(index);
 139  
 140      if (i === -1) {
 141        this.listOfHidden.push(index);
 142      } else if (force !== true) {
 143        this.listOfHidden.splice(i, 1);
 144      }
 145  
 146      this.$headers[index].classList.toggle('d-none', force);
 147      this.$rows.forEach($col => {
 148        $col.children[index].classList.toggle('d-none', force);
 149      });
 150      this.updateCounter();
 151    }
 152    /**
 153     * Save state, list of hidden columns
 154     */
 155  
 156  
 157    saveState() {
 158      window.localStorage.setItem(this.storageKey, this.listOfHidden.join(','));
 159    }
 160    /**
 161     * Load state, list of hidden columns
 162     */
 163  
 164  
 165    loadState() {
 166      const stored = window.localStorage.getItem(this.storageKey);
 167  
 168      if (stored) {
 169        this.listOfHidden = stored.split(',').map(val => parseInt(val, 10));
 170      }
 171    }
 172  
 173  }
 174  
 175  if (window.innerWidth > 992) {
 176    // Look for dataset name else page-title
 177    [...document.querySelectorAll('table')].forEach($table => {
 178      const tableName = $table.dataset.name ? $table.dataset.name : document.querySelector('.page-title').textContent.trim().replace(/[^a-z0-9]/gi, '-').toLowerCase(); // Skip unnamed table
 179  
 180      if (!tableName) {
 181        return;
 182      }
 183      /* eslint-disable-next-line no-new */
 184  
 185  
 186      new TableColumns($table, tableName);
 187    });
 188  }


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