diff options
| author | Paul Donald | 2026-02-19 23:56:43 +0000 |
|---|---|---|
| committer | Paul Donald | 2026-02-20 00:29:43 +0000 |
| commit | a8db14e2cfe1d35128e3253b2956706f197340a6 (patch) | |
| tree | 4b22364e16a3747ea7454643f92688a5af24acb9 | |
| parent | 39ce4bbc944af70a7a4ac6956c915a5c68b17e49 (diff) | |
| download | luci-a8db14e2cfe1d35128e3253b2956706f197340a6.tar.gz | |
luci-base: handleSort and UITable.update fix
Generated rows for a table need to land in the tbody
so make UITable.update align with this.
follow-up to 2da63d766a765ecae80a1d0a9849fb5f8c5aebb5
The mentioned commit restructured tables. Update sorting
to align with this. Otherwise window.requestAnimationFrame
puts sorted rows in the table element.
Signed-off-by: Paul Donald <newtwen+github@gmail.com>
| -rw-r--r-- | modules/luci-base/htdocs/luci-static/resources/form.js | 18 | ||||
| -rw-r--r-- | modules/luci-base/htdocs/luci-static/resources/ui.js | 21 |
2 files changed, 24 insertions, 15 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index 1fe7fe3ca3..3d87b3d786 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -3636,32 +3636,34 @@ const CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection * @returns {null} */ handleSort(ev) { - if (!ev.target.matches('th[data-sortable-row]')) + const th = ev.target && ev.target.closest ? ev.target.closest('th[data-sortable-row]') : null; + if (!th) return; - const th = ev.target; const descending = (th.getAttribute('data-sort-direction') == 'desc'); const config_name = this.uciconfig ?? this.map.config; let index = 0; const list = []; - ev.currentTarget.querySelectorAll('th').forEach((other_th, i) => { + const headerRow = ev.currentTarget; + headerRow.querySelectorAll('th').forEach((other_th, i) => { if (other_th !== th) other_th.removeAttribute('data-sort-direction'); else index = i; }); - ev.currentTarget.parentNode.querySelectorAll('tr.cbi-section-table-row').forEach(L.bind((tr) => { + const tableEl = headerRow.closest('table') || headerRow.parentNode; + tableEl.querySelectorAll('tr.cbi-section-table-row').forEach(L.bind((tr, i) => { const sid = tr.getAttribute('data-sid'); const opt = tr.childNodes[index].getAttribute('data-name'); let val = this.cfgvalue(sid, opt); tr.querySelectorAll('.flash').forEach((n) => { - n.classList.remove('flash') + n.classList.remove('flash'); }); - val = Array.isArray(val) ? val.join(' '): val; + val = Array.isArray(val) ? val.join(' ') : val; val = `${val}`; // coerce non-string types to string list.push([ ui.Table.prototype.deriveSortKey((val != null && typeof val.trim === 'function') ? val.trim() : ''), @@ -3679,9 +3681,11 @@ const CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection let ref_sid; let cur_sid; + const tbodyEl = (tableEl.tBodies && tableEl.tBodies[0]) ? tableEl.tBodies[0] : tableEl; + for (let i = 0; i < list.length; i++) { list[i][1].childNodes[index].classList.add('flash'); - th.parentNode.parentNode.appendChild(list[i][1]); + tbodyEl.appendChild(list[i][1]); cur_sid = list[i][1].getAttribute('data-sid'); diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index 7802fe0765..706cc7f13b 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -3901,8 +3901,10 @@ const UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ { this.data = data; this.placeholder = placeholder; + const tbodyEl = (this.node.tBodies && this.node.tBodies[0]) ? this.node.tBodies[0] : this.node; + let n = 0; - const rows = this.node.querySelectorAll('tr, .tr'); + const rows = tbodyEl.querySelectorAll('tr, .tr'); const trows = []; const captionClasses = this.options.captionClasses; const trTag = (rows[0] && rows[0].nodeName == 'DIV') ? 'div' : 'tr'; @@ -3933,16 +3935,16 @@ const UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ { for (let i = 0; i < n; i++) { if (rows[i+1]) - this.node.replaceChild(trows[i], rows[i+1]); + tbodyEl.replaceChild(trows[i], rows[i+1]); else - this.node.appendChild(trows[i]); + tbodyEl.appendChild(trows[i]); } while (rows[++n]) - this.node.removeChild(rows[n]); + tbodyEl.removeChild(rows[n]); - if (placeholder && this.node.firstElementChild === this.node.lastElementChild) { - const trow = this.node.appendChild(E(trTag, { 'class': 'tr placeholder' })); + if (placeholder && tbodyEl.firstElementChild === tbodyEl.lastElementChild) { + const trow = tbodyEl.appendChild(E(trTag, { 'class': 'tr placeholder' })); const td = trow.appendChild(E(tdTag, { 'class': 'td' }, placeholder)); if (typeof(captionClasses) == 'object') @@ -4123,10 +4125,13 @@ const UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ { * @param {Event} ev */ handleSort(ev) { - if (!ev.target.matches('th[data-sortable-row]')) + let th = (ev && ev.target) ? ev.target : null; + if (th && typeof th.matches === 'function' && !th.matches('th[data-sortable-row]')) + th = (typeof th.closest === 'function') ? th.closest('th[data-sortable-row]') : null; + + if (!th) return; - const th = ev.target; const direction = (th.getAttribute('data-sort-direction') == 'asc'); let index = 0; |