summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-base
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-02-24 16:48:00 +0100
committerJo-Philipp Wich <jo@mein.io>2022-02-24 23:45:18 +0100
commitd8ed1e7b7dc3965355a8aaa34e8e2cb9fd7c5d74 (patch)
treeb26373b8bef75a9eb51c572e445fb6675fff0034 /modules/luci-base
parent06b351722e4d545fb8fb2f578aaf88e3883e68f5 (diff)
luci-base: form.js: add column sorting to TableSections and GridSections
Add ability to reorder TableSection and GridSection rows by clicking on column headers. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules/luci-base')
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/form.js68
1 files changed, 66 insertions, 2 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js
index 23cc0b1cb5..c17f8ff0ca 100644
--- a/modules/luci-base/htdocs/luci-static/resources/form.js
+++ b/modules/luci-base/htdocs/luci-static/resources/form.js
@@ -2615,7 +2615,8 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
if (has_titles) {
var trEl = E('tr', {
'class': 'tr cbi-section-table-titles ' + anon_class,
- 'data-title': (!this.anonymous || this.sectiontitle) ? _('Name') : null
+ 'data-title': (!this.anonymous || this.sectiontitle) ? _('Name') : null,
+ 'click': this.sortable ? ui.createHandlerFn(this, 'handleSort') : null
});
for (var i = 0, opt; i < max_cols && (opt = this.children[i]) != null; i++) {
@@ -2624,7 +2625,8 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
trEl.appendChild(E('th', {
'class': 'th cbi-section-table-cell',
- 'data-widget': opt.__name__
+ 'data-widget': opt.__name__,
+ 'data-sortable-row': this.sortable ? '' : null
}));
if (opt.width != null)
@@ -3034,6 +3036,68 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
.catch(function() {});
},
+ /** @private */
+ handleSort: function(ev) {
+ if (!ev.target.matches('th[data-sortable-row]'))
+ return;
+
+ var th = ev.target,
+ descending = (th.getAttribute('data-sort-direction') == 'desc'),
+ config_name = this.uciconfig || this.map.config,
+ index = 0,
+ list = [];
+
+ ev.currentTarget.querySelectorAll('th').forEach(function(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(function(tr, i) {
+ var sid = tr.getAttribute('data-sid'),
+ opt = tr.childNodes[index].getAttribute('data-name'),
+ val = this.cfgvalue(sid, opt);
+
+ tr.querySelectorAll('.flash').forEach(function(n) {
+ n.classList.remove('flash')
+ });
+
+ list.push([
+ ui.Table.prototype.deriveSortKey((val != null) ? val.trim() : ''),
+ tr
+ ]);
+ }, this));
+
+ list.sort(function(a, b) {
+ if (a[0] < b[0])
+ return descending ? 1 : -1;
+
+ if (a[0] > b[0])
+ return descending ? -1 : 1;
+
+ return 0;
+ });
+
+ window.requestAnimationFrame(L.bind(function() {
+ var ref_sid, cur_sid;
+
+ for (var i = 0; i < list.length; i++) {
+ list[i][1].childNodes[index].classList.add('flash');
+ th.parentNode.parentNode.appendChild(list[i][1]);
+
+ cur_sid = list[i][1].getAttribute('data-sid');
+
+ if (ref_sid)
+ this.map.data.move(config_name, cur_sid, ref_sid, true);
+
+ ref_sid = cur_sid;
+ }
+
+ th.setAttribute('data-sort-direction', descending ? 'asc' : 'desc');
+ }, this));
+ },
+
/**
* Add further options to the per-section instanced modal popup.
*