How to make bootstrap multiple tab group that shares same ID - javascript

First of all I understand that there should not be multiple instance of same ID but I am looking for better solution that will help me to complete my requirement. Below is just an example of what I am trying to do:
<div class="tab-group-1">
<ul class="nav nav-tabs" role="tablist">
<li class="active">Home</li>
<li>About</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="abc1">Home tab content</div>
<div class="tab-pane" id="abc2">About tab content</div>
</div>
</div>
<div class="tab-group-2">
<ul class="nav nav-tabs" role="tablist">
<li class="active">Home</li>
<li>About</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="abc1">Home tab content</div>
<div class="tab-pane" id="abc2">About tab content</div>
</div>
</div>

Here is something but you have small changes :
Bootply : http://www.bootply.com/U0LkomjCne
Explain : change a[href] by a[data-target] and prefix the target with the wrapper class.
HTML:
<div class="tab-group-1">
<ul class="nav nav-tabs" role="tablist">
<li class="active"><a data-target=".tab-group-1 #abc1" data-toggle="tab">Home</a></li>
<li><a data-target=".tab-group-1 #abc2" data-toggle="tab">About</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="abc1">Home tab content</div>
<div class="tab-pane" id="abc2">About tab content</div>
</div>
</div>
<div class="tab-group-2">
<ul class="nav nav-tabs" role="tablist">
<li class="active"><a data-target=".tab-group-2 #abc1" data-toggle="tab">Home</a></li>
<li><a data-target=".tab-group-2 #abc2" data-toggle="tab">About</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="abc1">Home tab content</div>
<div class="tab-pane" id="abc2">About tab content</div>
</div>
</div>

Related

Why when tab2 is clicked it appears always the content of the tab1?

I have some tabs using bootstrap 4. In the tab with id "mytabs" I have other two tabs inside it. And in this tabs inside "#mytabs" that is an issue. If I click in the "tab1" link it appears the content of the tab1 but if I click in the "tab2" link it still appears the content of the "tab1".
Do you know where is the issue?
Fiddle with issue: https://jsfiddle.net/cv25swga/8/
HTML:
<body>
<div class="bg-light-gray2">
<div class="container nopadding py-4">
<div class="row mt-3">
<div class="col-12">
<ul class="nav nav-pills bg-light-gray registration_form_list" role="tablist">
<!-- other tab links -->
<li class="disabled">
<a class="nav-link" href="#mytabs" data-toggle="tab" role="tab">
<i class="fa fa-lock" aria-hidden="true"></i>
<span class="d-none d-lg-inline-block">Access Data</span>
</a>
</li>
</ul>
<div class="tab-content registration_body bg-white" id="myTabContent">
<div class="tab-pane clearfix fade" id="mytabs" role="tabpanel"
aria-labelledby="contact-tab">
<div class="d-flex mb-3">
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active border" id="tab1" href="#tab1"
data-toggle="tab"
role="tab">tab1</a>
</li>
<li class="nav-item">
<a class="nav-link border" id="tab2" href="#tab2"
data-toggle="tab" role="tab">tab2</a>
</li>
</ul>
</div>
<div class="tab-content bg-white" id="myTabContent">
<div class="tab-pane fade show active clearfix" id="tab1" role="tabpanel"
aria-labelledby="home-tab">
tab1
</div>
<div class="tab-pane fade show clearfix" id="tab2" role="tabpanel"
aria-labelledby="home-tab">
tab2
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
This is caused by the fact both your tabs and the links have the same ID.
Change your IDs up so that they are unique on the page and the problem will disappear.

Bootstrap tabs without anchors?

I wonder whether it is possible to write Bootstrap tabs without using anchor elements <a>?
The reason I want to know is that I want to add elements inside the tab that are not valid children of <a> - in my case I want to add an <input> (note the <input> is not used to control the tabs, as such).
An archetype tab example may be:
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active">Section 1</li>
<li>Section 2</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<p>I'm in Section 1.</p>
</div>
<div class="tab-pane" id="tab2">
<p>I'm in Section 2.</p>
</div>
</div>
</div>
I know I can make tabs show programmatically using:
$('#tab1').tab('show')
But that appears to depend on the fact that it's an <a>. Could I use a <div>, for example, and hook into the click event with JQuery?
I would need some way to specify the href if I were to do it that way.
You can use any other element. Instead of href attribute, use data-target.
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active"><span data-target="#tab1" data-toggle="tab">Section 1</span ></li>
<li> <span data-target="#tab2" data-toggle="tab">Section 2</span ></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<p>I'm in Section 1.</p>
</div>
<div class="tab-pane" id="tab2">
<p>I'm in Section 2.</p>
</div>
</div>
</div>
No need for custom javascript, but you need to style. Example in jsfiddle.
I think you can do something like this
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTabs" role="tablist">
<li role="presentation" class="active"> <input type="text" name="" id="input" class="form-control" value="" required="required" pattern="" title=""></li>
<li role="presentation">Profile</li>
<li role="presentation">Messages</li>
<li role="presentation">Settings</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">...</div>
<div role="tabpanel" class="tab-pane" id="profile">...</div>
<div role="tabpanel" class="tab-pane" id="messages">...</div>
<div role="tabpanel" class="tab-pane" id="settings">...</div>
</div>
</div>
<div id="clickdiv" style="background-color: red;width: 20px;height: 20px"></div>
<script type="text/javascript">
$("#clickdiv").click(function(){
// $('#myTabs a:first').tab('show') // Select first tab
// $('#myTabs a:last').tab('show') // Select last tab
$('#myTabs li:eq(2) a').tab('show') // Select third tab (0-indexed)
});
</script>
You can use data-target on the inputs..
<input data-target="#..." data-toggle="tab" class="form-control">
Demo: http://www.codeply.com/go/mXUpU5b2x0

Is there a way to use bootstrap tabs without using a unique identifier

I would like to be able to use bootstrap tabs but without using a unique selector.
I cannot guarantee that the selector is the only one in the dom.
I have many sub templates which are either included in the page as it is rendered or can be loaded inside a modal via ajax.
I do use id's but never in the templates i might use within a modal, some modals are preloaded after the page load event.
<div class="panel">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li><a data-target=".pane1" data-toggle="tab" aria-expanded="true">pane 1</a></li>
<li><a data-target=".pane2" data-toggle="tab" aria-expanded="true">pane 2</a></li>
</ul>
</div>
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane pane1">pane 1</div>
<div class="tab-pane pane2">pane 2</div>
</div>
</div>
</div>
I have tried an onclick event on the anchor tag with just jquery which is less than ideal, but cannot get it to work with the .tab('show')
onclick="$(this).closest('.panel')
.find('.tab-pane').hide();$(this).closest('.panel').find('.pane1').show();"
Yes it is possible...for this HTML:
<div class="panel">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li>pane 1</li>
<li>pane 2</li>
</ul>
</div>
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane">pane 1</div>
<div class="tab-pane">pane 2</div>
</div>
</div>
</div>
This Javascript:
$('.panel .nav-tabs').on('click', 'a', function(e){
var tab = $(this).parent(),
tabIndex = tab.index(),
tabPanel = $(this).closest('.panel'),
tabPane = tabPanel.find('.tab-pane').eq(tabIndex);
tabPanel.find('.active').removeClass('active');
tab.addClass('active');
tabPane.addClass('active');
});
See this functioning bootply
Note Take note that I removed all data attributes from the anchors to prevent bootstraps auto wireup to them**
This solution uses role attributes to control functionality rather than class names, all role are valid ARIA values. http://accessibility.athena-ict.com/aria/examples/tabpanel2.shtml. The solution works when nesting "tabpanels".
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation"><a role="tab" data-toggle="tab">1</a></li>
<li role="presentation"><a role="tab" data-toggle="tab">2</a></li>
<li role="presentation"><a role="tab" data-toggle="tab">3</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel">1</div>
<div role="tabpanel">2</div>
<div role="tabpanel">3</div>
</div>
</div>
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation"><a role="tab" data-toggle="tab">1</a></li>
<li role="presentation"><a role="tab" data-toggle="tab">2</a></li>
<li role="presentation"><a role="tab" data-toggle="tab">3</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel">1</div>
<div role="tabpanel">2</div>
<div role="tabpanel">3</div>
</div>
</div>
javascript
I modified bootstrap tabs "show" method to include this code these lines.
var $context = $this.closest('[role="tabpanel"]');
if($context.length && $target.length != 1){
if($target.length > 1){
$target = $context.find('[role="tabpanel"] ').eq($this.parent().index());
} else {
$target = $context.find(selector).length ? $context.find(selector) : $target;
}
}
Full method.
$.fn.tab.Constructor.prototype.show=function(){var t=this.element,e=t.closest("ul:not(.dropdown-menu)"),a=t.data("target");if(a||(a=t.attr("href"),a=a&&a.replace(/.*(?=#[^\s]*$)/,"")),!t.parent("li").hasClass("active")){var r=e.find(".active:last a"),n=$.Event("hide.bs.tab",{relatedTarget:t[0]}),i=$.Event("show.bs.tab",{relatedTarget:r[0]});if(r.trigger(n),t.trigger(i),!i.isDefaultPrevented()&&!n.isDefaultPrevented()){var l=$(a),s=t.closest('[role="tabpanel"]');s.length&&1!=l.length&&(l=l.length>1?s.find('.tab-pane, [role="tabpanel"] ').eq(t.parent().index()):s.find(a).length?s.find(a):l),this.activate(t.closest("li"),e),this.activate(l,l.parent(),function(){r.trigger({type:"hidden.bs.tab",relatedTarget:t[0]}),t.trigger({type:"shown.bs.tab",relatedTarget:r[0]})})}}};

Bootstrap Tabbed Nav with Collapsing Categories

I have been trying to get a tabbed nav system working that allows the user to collapse tabs into category headings. Ideally the categories would automatically close if you select a tab outside of them, and would both look like a selected tab and actually select the first tab in their group when selected.
As of now, I have the nav functioning with the ability to show and hide certain tabs and all of the tabs work, but it is treating the tabs inside of the collapsible group as a different set from those outside it and, as such, does not deselect tabs properly. I was trying to remedy this using javascript, but I haven't figured out a way. Any insights into this would be greatly appreciated.
Link to the code on jsFiddle.
<div class="row">
<div class="span4">
<div class="side-nav-container affix-top">
<ul class="nav nav-tabs nav-stacked">
<li class="active"><a data-toggle="collapse" href="#Tab1">Tab1</a>
</li>
<div id="Tab1" class="collapse in">
<ul class="nav nav-tabs nav-stacked" id="subnav">
<li class="active"><a id="subnavtab" data-toggle="tab" href="#Subtab1">Subtab1</a></li>
<li><a data-toggle="tab" href="#Subtab2">Subtab2</a></li>
<li><a data-toggle="tab" href="#Subtab3">Subtab3</a></li>
</ul>
</div>
<li><a data-toggle="tab" href="#Tab2">Tab2</a></li>
<li><a data-toggle="tab" href="#Tab3">Tab3</a></li>
<li><a data-toggle="tab" href="#Tab4">Tab4</a></li>
</ul>
</div>
</div>
<div class="span8">
<div class="tab-content">
<div class="tab-pane fade active in" id="Subtab1">Content 1a</div>
<div class="tab-pane fade" id="Subtab2">Content 1b</div>
<div class="tab-pane fade" id="Subtab3">Content 1c</div>
<div class="tab-pane fade" id="Tab2">Content 2</div>
<div class="tab-pane fade" id="Tab3">Content 3</div>
<div class="tab-pane fade" id="Tab4">Content 4</div>
</div>
</div>
I managed to get this working but it required some slight changes in the markup plus some custom jQuery code.
Here's the updated fiddle. Note that the CSS was also updated to accommodate for the markup changes.
Here's the resulting code:
HTML
<div class="row">
<div class="span4">
<div class="side-nav-container affix-top">
<ul class="nav nav-tabs nav-stacked">
<li class="active"> <a data-toggle="collapse" href="#Tab1">Tab1</a>
<ul class="subnav nav nav-tabs nav-stacked collapse in" id="Tab1">
<li class="active"><a class="subnavtab" data-toggle="tab" href="#Subtab1">Subtab1</a></li>
<li><a class="subnavtab" data-toggle="tab" href="#Subtab2">Subtab2</a></li>
<li><a class="subnavtab" data-toggle="tab" href="#Subtab3">Subtab3</a></li>
</ul>
</li>
<li><a data-toggle="tab" href="#Tab2">Tab2</a></li>
<li><a data-toggle="tab" href="#Tab3">Tab3</a></li>
<li><a data-toggle="tab" href="#Tab4">Tab4</a></li>
</ul>
</div>
</div>
<div class="span8">
<div class="tab-content">
<div class="tab-pane fade active in" id="Subtab1">Content 1a</div>
<div class="tab-pane fade" id="Subtab2">Content 1b</div>
<div class="tab-pane fade" id="Subtab3">Content 1c</div>
<div class="tab-pane fade" id="Tab2">Content 2</div>
<div class="tab-pane fade" id="Tab3">Content 3</div>
<div class="tab-pane fade" id="Tab4">Content 4</div>
</div>
</div>
</div>
jQuery
$('.nav-tabs [data-toggle="collapse"]').on('click', function () {
//Prevent the subnav from collapsing
if ($($(this).attr('href')).hasClass('in')) return false;
//Make collapse links act like tabs
$(this).parent().addClass('active').siblings('li').removeClass('active');
//Activate first subtab
$($(this).attr('href')).find('[data-toggle="tab"]').first().tab('show');
});
$('.nav-tabs > li > a').on('click', function () {
//Hide any open subnav only if it's not the collapse link
//also deactivate any active subtab
if ($(this).data('toggle') != 'collapse') {
$(this).closest('.nav-tabs').find('.collapse.in').collapse('hide').find('.active').removeClass('active');
}
});

Bootstrap Tabs Not Letting me change ID

Alright, I am building an application that has Bootstrap Tabs. I have all the .js files that Twitter Bootstrap has to offer in my head tag.
When I add tabs like this it works
<ul class="nav nav-tabs" data-tabs="tabs" id="myTab">
<li class="active">Post Update</li>
<li>Post Photos</li>
<li>Post Video</li>
<li>Create a Poll</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">Test 1</div>
<div class="tab-pane" id="tab2">Test 2</div>
<div class="tab-pane" id="tab3">Test 3</div>
<div class="tab-pane" id="tab4">Test 4</div>
</div>
<script>
$(function(){
$('#myTab a:last').tab('show');
});
</script>
But on the other hand, when I change the ID on the tabs in my JavaScript and HTML, it does not work any more...
<ul class="nav nav-tabs" data-tabs="tabs" id="changedID">
<li class="active">Post Update</li>
<li>Post Photos</li>
<li>Post Video</li>
<li>Create a Poll</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">Test 1</div>
<div class="tab-pane" id="tab2">Test 2</div>
<div class="tab-pane" id="tab3">Test 3</div>
<div class="tab-pane" id="tab4">Test 4</div>
</div>
<script>
$(function(){
$('#changedID a:last').tab('show');
});
</script>
Is there any way to fix this issue with bootstrap tabs, because this will get really annoying if I cannot put more than one set of tabs on the same page.
Try adding data-toggle="tab" to your links, and make sure your second set of tabs on the page have different id's
http://jsfiddle.net/JqGt9/1/
<div class="container">
<ul class="nav nav-tabs" id="myTab">
<li class="active">Post Update</li>
<li>Post Photos</li>
<li>Post Video</li>
<li>Create a Poll</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">Test 1</div>
<div class="tab-pane" id="tab2">Test 2</div>
<div class="tab-pane" id="tab3">Test 3</div>
<div class="tab-pane" id="tab4">Test 4</div>
</div>
</div>
<div class="container">
<ul class="nav nav-tabs" id="myTab2">
<li class="active">Post Update</li>
<li>Post Photos</li>
<li>Post Video</li>
<li>Create a Poll</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab5">Test 5</div>
<div class="tab-pane" id="tab6">Test 6</div>
<div class="tab-pane" id="tab7">Test 7</div>
<div class="tab-pane" id="tab8">Test 8</div>
</div>
</div>
Try this format.
<ul class="nav nav-tabs" id="myTab">
<li class="active">Section 1</li>
<li>Section 2</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<p>I'm in Section 1.</p>
</div>
<div class="tab-pane" id="tab2">
<p> I'm in Section 2.</p>
</div>
</div>
----------
$('#myTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');
})

Categories