Browse Source

Merge pull request #15186 from Piccirello/webui-table-keyboard-nav

Support navigating Web UI tables with arrow keys
adaptive-webui-19844
Chocobo1 4 years ago committed by GitHub
parent
commit
d923c03d52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 77
      src/webui/www/private/scripts/dynamicTable.js
  2. 18
      src/webui/www/private/scripts/prop-files.js

77
src/webui/www/private/scripts/dynamicTable.js

@ -617,7 +617,8 @@ window.qBittorrent.DynamicTable = (function() {
onSelectedRowChanged: function() {}, onSelectedRowChanged: function() {},
updateRowData: function(data) { updateRowData: function(data) {
const rowId = data['rowId']; // ensure rowId is a string
const rowId = `${data['rowId']}`;
let row; let row;
if (!this.rows.has(rowId)) { if (!this.rows.has(rowId)) {
@ -696,8 +697,13 @@ window.qBittorrent.DynamicTable = (function() {
this.updateRow(trs[rowPos], fullUpdate); this.updateRow(trs[rowPos], fullUpdate);
else { // else create a new row in the table else { // else create a new row in the table
const tr = new Element('tr'); const tr = new Element('tr');
// set tabindex so element receives keydown events
// more info: https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event
tr.setProperty("tabindex", "-1");
tr['rowId'] = rows[rowPos]['rowId']; const rowId = rows[rowPos]['rowId'];
tr.setProperty("data-row-id", rowId);
tr['rowId'] = rowId;
tr._this = this; tr._this = this;
tr.addEvent('contextmenu', function(e) { tr.addEvent('contextmenu', function(e) {
@ -734,6 +740,16 @@ window.qBittorrent.DynamicTable = (function() {
} }
return false; return false;
}); });
tr.addEvent('keydown', function(event) {
switch (event.key) {
case "up":
this._this.selectPreviousRow();
return false;
case "down":
this._this.selectNextRow();
return false;
}
});
this.setupTr(tr); this.setupTr(tr);
@ -812,6 +828,50 @@ window.qBittorrent.DynamicTable = (function() {
getRowIds: function() { getRowIds: function() {
return this.rows.getKeys(); return this.rows.getKeys();
}, },
selectNextRow: function() {
const visibleRows = $(this.dynamicTableDivId).getElements("tbody tr").filter(e => e.getStyle("display") !== "none");
const selectedRowId = this.getSelectedRowId();
let selectedIndex = -1;
for (let i = 0; i < visibleRows.length; ++i) {
const row = visibleRows[i];
if (row.getProperty("data-row-id") === selectedRowId) {
selectedIndex = i;
break;
}
}
const isLastRowSelected = (selectedIndex >= (visibleRows.length - 1));
if (!isLastRowSelected) {
this.deselectAll();
const newRow = visibleRows[selectedIndex + 1];
this.selectRow(newRow.getProperty("data-row-id"));
}
},
selectPreviousRow: function() {
const visibleRows = $(this.dynamicTableDivId).getElements("tbody tr").filter(e => e.getStyle("display") !== "none");
const selectedRowId = this.getSelectedRowId();
let selectedIndex = -1;
for (let i = 0; i < visibleRows.length; ++i) {
const row = visibleRows[i];
if (row.getProperty("data-row-id") === selectedRowId) {
selectedIndex = i;
break;
}
}
const isFirstRowSelected = selectedIndex <= 0;
if (!isFirstRowSelected) {
this.deselectAll();
const newRow = visibleRows[selectedIndex - 1];
this.selectRow(newRow.getProperty("data-row-id"));
}
},
}); });
const TorrentsTable = new Class({ const TorrentsTable = new Class({
@ -2006,6 +2066,19 @@ window.qBittorrent.DynamicTable = (function() {
row.full_data.remaining = 0; row.full_data.remaining = 0;
else else
row.full_data.remaining = (row.full_data.size * (1.0 - (row.full_data.progress / 100))); row.full_data.remaining = (row.full_data.size * (1.0 - (row.full_data.progress / 100)));
},
setupTr: function(tr) {
tr.addEvent('keydown', function(event) {
switch (event.key) {
case "left":
qBittorrent.PropFiles.collapseFolder(this._this.getSelectedRowId());
return false;
case "right":
qBittorrent.PropFiles.expandFolder(this._this.getSelectedRowId());
return false;
}
});
} }
}); });

18
src/webui/www/private/scripts/prop-files.js

@ -43,7 +43,9 @@ window.qBittorrent.PropFiles = (function() {
createPriorityCombo: createPriorityCombo, createPriorityCombo: createPriorityCombo,
updatePriorityCombo: updatePriorityCombo, updatePriorityCombo: updatePriorityCombo,
updateData: updateData, updateData: updateData,
collapseIconClicked: collapseIconClicked collapseIconClicked: collapseIconClicked,
expandFolder: expandFolder,
collapseFolder: collapseFolder
}; };
}; };
@ -495,6 +497,20 @@ window.qBittorrent.PropFiles = (function() {
collapseNode(node); collapseNode(node);
}; };
const expandFolder = function(id) {
const node = torrentFilesTable.getNode(id);
if (node.isFolder) {
expandNode(node);
}
};
const collapseFolder = function(id) {
const node = torrentFilesTable.getNode(id);
if (node.isFolder) {
collapseNode(node);
}
};
const filesPriorityMenuClicked = function(priority) { const filesPriorityMenuClicked = function(priority) {
const selectedRows = torrentFilesTable.selectedRowsIds(); const selectedRows = torrentFilesTable.selectedRowsIds();
if (selectedRows.length === 0) return; if (selectedRows.length === 0) return;

Loading…
Cancel
Save