I have some 'static' HTML on my page:
<div id="DIVISIONS"> <ul class="nav nav-tabs" id="DIVISIONTABS"> @* <li> nodes will be injected here by javascript *@ </ul> <div class="tab-content" id="DIVISIONTABPANES"> @* <div class="tab-pane"> nodes will be injected here by javascript *@ </div> </div>
On page load, I create a tab 'framework', i.e. create the bootstrap tabs and tab content containers.
I trigger the process with:
$(window).bind("load", prepareDivisionTabs);
And "prepareDivisionTabs" does this:
function prepareDivisionTabs() { // Retrieve basic data for creating tabs $.ajax({ url: "@Url.Action("GetDivisionDataJson", "League")", cache: false }).done(function (data) { var $tabs = $('#DIVISIONTABS').empty(); var $panes = $('#DIVISIONTABPANES').empty(); for (var i = 0; i < data.length; i++) { var d = data[i]; $tabs.append("<li><a href=\"#TABPANE" + d.DivisionId + "\" data-toggle=\"tab\">" + NMWhtmlEncode(d.Name) + "</a></li>"); $panes.append("<div id=\"TABPANE" + d.DivisionId + "\" class=\"tab-pane\"></div>") } renderDivisionTabPaneContents(data); }).fail(function (err) { alert("AJAX error in request: " + JSON.stringify(err, null, 2)); }); }
For info, the "renderDivisionTabPaneContents" in the above does this:
function renderDivisionTabPaneContents(data) { for (var i = 0; i < data.length; i++) { var d = data[i]; renderDivisionTabPaneContent(d.DivisionId); } } function renderDivisionTabPaneContent(id) { var $tabPane = $('#TABPANE' + id); $tabPane.addClass("loader") $.ajax({ url: "/League/GetDivisionPartialView?divisionId=" + id, cache: false }).done(function (html) { $tabPane.html(html); }).fail(function (err) { alert("AJAX error in request: " + JSON.stringify(err, null, 2)); }).always(function () { $tabPane.removeClass("loader") }); }
All good so far. My page loads, my tab contents are rendered, and when I click the different tabs, the relevant content is shown.
Now, rather than loading all content at the start, I want to load tab content just-in-time by using the 'shown' event of the tabs. To test this, I've wanted to just make sure I could get a javascript alert when the tab was shown. So, I create the following to trigger the attachment of tab shown events:
$(function () { attachTabShownEvents(); })
which calls:
function attachTabShownEvents() { $(document).on('shown', 'a[data-toggle="tab"]', function (e) { alert('TAB CHANGED'); }) }
I'd therefore expect so see the "TAB CHANGED" alert after the change of tab. But ... I see no alerts.
Could anybody help me out here?
The correct event binding for tab change is shown.bs.tab
.
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) { alert('TAB CHANGED'); })
Update 11-01-2020 --- Bootstrap 4.5
This is still the correct answer however, this is a bit of additional helpful information found all the way at the bottom of the official bootstrap docs page at: https://getbootstrap.com/docs/4.5/components/navs/#tabs
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { e.target // newly activated tab e.relatedTarget // previous active tab })
You can determine which tab has been selected each time the code fires with e.target
.
If you have unique IDs on your elements then you could do something like the following so code only runs when the appropriate tab is clicked.
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { switch (e.target.id){ case "mainTab":{ doMainTabStuff(); break; } case "configTab":{ doConfigTabStuff(); break; } } })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With