[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |