Tab

The Navs: Tabs & Pills lesson covered how tabs and pills look. On their own, though, clicking one does nothing — the Tab plugin is what actually swaps which content pane is visible. We'll finish the TrailMap trail-detail nav from that earlier lesson by making its Overview, Reviews, and Photos tabs functional.

Two Pieces: The Nav and the Panes

A functional tab set needs the nav links you already know, plus a matching .tab-content wrapper holding one .tab-pane per link. Each link's href points at the pane's id, and data-toggle="tab" tells the plugin to treat the click as a pane switch instead of a normal navigation.

<ul class="nav nav-tabs">
  <li class="active"><a href="#overview" data-toggle="tab">Overview</a></li>
  <li><a href="#reviews" data-toggle="tab">Reviews</a></li>
  <li><a href="#photos" data-toggle="tab">Photos</a></li>
</ul>

<div class="tab-content">
  <div class="tab-pane active" id="overview">Ridge Overlook Loop is a 4.2 mile out-and-back trail...</div>
  <div class="tab-pane" id="reviews">"Great sunset views, moderate climb." — 4.5 stars</div>
  <div class="tab-pane" id="photos">[ trail photo gallery ]</div>
</div>
.active placement matters: the .active class has to be on both the opening <li> in the nav and the matching .tab-pane — miss one and you'll either have no tab highlighted, or a pane with no way to select it.

Pills Work Identically

Swap .nav-tabs for .nav-pills and data-toggle="tab" for data-toggle="pill" — the pane-switching behavior is exactly the same either way.

<ul class="nav nav-pills">
  <li class="active"><a href="#overview" data-toggle="pill">Overview</a></li>
  <li><a href="#reviews" data-toggle="pill">Reviews</a></li>
</ul>

Reacting to a Tab Switch: shown.bs.tab

To run code right after a new pane becomes visible — say, lazy-loading the photo gallery only when the Photos tab is actually opened — listen for shown.bs.tab on the nav:

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  var target = $(e.target).attr('href'); // e.g. "#photos"
  if (target === '#photos') {
    // load the trail photo gallery lazily, only now
    loadTrailPhotos();
  }
});
e.target vs e.relatedTarget: inside the shown.bs.tab handler, e.target is the tab that just became active and e.relatedTarget is the one that was active before — handy if you need to clean something up on the tab being left.
Up next: Tooltip & Popover — two plugins that, unlike Tab, need explicit JavaScript initialization on every page that uses them.