luci-base: ui.js: rework tab state handling
Properly preserve the selection state of nested tabs. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
fb18c278a4
commit
c2eba00a10
1 changed files with 33 additions and 13 deletions
|
@ -1556,9 +1556,6 @@ return L.Class.extend({
|
||||||
document.addEventListener('dependency-update', this.updateTabs.bind(this));
|
document.addEventListener('dependency-update', this.updateTabs.bind(this));
|
||||||
|
|
||||||
this.updateTabs();
|
this.updateTabs();
|
||||||
|
|
||||||
if (!groups.length)
|
|
||||||
this.setActiveTabId(-1, -1);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initTabGroup: function(panes) {
|
initTabGroup: function(panes) {
|
||||||
|
@ -1576,6 +1573,7 @@ return L.Class.extend({
|
||||||
active = pane.getAttribute('data-tab-active') === 'true';
|
active = pane.getAttribute('data-tab-active') === 'true';
|
||||||
|
|
||||||
menu.appendChild(E('li', {
|
menu.appendChild(E('li', {
|
||||||
|
'style': L.dom.isEmpty(pane) ? 'display:none' : null,
|
||||||
'class': active ? 'cbi-tab' : 'cbi-tab-disabled',
|
'class': active ? 'cbi-tab' : 'cbi-tab-disabled',
|
||||||
'data-tab': name
|
'data-tab': name
|
||||||
}, E('a', {
|
}, E('a', {
|
||||||
|
@ -1590,7 +1588,7 @@ return L.Class.extend({
|
||||||
group.parentNode.insertBefore(menu, group);
|
group.parentNode.insertBefore(menu, group);
|
||||||
|
|
||||||
if (selected === null) {
|
if (selected === null) {
|
||||||
selected = this.getActiveTabId(groupId);
|
selected = this.getActiveTabId(panes[0]);
|
||||||
|
|
||||||
if (selected < 0 || selected >= panes.length || L.dom.isEmpty(panes[selected])) {
|
if (selected < 0 || selected >= panes.length || L.dom.isEmpty(panes[selected])) {
|
||||||
for (var i = 0; i < panes.length; i++) {
|
for (var i = 0; i < panes.length; i++) {
|
||||||
|
@ -1605,32 +1603,51 @@ return L.Class.extend({
|
||||||
menu.childNodes[selected].classList.remove('cbi-tab-disabled');
|
menu.childNodes[selected].classList.remove('cbi-tab-disabled');
|
||||||
panes[selected].setAttribute('data-tab-active', 'true');
|
panes[selected].setAttribute('data-tab-active', 'true');
|
||||||
|
|
||||||
this.setActiveTabId(groupId, selected);
|
this.setActiveTabId(panes[selected], selected);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPathForPane: function(pane) {
|
||||||
|
var path = [], node = null;
|
||||||
|
|
||||||
|
for (node = pane ? pane.parentNode : null;
|
||||||
|
node != null && node.hasAttribute != null;
|
||||||
|
node = node.parentNode)
|
||||||
|
{
|
||||||
|
if (node.hasAttribute('data-tab'))
|
||||||
|
path.unshift(node.getAttribute('data-tab'));
|
||||||
|
else if (node.hasAttribute('data-section-id'))
|
||||||
|
path.unshift(node.getAttribute('data-section-id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.join('/');
|
||||||
|
},
|
||||||
|
|
||||||
getActiveTabState: function() {
|
getActiveTabState: function() {
|
||||||
var page = document.body.getAttribute('data-page');
|
var page = document.body.getAttribute('data-page');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var val = JSON.parse(window.sessionStorage.getItem('tab'));
|
var val = JSON.parse(window.sessionStorage.getItem('tab'));
|
||||||
if (val.page === page && Array.isArray(val.groups))
|
if (val.page === page && L.isObject(val.paths))
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
catch(e) {}
|
catch(e) {}
|
||||||
|
|
||||||
window.sessionStorage.removeItem('tab');
|
window.sessionStorage.removeItem('tab');
|
||||||
return { page: page, groups: [] };
|
return { page: page, paths: {} };
|
||||||
},
|
},
|
||||||
|
|
||||||
getActiveTabId: function(groupId) {
|
getActiveTabId: function(pane) {
|
||||||
return +this.getActiveTabState().groups[groupId] || 0;
|
var path = this.getPathForPane(pane);
|
||||||
|
return +this.getActiveTabState().paths[path] || 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
setActiveTabId: function(groupId, tabIndex) {
|
setActiveTabId: function(pane, tabIndex) {
|
||||||
|
var path = this.getPathForPane(pane);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var state = this.getActiveTabState();
|
var state = this.getActiveTabState();
|
||||||
state.groups[groupId] = tabIndex;
|
state.paths[path] = tabIndex;
|
||||||
|
|
||||||
window.sessionStorage.setItem('tab', JSON.stringify(state));
|
window.sessionStorage.setItem('tab', JSON.stringify(state));
|
||||||
}
|
}
|
||||||
|
@ -1642,9 +1659,12 @@ return L.Class.extend({
|
||||||
updateTabs: function(ev, root) {
|
updateTabs: function(ev, root) {
|
||||||
(root || document).querySelectorAll('[data-tab-title]').forEach(function(pane) {
|
(root || document).querySelectorAll('[data-tab-title]').forEach(function(pane) {
|
||||||
var menu = pane.parentNode.previousElementSibling,
|
var menu = pane.parentNode.previousElementSibling,
|
||||||
tab = menu.querySelector('[data-tab="%s"]'.format(pane.getAttribute('data-tab'))),
|
tab = menu ? menu.querySelector('[data-tab="%s"]'.format(pane.getAttribute('data-tab'))) : null,
|
||||||
n_errors = pane.querySelectorAll('.cbi-input-invalid').length;
|
n_errors = pane.querySelectorAll('.cbi-input-invalid').length;
|
||||||
|
|
||||||
|
if (!menu || !tab)
|
||||||
|
return;
|
||||||
|
|
||||||
if (L.dom.isEmpty(pane)) {
|
if (L.dom.isEmpty(pane)) {
|
||||||
tab.style.display = 'none';
|
tab.style.display = 'none';
|
||||||
tab.classList.remove('flash');
|
tab.classList.remove('flash');
|
||||||
|
@ -1690,7 +1710,7 @@ return L.Class.extend({
|
||||||
if (L.dom.matches(pane, '[data-tab]')) {
|
if (L.dom.matches(pane, '[data-tab]')) {
|
||||||
if (pane.getAttribute('data-tab') === name) {
|
if (pane.getAttribute('data-tab') === name) {
|
||||||
pane.setAttribute('data-tab-active', 'true');
|
pane.setAttribute('data-tab-active', 'true');
|
||||||
L.ui.tabs.setActiveTabId(groupId, index);
|
L.ui.tabs.setActiveTabId(pane, index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pane.setAttribute('data-tab-active', 'false');
|
pane.setAttribute('data-tab-active', 'false');
|
||||||
|
|
Loading…
Reference in a new issue