Bootstrap shown.bs.tab event not working - javascript

I'm using the Flexy template (using bootstrap) and I can't get the shown.bs.tab event on tab to work.
I've managed to make it work on JSFiddle.
Here is the code I use in my template that produce nothing :
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<li class="active"><a id="tab1" href="#chart1" role="tab" data-toggle="tab">Tab 1</a></li>
<li><a id="tab2" href="#chart2" role="tab" data-toggle="tab">Tab 2</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="chart1">Tab 1 Content</div>
<div class="tab-pane" id="chart2">Tabe 2 Content</div>
</div>
</div>
<script>
$(function() {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
alert(e.target.href);
})
});
</script>
What can I miss ? If I copy/paste this code on the Flexy code it doesn't work. What are the steps to understand what is wrong ? Thanks !

Bootstrap tab events are based off the .nav-tabs elements, not the .tab-content elements. So in order to tap into the show event, you need the element with an href that is pointed towards #tab1, not the #tab1 content element itself.
So instead of this:
$('#tab1').on('shown.bs.tab', function (e) {
console.log("tab1");
});
Do this instead:
$('[href=#tab1]').on('shown.bs.tab', function (e) {
console.log("tab1");
});
Or, to capture all of them, just do this:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
console.log(e.target.href);
})
Demo in Stack Snippets
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
console.log(e.target.href);
})
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<li class="active"><a id="tab1" href="#chart1" role="tab" data-toggle="tab">Tab 1</a></li>
<li><a id="tab2" href="#chart2" role="tab" data-toggle="tab">Tab 2</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="chart1">Tab 1 Content</div>
<div class="tab-pane" id="chart2">Tabe 2 Content</div>
</div>
</div>

If the Tab is dynamic in anyway try using
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
alert(e.target.href);
})

In my case, there was a conflict between Jquery and Bootstrap.
I solved the problem with jQuery.noConflict(). See below!
I hope that helps!
// Issue # tabs toggle
jQuery.noConflict();
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
alert(e.target.href);
});

The issue was more a rails-related one.
I ended up by removing one by one every piece of code since the issue was not there in the raw template as #KyleMit says.
Whenever I remove the line //= require bootstrap-sprockets from my application.js file the issue disappears !
The issue was that I was requiring both bootstrap and bootstrap-sprockets. I should have require just one of them but not both.

The issue I faces was that I had 2 sets of tabs on my page. and I had already bound the 1st tab set with
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
console.log(e.target.href);
})
For the 2nd tab set also i had defined the same way.. but I had assigned an id to the ul and bound the click element as:
$('#tabId > li > a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
console.log(e.target.href);
})
The 1st tab was working here but the 2nd wouldn't work. I then figured it out and assigned id's to both uls.. now it works

Try this, it's simple and listen to the only Tab you need :
$('a[href="#idTab"]').on('shown.bs.tab', function (e) {
`console.log('this tab is shown');`//or do something else
}

In my case, the bootstrap event 'shown.bs.tab' failed to fire using the above solutions. So, I decided to enable tabbable tabs via javaScript.
const adjustColumnHeaders = () => {
window.setTimeout(() => {
$($.fn.dataTable.tables(true)).DataTable()
.columns.adjust()
.responsive.recalc();
}, 200);
};
const boostrapTabs = $('a[data-bs-toggle="tab"]');
boostrapTabs.click(function () {
$(this).tab("show");
adjustColumnHeaders();
});
$(document).ready(function () {
const tabLink = $(`a[href=${'"' + window.location.hash + '"'}]`);
if(tabLink.length) tabLink.trigger( "click" );
});
Then in your HTML markup, rename data-toggle="tab" to data-bs-toggle="tab".
I.e:
<li class="nav-item" role="presentation">
<a class="nav-link" data-bs-toggle="tab" href="#tab-employees">
Employees
</a>
</li>

Related

How to stay on selected tab

i know there are a lot themes about that, but i dont know why, noone of them are working
I am using AdminLTE3, i have tabs, i want to stay on selected tab after refresh
my code (not working, but should work):
#extends('adminlte::page')
#section('title', 'Mans Profils')
#section('content_header')
#stop
#section('content')
<div class="container">
<ul class="nav nav-tabs">
<li class="active"><a data-target="#home" data-toggle="tab">Home</a></li>
<li>About</li>
<li>Contacts</li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane active" id="home">Home</div>
<div class="tab-pane" id="about">About</div>
<div class="tab-pane" id="contacts">Contacts</div>
</div>
#stop
#section('css')
#stop
#section('js')
<script>
$(function() {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
localStorage.setItem('lastTab', $(this).attr('href'));
});
var lastTab = localStorage.getItem('lastTab');
if (lastTab) {
$('[href="' + lastTab + '"]').tab('show');
}
});
</script>
#stop
No need to use localsStorage for that sake. just put condition over window.location.search
whichever tab has been clicked append window.location.search with that tab variable.
on reload check whether window.location.search string contains your tab variable then call the same code which is inside your tab click.

Jquery not working to hide and show div until Bootstrap tab clicked

I have 2 different divs that need to appear depending on which tab is active.
If tab "#myTab class overview" is active then the "rental div" should show. If "#myTab class overview" is not active them the "homeo div" should show.
My function does not work on page load, on page load both divs appear. If i click either tab then only does my function work.
Do you know how to get my function to be working on page load.
jQuery(document).ready(function () {
jQuery('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if ($("#myTab")[0].className=='overview active')
jQuery('#rental').show(), jQuery('#homeo').hide();
else
jQuery('#rental').hide(), jQuery('#homeo').show();
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rental">
DOWNLOAD APPLICATION
</div>
<div id="homeo">
Test
</div>
<ul class="nav nav-pills">
<li id="myTab" class="overview active"><a data-toggle="tab" href="#home">RENTAL</a></li>
<li><a data-toggle="tab" href="#homeowner">HOMEOWNER</a></li>
</ul>
Why not use CSS or style attribute to hide the element on pageload. Suppose you want to only show rental at page load
<div id="homeo" style="display:none;">
Test
</div>
Or with CSS
#homeo {
display: none;
}
.className is native javascript. jQuery objects don't have this property.
You want to use $("#myTab")[0].hasClass('overview')
jQuery hasClass documentation
You need to call your hide/show code on page load alongwith tab click as
jQuery(document).ready(function () {
if($('#myTab').hasClass('overview active'))
{
jQuery('#rental').show(), jQuery('#homeo').hide();
}else
{
jQuery('#rental').hide(), jQuery('#homeo').show();
}
jQuery('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if ($("#myTab")[0].className=='overview active')
jQuery('#rental').show(), jQuery('#homeo').hide();
else
jQuery('#rental').hide(), jQuery('#homeo').show();
});
})
Here is with demo
https://jsfiddle.net/jalayoza/cnsLfbza/
jQuery(document).ready(function () {
if($('#myTab').hasClass('overview active'))
{
jQuery('#rental').show(), jQuery('#homeo').hide();
}else
{
jQuery('#rental').hide(), jQuery('#homeo').show();
}
jQuery('a[data-toggle="tab"]').on('click', function (e) {
if ($("#myTab")[0].className=='overview active')
jQuery('#rental').show(), jQuery('#homeo').hide();
else
jQuery('#rental').hide(), jQuery('#homeo').show();
});
})
<div id="rental">
DOWNLOAD APPLICATION
</div>
<div id="homeo">
Test
</div>
<ul class="nav nav-pills">
<li id="myTab" class="overview active"><a data-toggle="tab" href="#home">RENTAL</a></li>
<li><a data-toggle="tab" href="#homeowner">HOMEOWNER</a></li>
</ul>

Turbolinks and Bootstrap Tab activation

I am basically facing the same problem as described here, under the additional context of Rails' Turbolinks.
I am using this piece of code
$(document).on('ready page:change', function() {
/* Show tab from anchor */
var hash = window.location.hash;
hash && $('ul.nav a[href="' + hash + '"]').tab('show');
/* Update URL anchor after selecting tab */
$('.nav-tabs a').click(function (e) {
$(this).tab('show');
var scrollmem = $('body').scrollTop();
window.location.hash = this.hash;
$('html,body').scrollTop(scrollmem);
});
Which does work for manual page reload (F5) and for cache restore, but not after reloading the page from a Turbolinks click*.
*When clicking a turbolinks link, if there is some cache of the page, then that cache is first restored and the good tab is shown, but then thre is still a request to the server to get the last contents, and once that request arrives and is parsed, the tab "switches back" to the original one
My bootstrap code looks like this
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#student" role="tab"></a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#mentor" role="tab"><%= </a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#company" role="tab"></a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<br />
<div class="tab-pane fade in active" id="student" role="tabpanel">
...
</div>
<div class="tab-pane fade" id="mentor" role="tabpanel">
...
</div>
<div class="tab-pane fade" id="company" role="tabpanel">
...
</div>
</div>
Rails 5 comes with Turbolinks 5. The solution was just to change the name of the event listener
$(document).on('ready turbolinks:load', function() {

Bootstrap nav-tabs check for selected tab using jquery

I have the following Bootstrap nav tabs:
<div class="row spiff_tabs_body">
<!-- Nav tabs -->
<ul class="nav nav-tabs spiff_tabs" role="tablist">
<li role="presentation" class="active">
Potential Spiff
</li>
<li role="presentation">
Instant Spiff
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="delayedspiff"></div>
<div role="tabpanel" class="tab-pane" id="instantspiff"></div>
</div>
</div>
</div>
</div>
I need to be able to check which tab is selected and then display an alert. I have the following javascript in my view:
<script>
$(function () {
FormGet('dashboard/delayedspiff', 'delayedspiff');
});
</script>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// here is the new selected tab id
var selectedTabId = e.target.id;
var id = $('.tab-content .active').attr('id');
if (id == "delayedspiff") {
alert("delayedspiff");
} else {
alert("instantspiff");
}
});
</script>
When I click the tabs it works, but the alert always displays delayedspiff. I need to dislay instantspiff when they click on the instantspiff tab. Can anyone see what I'm doing wrong?
You just need to remove class active from all tabs and add it to the tab which was clicked.
EDIT: In order to get the id of clicked tab, try using an attribute data-id on the tab selections.
<li role="presentation" class="active">
Potential Spiff
</li>
<li role="presentation">
Instant Spiff
</li>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var wrongid = $('.tab-content .active').attr('id');
$('a[data-toggle="tab"]').removeClass("active"); // remove class active from all tabs
$(this).addClass("active"); // add class active to the current tab
var correctid = $(this).data("id"); // get the attribute data-id of the clicked tab
alert($('.tab-content .active')[0].outerHTML); // shows why you are getting the incorrect id
if (correctid == "delayedspiff")
alert("delayedspiff");
else
alert("instantspiff");
});
</script>
Updated fiddle : https://jsfiddle.net/DTcHh/14313/

Bootstrap - Dynamically added nested tabs

I just started learning front-end development & really need help with a practice project.
I am trying to create 2-layers nested tabs where the user can add tabs on the outer layer. Each outer tab will have inner tabs where the user can also add more inner tabs. Each tab will have the same content for now, so I'm using an iframe to accomplish this - if you have better suggestion, then I would very much like to hear it.
The issue I'm having right now is that I don't know how to bind the inner tabs to the outer tabs. Each of the outer tabs should have different number of tabs depending on how many inner tabs the user creates. I cannot seem to accomplish this & all of my outer tabs currently have the same inner tabs.
Any help/input would be very much appreciated! Thanks.
Here's my code snippet:
<div class="container">
<!-- top level tabs -->
<ul class="nav nav-tabs" id="topNav">
<li class="active">Home<span>x</span></li>
<li>+ Add Tab</li>
</ul>
<div class="tabbable">
<!--bottomNav -->
<ul class="nav nav-tabs" id="bottomNav">
<li class="active">Test<span>x</span></li>
<li>+ Add Tab</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="bottom1"><br><iframe src="form.html" width="100%" height="60%" allowtransparency="true" frameBorder="0"></iframe></div>
</div>
</div>
</div>
My script:
$(document).ready(function() {
$(".nav-tabs").on("click", "a", function(e){
e.preventDefault();
$(this).tab('show');
})
.on("click", "span", function () {
var anchor = $(this).siblings('a');
$(anchor.attr('href')).remove();
$(this).parent().remove();
$(".nav-tabs li").children('a').first().click();
});
/* Adding New Tabs */
$('.addTop').click(function(e) {
e.preventDefault();
var id = $("#topNav").children().length;
$(this).closest('li').before('<li>#'+ id + '<span>x</span></li>');
// $('.tab-content').append('<div class="tab-pane" id="top'+id+'">'+ '<br><iframe src="form.html" width="100%" height="60%" allowtransparency="true" frameBorder="0">' + '</iframe>' + '</div>');
});
$('.addBottom').click(function(e) {
e.preventDefault();
var id = $("#bottomNav").children().length;
$(this).closest('li').before('<li>#'+ id + '<span>x</span></li>');
$('.tab-content').append('<div class="tab-pane" id="bottom'+id+'">'+ '<br><iframe src="form.html" width="100%" height="60%" allowtransparency="true" frameBorder="0">' + '</iframe>' + '</div>');
});
});
There are ready made sollutions out there, but let us leave it for others to suggest.
In reply to your issue: Your addTop.onclick event only adds a new tab, but does not create new content.tabbable for the said tab.
When you ad a new tab you have to do 3 things:
create a new tab.
create a new content for the new tab.
associate event.
Obviously you missed number 2 & 3.
Example:
$('.addTop').click(function(e){
e.preventDefault();
// create new tab
var newTab = $('<li>New Tab</li>');
$('#topNav').append(newTab);
// create new content for the new tab
var newTabContent = $('<div class="tabbable"></div>').hide();
$('.container').append(newTabContent);
// associate tab to content
newTab.click(function(){
newTabContent.show();
// hide others
$('.container > .tabbable').hide();
});
});
Hope this could help. This is the solution without using iframe
You can see the effect in jsfiddle link below:
http://jsfiddle.net/Lzfsgeq9/
Basically some points you need to be aware of are:
1.Use ahref to direct you subtab from parent tab
2.Use "on" event listener to deal with newly created element about event delegation issue
<div class="tabbable boxed parentTabs">
<ul id="topNav" class="nav nav-tabs">
<li class="active">Tab 1
</li>
<li>Tab 2
</li>
<li>+ Add Tab</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade active in" id="top1">
<div class="tabbable">
<ul id="bottomNav1" class="nav nav-tabs" data-parent="1">
<li class="active">Tab 11
</li>
<li>Tab 12
</li>
<li>+ Add Tab</li>
</ul>
</div>
</div>
<div class="tab-pane fade" id="top2">
<div class="tabbable">
<ul id="bottomNav2" class="nav nav-tabs" data-parent="2">
<li class="active">Tab 21
</li>
<li>Tab 22
</li>
<li>+ Add Tab</li>
</ul>
</div>
</div>
</div>
$("ul.nav-tabs").on("click","a",function (e) {
e.preventDefault();
$(this).tab('show');
});
$('.addTop').click(function(e) {
e.preventDefault();
var id = $("#topNav").children().length;
$(this).closest('li').before('<li><a href="#top'+id+'">Tab'+ id + '</li>');
createNewSubTab(id);
});
$('div.tab-content').on("click",".addBottom",function(e) {
e.preventDefault();
var parentId = $(this).closest('ul').data("parent");
var id = $("#bottomNav" + parentId).children().length;
$(this).closest('li').before('<li><a href="#bottom'+parentId+id+'">Tab'+ parentId + id + '</li>');
});
var createNewSubTab = function(id){
var bottomTabPane = $("<div></div>").attr({
id: "top" + id,
"class": "tab-pane fade"
});
var tabContainer = $("<div></div>").attr({
"class":"tabbable"
});
var bottomPanel = $("<ul></ul>").attr({
id:"bottomNav"+id,
"class":"nav nav-tabs",
"data-parent": id
});
var bottomAdd = $("<li></li>").append("<a href='#' class='addBottom' data-toggle='tab'>+ Add Tab</a>");
bottomTabPane.append(tabContainer);
tabContainer.append(bottomPanel);
bottomPanel.append(bottomAdd);
$(".tab-content").append(bottomTabPane);
}

Categories

Resources