AshAndrien
AshAndrien

Reputation: 148

show/hide twitter bootstrap tabs

I'm using bootstrap to display content below tabs, but I want to collapse the tabs when the tab is clicked again. Here is the code I tried to get to work, to no avail:

    <ul id="myTab" class="nav nav-tabs">
        <li class="square"><a class="story" href="#article1" data-toggle="tab"><img src="#"/></a></li>
        <li class="square"><a class="story" href="#article2" data-toggle="tab"><img src="#g"/></a></li>
        <li class="square"><a class="story" href="#article3" data-toggle="tab"><img src="#"/></a></li>
               <div id="article1" class="tab-pane fade"><p>Lorem ipsum...</p></div>
               <div id="article2" class="tab-pane fade"><p>Lorem ipsum dolor sit amet....</p</div>
               <div id="article3" class="tab-pane fade"><p>Lorem ipsum dolor sit amet...</p></div>
    </ul>

<script>
$('#myTab a').click(function (e) {
            if($(this).tab.hasClass('active')){
                    $(this).tab('hide');
                } else {
                        e.preventDefault();
                        $(this).tab('show');
                    }
                })
</script>

I'm not sure if tabs are supposed to work this way...should I try the collapse functionality?

Upvotes: 7

Views: 49951

Answers (6)

GEkk
GEkk

Reputation: 1366

What about to do something like that? show.bs.tab will always fire before click and it will give to click the right status

$(document).on('show.bs.tab', '#myTab a', function(e) {
   if (!$(e.target).hasClass('active')) {
      $(e.target).addClass('monkeyPatch');
   }
});

$(document).on('click', '#myTab a', function(e) {
   var tab = $(this);
   if (tab.hasClass('monkeyPatch')) {
      tab.removeClass('monkeyPatch');
   } else {
      $('.tab-pane').removeClass('active');
      tab.parent('li').removeClass('active');
   }
});

Upvotes: 0

Rickedb
Rickedb

Reputation: 108

Got the same problem and solved by modifying the bootstrap.js.

Find the tab class definition (usually line 1783) on Tab.prototype.show function and modify:

if ($this.parent('li').hasClass('active')) return

to

if ($this.parent('li').hasClass('active')) {
            $this.parent('li').removeClass('active')
            $(selector).removeClass('active')
            return
        }

Then it will work as expected and without creating more "custom scripts" in your project.

EDIT:

This modification affects EVERY tab panel in your project, however, if you want to make this effect only on desired objects you'll need to add some data-hide or something like that, such as:

if ($this.parent('li').hasClass('active')) {
            if ($this.parent('li').attr('data-hide') == "on") {
                $this.parent('li').removeClass('active')
                $(selector).removeClass('active')
            }
            return
        }

then, every parent <li> with data-hide will hide when click.

Upvotes: 1

Eckonator
Eckonator

Reputation: 107

I get a working bootstrap pills navigation which supports open/close toogle with this code:

jQuery(function() {
// Closing active pill when clicking on toggle:
jQuery(document).off('click.bs.tab.data-api');
jQuery(document).on('click.bs.tab.data-api', '[data-toggle="pill"]', function(e) {
    e.preventDefault();
    var activeClass = 'active';
    var tab = jQuery(this).attr('href');
    var tab = tab && tab.replace(/.*(?=#[^\s]*$)/, ''); // strip for ie7
    var tab = jQuery(tab);
    if (!tab.hasClass(activeClass)) {
        jQuery(this).tab('show');
    } else {
        jQuery(this).parent().removeClass(activeClass);
        tab.parent().children().removeClass(activeClass);
    }
});

});

Upvotes: 0

Jeromy French
Jeromy French

Reputation: 12121

Yes, it sounds like you want Bootstrap's collapse widget. That said, this jQuery will hide an already active tab:

$('#myTab a').click(function (e) {
    if($(this).parent('li').hasClass('active')){
        $( $(this).attr('href') ).hide();
    }
});​

The problem is that this prevents a hidden tab from being shown again, so I don't think you'll want to use it. See http://jsfiddle.net/jhfrench/NQ97h/

If you want to be able to bring the tab back, try:

$('#myTab a').click(function (e) {
    if($(this).parent('li').hasClass('active')){
        var target_pane=$(this).attr('href');
        $( target_pane ).toggle( !$( target_pane ).is(":visible") );
    }
});

See http://jsfiddle.net/epT3L/ for this solution.

Upvotes: -4

Chris Bartley
Chris Bartley

Reputation: 417

Here's a tweak of Jeromy's solution that I believe does what you want:

$('#myTab a').click(function (e) {
    var tab = $(this);
    if(tab.parent('li').hasClass('active')){
        window.setTimeout(function(){
            $(".tab-pane").removeClass('active');
            tab.parent('li').removeClass('active');
        },1);
    }
});

http://jsfiddle.net/NQ97h/39/

Upvotes: 20

Sigfried
Sigfried

Reputation: 3090

I've got a version that works (in my case, just for the main tabs, you'll have to modify it to handle the dropdown tabs.) I just threw it into a fork of Jeromy's jsfiddle above: http://jsfiddle.net/HsqQQ/3/

Here's the code:

 $(document).off('click.tab.data-api');
    $(document).on('click.tab.data-api', '[data-toggle="tab"]', function (e) {
        e.preventDefault();
        var tab = $($(this).attr('href'));
        var activate = !tab.hasClass('active');
        $('div.tab-content>div.tab-pane.active').removeClass('active');
        $('ul.nav.nav-tabs>li.active').removeClass('active');
        if (activate) {
            $(this).tab('show')
        }
    });

Upvotes: 1

Related Questions