luci-base: ui.js: sorting fixes for tables initialized from markup
authorJo-Philipp Wich <jo@mein.io>
Thu, 19 Oct 2023 21:42:13 +0000 (23:42 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 19 Oct 2023 21:46:03 +0000 (23:46 +0200)
 - Populate id option from table id attribute
 - Update column head sort indicator in UITable.update()
 - Don't store sort state for tables without id

Ref: https://github.com/openwrt/luci/issues/6640
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/htdocs/luci-static/resources/ui.js

index 1580996ef419f7b5dfed6f2a814c71cfc6b42dab..5502dfed25afc708e4a4239f33fb96b6ff11f8d1 100644 (file)
@@ -3233,6 +3233,17 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ {
                if (!Array.isArray(data))
                        return;
 
+               this.data = data;
+               this.placeholder = placeholder;
+
+               var n = 0,
+                   rows = this.node.querySelectorAll('tr, .tr'),
+                   trows = [],
+                   headings = [].slice.call(this.node.firstElementChild.querySelectorAll('th, .th')),
+                   captionClasses = this.options.captionClasses,
+                   trTag = (rows[0] && rows[0].nodeName == 'DIV') ? 'div' : 'tr',
+                   tdTag = (headings[0] && headings[0].nodeName == 'DIV') ? 'div' : 'td';
+
                if (sorting) {
                        var list = data.map(L.bind(function(row) {
                                return [ this.deriveSortKey(row[sorting[0]], sorting[0]), row ];
@@ -3249,18 +3260,14 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ {
                        list.forEach(function(item) {
                                data.push(item[1]);
                        });
-               }
 
-               this.data = data;
-               this.placeholder = placeholder;
-
-               var n = 0,
-                   rows = this.node.querySelectorAll('tr, .tr'),
-                   trows = [],
-                   headings = [].slice.call(this.node.firstElementChild.querySelectorAll('th, .th')),
-                   captionClasses = this.options.captionClasses,
-                   trTag = (rows[0] && rows[0].nodeName == 'DIV') ? 'div' : 'tr',
-                   tdTag = (headings[0] && headings[0].nodeName == 'DIV') ? 'div' : 'td';
+                       headings.forEach(function(th, i) {
+                               if (i == sorting[0])
+                                       th.setAttribute('data-sort-direction', sorting[1] ? 'desc' : 'asc');
+                               else
+                                       th.removeAttribute('data-sort-direction');
+                       });
+               }
 
                data.forEach(function(row) {
                        trows[n] = E(trTag, { 'class': 'tr' });
@@ -3324,6 +3331,7 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ {
                if (!headrow)
                        return;
 
+               options.id = node.id;
                options.classes = [].slice.call(node.classList).filter(function(c) { return c != 'table' });
                options.sortable = [];
                options.captionClasses = [];
@@ -3422,8 +3430,11 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ {
                if (this.sortState)
                        return this.sortState;
 
+               if (!this.options.id)
+                       return null;
+
                var page = document.body.getAttribute('data-page'),
-                   key = page + '.' + this.id,
+                   key = page + '.' + this.options.id,
                    state = session.getLocalData('tablesort');
 
                if (L.isObject(state) && Array.isArray(state[key]))
@@ -3440,7 +3451,7 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ {
                        return;
 
                var page = document.body.getAttribute('data-page'),
-                   key = page + '.' + this.id,
+                   key = page + '.' + this.options.id,
                    state = session.getLocalData('tablesort');
 
                if (!L.isObject(state))
@@ -3456,19 +3467,15 @@ var UITable = baseclass.extend(/** @lends LuCI.ui.table.prototype */ {
                if (!ev.target.matches('th[data-sortable-row]'))
                        return;
 
-               var th = ev.target,
-                   direction = (th.getAttribute('data-sort-direction') == 'asc'),
-                   index = 0;
+               var index, direction;
 
-               this.node.firstElementChild.querySelectorAll('th').forEach(function(other_th, i) {
-                       if (other_th !== th)
-                               other_th.removeAttribute('data-sort-direction');
-                       else
+               this.node.firstElementChild.querySelectorAll('th, .th').forEach(function(th, i) {
+                       if (th === ev.target) {
                                index = i;
+                               direction = th.getAttribute('data-sort-direction') == 'asc';
+                       }
                });
 
-               th.setAttribute('data-sort-direction', direction ? 'desc' : 'asc');
-
                this.setActiveSortState(index, direction);
                this.update(this.data, this.placeholder);
        }