I have managed to implement navigation to a specific tab, using the ActiveTab property of the Tabs widget and an input parameter filling this property (as described in different forum posts, like this one)
However, I run into an issue when the user subsequently clicks another tab. The input parameters stay the same (set in the URL) and this somehow causes a blank screen.
Is this an issue that others recognize? How can I solve this issue?
Hi Remco,
Are you trying to implement this for Reactive Web/Mobile or Traditional Web?
I took the liberty of adding a Demo OML for Reactive Web.
Hope it helps.
Regards,
Nordin
Nordin Ahdi wrote:
Hi Nordin,
Thanks for your help. I have adjusted your OML since I see the issue is caused by a slightly more complicated situation. I have subtabs within the tabs. On changing these, the real issue occurs.
I think your OML upload got stuck somehow. It keeps showing me this.
Could you try uploading it again?
This is strange indeed. Somehow at the same time when you click one of the SubTabs and the whole thing would just disappear, these errors pop up in the browser. I have tried a few ways of implementing this, but it results in these same errors.
Changing the SubTab parameter in the URL does change the SubTabs accordingly.
I'll do some more tests later today. In the meantime if someone has an idea how to solve this, feel free to post a solution.
Hello,
Nested Tabs is not possible in Reactive Application it wont work as excepted and this is known issue.
OS Team is working on it
Thanks and Regards,
Gandeev Boddeti wrote:
Thanks a lot for this clarification, although I'm of course far from happy with the conclusion... I see that the same issue even occurs when I mimic tab behaviour with a 'tab-select' screen action and custom containers.
Is there any idea when this is fixed?
Yes, I have the same issue. Very frustrating that nesting doesn't work properly.
-JT
Hi Guys,
I opened up a SR with OutSystems, but they're taking forever.
I cloned OutSystemsUI, and modified Tabs->OnReady->Init.js to address a few issues with the nexted tabs. As long as you don't have any empty Tab headers laying in your layout, this should work. Well, it works for me anyways.
Compare the JS below with the first few lines of your init.js, and patch accordingly. (No warrantly implied by below code. Use at own risk. Your mileage may vary. Please contact manufacturer for details.)
----------------------------init.js------------------------------
window.addEventListener('orientationchange', $actions.OnOrientationChange);var tab = document.getElementById($parameters.Id);var list = tab.querySelector('.list');var init = function() { var headerTabs = tab.querySelector(".tabs-header"); var contentTabs = tab.querySelector(".tabs-content"); var tabsHeaderItems = headerTabs.querySelectorAll(".tabs-header-tab"); var tabsContentItems = contentTabs.querySelectorAll(".tabs-content-tab"); var tabNumber; for(var i = 0; i < tabsHeaderItems.length; i++) { tabNumber = i; tabsHeaderItems[i].setAttribute('data-tab', tabNumber); if(tabsContentItems[i] !== undefined) { tabsContentItems[i].setAttribute('data-tab', tabNumber); tabsContentItems[i].setAttribute('aria-labelledby', tabsHeaderItems[i].getAttribute('id')); } tabsHeaderItems[i].addEventListener('click', function(e) { if(e.currentTarget.offsetParent==headerTabs) { $actions.TabsOnClick(parseFloat(e.currentTarget.dataset.tab),e.currentTarget.offsetParent.id); } }); }
Actually, use this:
//Tabs->OnReady->init.js
window.addEventListener('orientationchange', $actions.OnOrientationChange);var tab = document.getElementById($parameters.Id);var list = tab.querySelector('.list');var init = function() { var headerTabs = tab.querySelector(".tabs-header"); var contentTabs = tab.querySelector(".tabs-content"); var tabsHeaderItems = headerTabs.querySelectorAll(".tabs-header-tab"); var tabsContentItems = contentTabs.querySelectorAll(".tabs-content-tab:not([data-tab])"); var tabNumber; for(var i = 0; i < tabsHeaderItems.length; i++) { tabNumber = i; tabsHeaderItems[i].setAttribute('data-tab', tabNumber); if(tabsContentItems[i] !== undefined) { tabsContentItems[i].setAttribute('data-tab', tabNumber); tabsContentItems[i].setAttribute('data-tab-group', tab.id); tabsContentItems[i].setAttribute('aria-labelledby', tabsHeaderItems[i].getAttribute('id')); } tabsHeaderItems[i].addEventListener('click', function(e) { if(e.currentTarget.offsetParent==headerTabs) { $actions.TabsOnClick(parseFloat(e.currentTarget.dataset.tab),e.currentTarget.offsetParent.id); } }); }
-------snip-------
//Tabs->ChangeTab->changeTab.js
var tab = document.getElementById($parameters.id);var headerTabs = tab.querySelector(".tabs-header");var contentTabs = tab.querySelector(".tabs-content");var newTabHeader = headerTabs.querySelector("[data-tab = '" + $parameters.ActiveTab + "']");var newTabContent = contentTabs.querySelector("[data-tab-group = '" + tab.id + "'][data-tab = '" + $parameters.ActiveTab + "']"); newTabHeader.classList.add('active'); newTabHeader.setAttribute("tabindex", "0"); newTabHeader.setAttribute("aria-selected", "true"); newTabContent.classList.add('open'); newTabContent.setAttribute("tabindex", "0");
//Tabs->RemoveActive->RemoveActive.js
var tab = document.getElementById($parameters.Id);var headerTabs = tab.querySelector(".tabs-header");var contentTabs = tab.querySelector(".tabs-content");var tabHeader = headerTabs.querySelector("[data-tab = '" + $parameters.activeTab + "']");var tabContent = contentTabs.querySelector("[data-tab = '" + $parameters.activeTab + "'][data-tab-group = '" + tab.id +"']");if(tabHeader) { tabHeader.classList.remove('active'); tabHeader.setAttribute("tabindex", "-1"); tabHeader.setAttribute("aria-selected", "false");}if(tabContent){ tabContent.classList.remove('open'); tabContent.setAttribute("tabindex", "-1");}
-------snip--------
Hi everyone,
I had the same problem and after 2 days trying to undestand the easy way to fix, I finally did.
I did it on the version OutSystemsUIWeb Version 1.8.7.
As I am only employee, and I dont have a role to change directly there source of OutSystemsUIWeb/Tab Object, I overwrite the script of the Tab into my page (where I also have many Tab inside other).
Acctually I put into each item Header a variable called "indice" as a sequential number, and I reset it when I found a new Tab inside.
Each Tab main has their headers with a sequential number. 0,1,2,3... And each click I get this attribute and return.
follow and replace the original javascript from Tab 1.8.7.
To get the original, go to Tab into OutsystemUIWeb Tab webblock locate javascript, and there are the code.
locate:
var start = function(widgetIdParam, onChangeId) {
// Sets main objects
widgetId = widgetIdParam;
tabs = document.querySelector('#' + widgetId + ' .tabs');
tabsHeaderItems = tabs.querySelectorAll('.tabs-header-item');
// Accessibility tabindex change values to all tabsHeaderItems
tabsHeaderItems = [].slice.call(tabsHeaderItems);
tabsHeaderItems.forEach(function(item) {
item.setAttribute('tabindex', "-1");
});
Replace to:
cont=0;
paiTab='';
if(paiTab!=item.parentElement.id){ //each node main tab, reset cont
cont=0
}
item.setAttribute('indice',cont++); // putting number of index direct into tab header. Onclick return this indice
paiTab=item.parentElement.id
Locate:
var onTabsKeypress = function(e) {
....
...
// get index from the active Tab
getCurrentIndex();
Remove the code;
var onTabsClick = function(e) {
var target = e.target;
setTimeout(function(){
TriggerEvents(changeId, currentTabIndex);
}, 0);
getCurrentIndex(clickedTabHeader);
var getCurrentIndex = function() {
for(var i = 0; i < tabsContentItems.length; i++) {
if(tabsContentItems[i].classList.contains('active')) {
currentTabIndex = i;
var getCurrentIndex = function(ItemHeader) {
currentTabIndex = parseInt(ItemHeader.getAttribute('indice'));
/*Old code
}*/
Only to continue the post before.
following the oml.