Reputation: 2295
I am using Twitter bootstrap nav tabs and nav pills. This is my html code:
<div class="Header2" style="background-color:#1E3848">
<div id="headerTab">
<ul class="nav nav-tabs">
<li class="active ans-tab"> <a href="http://myweb.com/">Home</a></li>
<li class="topTab"><a href="http://myweb.com/score/">Score</a></li>
<li class="topTab"><a href="http://myweb.com/leaderboards/">Leaderboards</a></li>
</ul>
</div>
<div id="subHeaderTabPlayer">
<ul class="nav nav-pills">
<li class="active"> <a href="http://myweb.com/">Top</a></li>
<li><a href="http://myweb.com/rules/" data-toggle="pill">Rules</a></li>
<li><a href="http://myweb.com/player/" data-toggle="pill">Player</a></li>
<li><a href="http://myweb.com/categories/" data-toggle="pill">Categories</a></li>
</ul>
</div>
</div>
Now if I add attribute data-toggle="pill"
and data-toggle="tab"
the tab with active class change to one which I have clicked. However, href
is no longer working.
If I do not use these classes, href
works but active class does not change and it always stays to the element that class was given at the load of page.
I even tried using jQuery to toggle class behavior and it does not work as well. My script code is:
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(window).load(function(){
document.getElementById( 'subHeaderTabPlayer' ).style.display = 'none';
$('ul.nav-tabs li a').click(function (e) {
var activeTab= document.getElementByClass('active');
activeTab.removeAttribute("class");
$('ul.nav-tabs li.active').removeClass('active')
$(this).parent('li').addClass('active')
})
$('ul.nav-pills li a').click(function (e) {
$('ul.nav-pills li.active').removeClass('active');
$(this).parent('li').addClass('active');
})
$(".ans-tab").click(function() {
document.getElementById('subHeaderTabPlayer').style.visibility = 'visible';
document.getElementById('subHeaderTabPlayer' ).style.display = 'block';
});
$(".topTab").click(function() {
document.getElementById('subHeaderTabPlayer').style.visibility = 'collapse';
document.getElementById('subHeaderTabPlayer' ).style.display = 'none';
});
});
</script>
Upvotes: 23
Views: 74089
Reputation: 63
I followed @syeh solution and got it right. Below is a snippet of my code.
<ul class="nav nav-pills">
<li <?php if (strchr($this->pageTitle,' Job') === ' Job') echo 'class=active';?>><?php echo CHtml::link('JOBS', array('Job/index'));?></li>
<li <?php if (strchr($this->pageTitle,'Artisan') === 'Artisan') echo 'class=active';?>><?php echo CHtml::link('ARTISANS', array('Artisan/index'));?></li>
<li <?php if (strchr($this->pageTitle,'Task') === 'Task') echo 'class=active';?>><?php echo CHtml::link('TASKS',array('Task/index'));?></li>
</ul>
Upvotes: 0
Reputation: 1056
<?php
function activate($uri) {
if ($_SERVER['REQUEST_URI'] == $uri) {
echo ' class="active" ';
}
}
?>
<nav>
<ul class="nav nav-tabs">
<li role="tab" <?php activate('/wikireport/index.php'); ?> ><a href="index.php" aria-controls="Home">Wiki Report</a></li>
<li role="tab" <?php activate('/wikireport/examples.php'); ?> ><a href="examples.php" aria-controls="Examples">Examples</a></li>
<li role="tab" <?php activate('/wikireport/about.php'); ?> ><a href="about.php" aria-controls="About">About</a></li>
</ul>
</nav>
And then in the "content" file, just require/include your navline.php
<?php
include('navline.php');
?>
Upvotes: -1
Reputation: 126
I was having a similar issue: when clicked, tabs would become active but would not properly remove the active
class from other tabs (i.e. every tab the user clicked on a pageview would have the active
class).
Switching from an <ol>
to a <ul>
made the tabs behave properly.
Upvotes: 0
Reputation:
This example worked for me:
$leftBlock.on("click", "#navFinished", function(){
$('ul.nav-pills li.active').removeClass('active');
$(this).addClass('active');
});
While this example did not work
$leftBlock.on("click", "#navFinished", function(){
$('ul.nav-pills li.active').removeClass('active')
$(this).parent('li').addClass('active')
})
Removing .parent("li") helped.
Upvotes: 1
Reputation: 3504
This is a more generalized client side solution using jQuery. It only assumes that your tabs have the data-toggle attribute and each group of tabs is wrapped in some kind of container element.
$('[data-toggle="tab"],[data-toggle="pill"]').click(function() {
$(this).parent().children('.active[data-toggle="tab"],.active[data-toggle="pill"]').removeClass('active');
$(this).addClass('active');
});
Upvotes: 0
Reputation: 31
Something to consider: If each li element uses a different controller, here's something you could try.
How to get Twitter-Bootstrap navigation to show active link?
Your code could look something like this:
<ul class="nav nav-pills">
<li class="<%= 'active' if params[:controller] == 'home' %>"> <a href="link" data-toggle="pill">Top</a></li>
<li class="<%= 'active' if params[:controller] == 'rules' %>"><a href="link" data-toggle="pill">Rules</a></li>
<li class="<%= 'active' if params[:controller] == 'player' %>"><a href="link" data-toggle="pill">Player</a></li>
<li class="<%= 'active' if params[:controller] == 'categories' %>"><a href="link" data-toggle="pill">Categories</a></li>
</ul>
Upvotes: 3
Reputation: 12974
Bootstrap nav tabs and pills work with a JS plugin. The plugin is loaded on the page and takes care of the highlighting and the remembering of the currently active tab or pill. It disables the href attributes if they link to other pages, simply because when you click on a link to another page, a new page is loaded. The JS is then reloaded for this new page, and it does not know about which tab or pill is currently active. They are designed to work with single page apps or links to anchors on the same page, and they work fine for that purpose.
The jQuery approach fails for the same reason, but might be easier to explain.
$('ul.nav-pills li a').click(function (e) {
$('ul.nav-pills li.active').removeClass('active')
$(this).parent('li').addClass('active')
})
You click on a link, JS goes off and changes the class, only if it has enough time to do so before the next page is loaded, this next page is loaded because the href attribute on the link tells the browser to navigate to a new page. And the new page loads your JS again, it can't possibly remember the variables from the previous page, like which tab or pill is meant to be active.
If you are going to navigate to other pages, you might as well just set the active class on the right tab for the specific page that is being loaded.
If you really need to do this on the client side, you could do something like this, and load it on each page.
$(document).ready(function () {
// Set BaseURL
var baseURL = 'http://myweb.com/'
// Get current URL and replace baseURL
var href = window.location.href.replace(baseURL, '');
// Remove trailing slash
href = href.substr(-1) == '/' ? href.substr(0, href.length - 1) : href;
// Get last part of current URL
var page = href.substr(href.lastIndexOf('/') + 1);
// Add trailing slash if not empty (empty means we're currently at baseURL)
page = page != '' ? page + '/' : page;
// Select link based on href attribute and set it's closest 'li' to 'active'.
// .siblings('.active').removeClass() is only needed if you have a default 'active li'.
$('a[href="' + baseURL + page + '"]', '.nav li').closest('li').addClass('active').siblings('.active').removeClass();
});
It sets the active tab based on the last part of the URL, it's kind of specific to your scenario (and previously my scenario) though. You'd have to adapt it if there were file extensions or query parameters involved. Every page needs to at least have a link to itself on it. And it preferably has the exact same header with the same tabs and pills rendered on it as all the other pages.
Both of these last points again raise the thought in my mind "if you have to have this much control over what exactly is being rendered onto the page, you probably have access to the server side", and if that is the case, you might as well fix it there, as every link does a new request to the server anyway. And your solution wouldn't have to rely on some not so robust JavaScript to work.
So this is what I had going at one stage, you could improve it, or implement a solution where you post some data to the next page and read it with JavaScript there (which would probably be easier and more robust if you had file extensions or query strings to deal with).
Good luck with it! :)
Upvotes: 29