简体   繁体   中英

Invoke Bootstrap Accordion via JavaScript

I want to use the accordion on my site, however I'd prefer to use it over javascript plugin rather than html markup. I would like to have two buttons which open different content, however make only one visible at a time. After reading the documentation I figured that if they have the same parent selector it would work. Could anyone take a look at this fiddle and tell me where do I go from here?

http://jsfiddle.net/krasnoludojad/q7962oxp/

HTML

<div class="container-fluid" id="accordion">
    <div class="navbar-header">
        <button type="button" class="btn btn-default" id="btn-collapse-menu">MENU</button>
        <button type="button" class="btn btn-default" id="btn-collapse-login">LOGIN</button>
    </div>
    <div class="collapse navbar-collapse" id="navbar-collapse-menu">
        <nav>
            <ul class="list-unstyled text-center">
                <li><h3 href="#">BLOG</h3></li>                
            </ul>
        </nav>
    </div>
    <div class="collapse navbar-collapse" id="navbar-collapse-login">
        <p>Lorem ipsum.</p>
    </div>
</div>

JS

$('#btn-collapse-menu').on('click', function(){     
    $('#navbar-collapse-menu').collapse('toggle', {
        parent: "#accordion"
    });             
});
$('#btn-collapse-login').on('click', function(){        
    $('#navbar-collapse-login').collapse('toggle', {
        parent: "#accordion"
    });             
});

UPDATE

Well I've come up with a temporary solution, which I'm not that happy about so I would still appreciate the answer to mechanics behind working this out with parent option. For now I've patched with javascript by checking if the class .in exists that comes when the field is being shown

$('#btn-collapse-menu').on('click', function(){     
    $('#navbar-collapse-login').hasClass('in') ? $('#navbar-collapse-login').collapse('hide') : null;
    $('#navbar-collapse-menu').collapse('toggle');
});
$('#btn-collapse-login').on('click', function(){
    $('#navbar-collapse-menu').hasClass('in') ? $('#navbar-collapse-menu').collapse('hide') : null;
    $('#navbar-collapse-login').collapse('toggle');             
});

One of the problems is that there isn't really a method that allows you to toggle and specify the options for collapse all at the same time, so this doesn't exist:

$('#navbar-collapse-menu').collapse('toggle', {
    parent: "#accordion"
});   

Bootstrap controls really have two distinct phases (that are sometimes combined):

  1. Initialization
  2. Invocation.

The options are set during initialization, so your code would have to look like this:

$('#navbar-collapse-menu').collapse({
    parent: "#accordion"
});  
$('#navbar-collapse-menu').collapse('toggle');  

However, there are other problems like the parent is "dependent on the panel class".

If you just want a cleaner way of manually handling the toggles in javascript, you could do the following.

The problem with removing data-attributes on the elements is that they really provide a clean way of deciding what collapsible element each button is mapped to. To create in javascript, you should have one object that stores all your mappings and then you can invoke the entire accordion with a single javascript function.

On the first load of the page, create the mapping and initialize the collapse objects. Since we don't want them expanded yet, add the toggle:false option to prevent opening immediately. When any button in your accordion is clicked, get all the potentially collapsible elements. Hide any element that's not the originator of the event and toggle the target of the button that raised the event.

var mapping =  { 
  'btn-collapse-menu': '#navbar-collapse-menu' ,
  'btn-collapse-login': '#navbar-collapse-login' 
};

var $panels = $('#accordion .navbar-collapse').collapse({toggle: false});

$('#accordion .navbar-header button').click(function(){
  var target = mapping[this.id];
  $panels.not(target).collapse('hide');
  $panels.filter(target).collapse('toggle');
});

Here's a demo in stack snippets:

 var mapping = { 'btn-collapse-menu': '#navbar-collapse-menu' , 'btn-collapse-login': '#navbar-collapse-login' }; var $panels = $('#accordion .navbar-collapse').collapse({toggle: false}); $('#accordion .navbar-header button').click(function(){ var target = mapping[this.id]; $panels.not(target).collapse('hide'); $panels.filter(target).collapse('toggle'); }); 
 <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.js"></script> <div class="container-fluid panel" id="accordion"> <div class="navbar-header"> <button type="button" class="btn btn-default" id="btn-collapse-menu"> MENU </button> <button type="button" class="btn btn-default" id="btn-collapse-login"> LOGIN </button> </div> <div class="collapse navbar-collapse" id="navbar-collapse-menu"> <nav> <ul class="list-unstyled text-center"> <li><h3 href="#">Blog Content</h3></li> </ul> </nav> </div> <div class="collapse navbar-collapse" id="navbar-collapse-login"> <p>Login Content</p> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM