Say we have 2 tabs using data-role="navbar"
, and we switch to the second tab and then go to another new page. When we return back from the previous page, why is the tab that we selected second tab is not the one which is active. It shows the first tab as only active. Is jquery mobile not handling this.

- 97,681
- 90
- 411
- 885

- 593
- 1
- 15
- 32
3 Answers
Description :
Unfortunately jQuery Mobile
don't handle this correctly so we need to do it. Basically you need to remove href
from navbar li
element. Page change will be handled manually. What we are doing here is binding a click event to navbar li
element. When user clicks on navbar it will remove ui-btn-activ and ui-state-persist class from currently selected element. It will the add it to currently selected element and initialize a pageChange
after a small timeout. Timeout is needed because we need to be sure class is added before page change can occur.
Solution :
Here's a working example I made some time ago: http://jsfiddle.net/Gajotres/6h7gn/
Code:
This code is made for my current example and its navbar so change it slightly to work with your navbar.
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#kml li', function(){
var selectedLi = $(this);
$('#kml li').each(function( index ) {
var loopLi = $(this);
if(loopLi.find('a').hasClass('ui-btn-active')) {
$(this).find('a').removeClass('ui-btn-activ').removeClass('ui-state-persist');
}
});
selectedLi.find('a').addClass('ui-state-persist');
setTimeout(function(){
$.mobile.changePage( "#second", { transition: "slide"});
},100);
});
});
Edit :
Next version example: http://jsfiddle.net/Gajotres/6h7gn/
This one works on every page.
$(document).on('pagebeforeshow', '#index', function(){
$(document).off('click', '#custom-navbar li').on('click', '#custom-navbar li', function(e){
var selectedLi = $(this);
$('#custom-navbar li').each(function( index ) {
var loopLi = $(this);
if(loopLi.find('a').hasClass('ui-btn-active') || loopLi.find('a').hasClass('ui-state-persist')) {
loopLi.find('a').removeClass('ui-btn-activ').removeClass('ui-state-persist');
}
if(loopLi.attr('id') == selectedLi.attr('id')) {
loopLi.find('a').addClass('ui-state-persist');
}
});
setTimeout(function(){
$.mobile.changePage( selectedLi.find('a').attr('data-href'), { transition: "slide"});
},100);
});
});

- 57,309
- 16
- 102
- 130
-
Thanks. Perfect answer. But,have a small doubt. Why are we doing this on document object :$(document).on('click', '#kml li', function(){}). Am also using the same syntax. Want to know whether there is any specific reason for binding on document object. Or, it is just a syntax – user694688 May 25 '13 at 21:03
-
I am binding it to document level because usually we will need to use navbar on several pages, so this delegated binding will prevent us from doing this process for every single page. So we will do it only for a first navbar and it will work on every navbar loaded later. – Gajotres May 25 '13 at 21:11
-
So, you mean to say that we dont have to bind for navbar again. But, we are using "#kml li" id, which cannot be used anywhere in the next page because the ids need to be unique. Shouldn't we bind again then. Is my understanding correct? – user694688 May 25 '13 at 21:22
-
Take a look at my new content, this one will work on every available page, if you have several identical navbars. – Gajotres May 25 '13 at 21:53
-
Am doing this while selection of a tab in pageinit. It works fine on desktop browser but does not work on device. When we come back from a page, all the tabs appear as selected on whichever tabs i had clicked before going to that page.What could be the reason: var selectedItem = $(this);$(this).siblings().each(function(index){var loopItem = $(this);if(loopItem.find('a').hasClass('ui-btn-active')) { $(this).find('a').removeClass('ui-btn-active').removeClass('ui-state-persist'); } }); selectedItem.find('a').addClass('ui-btn-active').addClass('ui-state-persist'); – user694688 Jun 01 '13 at 06:46
-
This seems like a lot of extra memory usage. There shouldn't be any reason to use a loop here. Given you just want to remove the `ui-btn-active` class from the navbar, you could just do `$('#custom-navbar li').removeClass('ui-btn-active ui-state-persist')`, or really, since you are unlikely to need other page elements to be active in addition to these, `$('.ui-btn-active,.ui-state-persist').removeClass('ui-btn-active ui-btn-state-persist')`. Also, this may work on every page, but it shouldn't. The ID's are not unique - at the very least, you should bind to `$('[data-id="custom-navbar"]')` – dgo Oct 27 '13 at 20:42
Here is my short solution. It works perfect for me
Sample HTML structure
<div id="profile-screen" data-role="page" class="page">
<div data-role="content" class="content inner-page group">
<div data-role="tabs">
<div data-role="navbar">
<ul>
<li><a href="#tab-profile" class="ui-btn-active">Profile</a></li>
<li><a href="#tab-addresses">Addresses</a></li>
</ul>
</div>
<!-- Profile tab -->
<div id="tab-profile" class="main-content"> Sample Content for the first tab</div>
<!-- Addresses tab -->
<div id="tab-addresses" class="main-content"> Sample Content for the second tab</div>
</div>
</div>
</div>
And this is the solution
$( "#profile-screen" ).on( "pagebeforeshow", function() {
var active_content = $('#profile-screen .ui-tabs-panel[style*="block"]').attr('id');
$('#profile-screen a[href^="#'+ active_content +'"]').addClass('ui-btn-active');
});
First you have to find the active content. The typical for the active content is that it has style="display:block"
. When you you find it, you have to get the id ( it is var active_content
in my code ). When you know which content is active all that you have to do is to find the correct anchor tag and to set class ui-btn-active
. And all these things you have to type in pagebeforeshow
event.

- 13,845
- 13
- 50
- 77
I know this is old but no need for all this.
I had this problem too and all you need is few lines to fix it. In my case it was in a tabs so didn't need to change page.
$(document).on( "pageinit", "#yourpageID", function() {
$('div[data-role="tabs"] [data-role="navbar"] a').click( function(e) {
e.preventDefault();
$('div[data-role="tabs"] [data-role="navbar"] .ui-btn-active').removeClass('ui-btn-active ui-state-persist');
$(this).addClass('ui-btn-active ui-state-persist');
});
});
Also be careful using page events like pagebeforeshow to bind events in JQM, the previous(or more) page may be in the cache and if you go back and forth the click event will be binded multiple times. Instead use pageinit or .one to bind events

- 4,351
- 2
- 22
- 45

- 253
- 1
- 4
- 13
-
Brilliant! I also had issues with the tab not getting selected on page generation so added more to this solution: https://stackoverflow.com/a/64080164/1741690 – SharpC Sep 26 '20 at 18:54