Responsive dropdown navbar with angular-ui bootstrap (done in the correct angular kind of way)
Asked Answered
I

4

76

I've created a JSFiddle with a dropdown navbar using angular-ui-boostrap's module "ui.bootstrap.dropdownToggle": http://jsfiddle.net/mhu23/2pmz5/

<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
    <div class="container"> <a class="brand" href="#">
                My Responsive NavBar
            </a>

        <ul class="nav">
            <li class="divider-vertical"></li>
            <li class="dropdown"> <a href="#" class="dropdown-toggle">
                        Menu 1 <b class="caret"></b>
                    </a>

                <ul class="dropdown-menu">
                    <li><a href="#/list">Entry 1</a>
                    </li>
                    <li><a href="#/list">Entry 2</a>
                    </li>
                </ul>
            </li>
          ....
        </ul>
    </div>
</div>
</div>

As far as I understand this is the proper, angular kind of way to implement such a dropdown menu. The "wrong" way, in terms of angularjs, would be to include bootstrap.js and to use "data-toggle="dropdown"... Am I right here?

Now I'd like to add responsive behaviour to my navbar as done in the following Fiddle: http://jsfiddle.net/ghtC9/6/

BUT, there's something I don't like about the above solution. The guy included bootstrap.js!

So what would be the correct angular kind of way to add responsive behaviour to my existing navbar?

I obviously need to use bootstraps responsive navbar classes such as "nav-collapse collapse navbar-responsive-collapse". But I don't know how...

I'd really appreciate your help!

Thank you in advance! Michael

Insufficiency answered 28/4, 2013 at 22:18 Comment(0)
S
57

You can do it using the "collapse" directive: http://jsfiddle.net/iscrow/Es4L3/ (check the two "Note" in the HTML).

        <!-- Note: set the initial collapsed state and change it when clicking -->
        <a ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed" class="btn btn-navbar">
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
        </a>
        <a class="brand" href="#">Title</a>
           <!-- Note: use "collapse" here. The original "data-" settings are not needed anymore. -->
           <div collapse="navCollapsed" class="nav-collapse collapse navbar-responsive-collapse">
              <ul class="nav">

That is, you need to store the collapsed state in a variable, and changing the collapsed also by (simply) changing the value of that variable.


Release 0.14 added a uib- prefix to components:

https://github.com/angular-ui/bootstrap/wiki/Migration-guide-for-prefixes

Change: collapse to uib-collapse.

Salade answered 6/5, 2013 at 14:14 Comment(3)
This does not appear to answer the question directly - he is talking about a dropdown button in the navbar and you are talking about collapsing the whole navbar. Am I missing something?Kwangtung
Thanks man, I spent a lot of time trying to figure out why a simple collapsible menu was not workingAnglia
Personally, I don't think uib-collapse is the wrong way to go for a nav bar. I would rather use uib-dropdown.Laverty
E
123

Update 2015-06

Based on antoinepairet's comment/example:

Using uib-collapse attribute provides animations: http://plnkr.co/edit/omyoOxYnCdWJP8ANmTc6?p=preview

<nav class="navbar navbar-default" role="navigation">
    <div class="navbar-header">

        <!-- note the ng-init and ng-click here: -->
        <button type="button" class="navbar-toggle" ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">Brand</a>
    </div>

    <div class="collapse navbar-collapse" uib-collapse="navCollapsed">
        <ul class="nav navbar-nav">
        ...
        </ul>
    </div>
</nav>

Ancient..

I see that the question is framed around BS2, but I thought I'd pitch in with a solution for Bootstrap 3 using ng-class solution based on suggestions in ui.bootstrap issue 394:

The only variation from the official bootstrap example is the addition of ng- attributes noted by comments, below:

<nav class="navbar navbar-default" role="navigation">
  <div class="navbar-header">

    <!-- note the ng-init and ng-click here: -->
    <button type="button" class="navbar-toggle" ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed">
      <span class="sr-only">Toggle navigation</span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" href="#">Brand</a>
  </div>

  <!-- note the ng-class here -->
  <div class="collapse navbar-collapse" ng-class="{'in':!navCollapsed}">
  
    <ul class="nav navbar-nav">
    ...

Here is an updated working example: http://plnkr.co/edit/OlCCnbGlYWeO7Nxwfj5G?p=preview (hat tip Lars)

This seems to works for me in simple use cases, but you'll note in the example that the second dropdown is cut off.

Excel answered 11/10, 2013 at 10:45 Comment(15)
Instead of ng-class you should use 'collapse="navCollapsed"'. because your version doesn't make any animationSheasheaf
Another improvement: add ng-click="navCollapsed=true" to the last div of your snippet so that the drop down menu collapses after an item as been selected.Livialivid
@LarsBehnke but then you also get an animation when the navbar is NOT collapsed and that looks weird.Showthrough
The overflow can be made visible by adding overflow: visible to the .panel-group panel tag in the bootstrap.css documentAilurophobe
I can't even get the collapse="navCollapse" method to work at the moment for some reasonShaunna
@Shaunna It should be "navCollapsed", you missed a "d" thereNadia
Many of us are on BS2 for legacy projects we don't want the pain of converting. So why is switching to a BS3 answer one that gets a lot of votes? Am I missing something?Earthling
@SamanthaAtkins - guess it's just useful :) The accepted answer is for BS2, and I'm not suggesting changing. When I added the answer, I'd arrived looking for a BS3 solution, and didn't find one. I wouldn't mind guessing that the ratio of upvotes between the answers is an informal poll of the technology stack folk are using!Excel
So this is a great example but I feel it is lacking in keyboard support for it.Metacarpal
Can anyone get this to animate/transition like the normal dropdown?Yippee
I didn't edit in time, but I changed <div class="collapse navbar-collapse" ng-class="{'in':!navCollapsed}"> to <div collapse="navCollapsed"> and the transition worked!Yippee
I must be missing something here, but doesn't this solution result in the desktop version of the menu being collapsed and unviewable, given navbar-toggle is hidden? Even with the updates from the comments this is still the case.Sarcoid
updated the example.. @NathanHoad, media queries expose the navigation on desktop: @media (min-width: 768px) .navbar-collapse.collapse { display: block!important; height: auto!important; ...}Excel
Quite important for mental sanity which I lost for the sake of all ;) since angular-ui 0.13 you need ngAnimate if you want transitions. github.com/angular-ui/bootstrap/issues/3676Interplay
If you are using dropdown menu in navbar, the ng-class is also important for setting a class called "open" in the dropdown menu like in the bootstrap example. <li class="dropdown" ng-class="{open: !isDropDownCollapsed}">Subsist
S
57

You can do it using the "collapse" directive: http://jsfiddle.net/iscrow/Es4L3/ (check the two "Note" in the HTML).

        <!-- Note: set the initial collapsed state and change it when clicking -->
        <a ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed" class="btn btn-navbar">
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
        </a>
        <a class="brand" href="#">Title</a>
           <!-- Note: use "collapse" here. The original "data-" settings are not needed anymore. -->
           <div collapse="navCollapsed" class="nav-collapse collapse navbar-responsive-collapse">
              <ul class="nav">

That is, you need to store the collapsed state in a variable, and changing the collapsed also by (simply) changing the value of that variable.


Release 0.14 added a uib- prefix to components:

https://github.com/angular-ui/bootstrap/wiki/Migration-guide-for-prefixes

Change: collapse to uib-collapse.

Salade answered 6/5, 2013 at 14:14 Comment(3)
This does not appear to answer the question directly - he is talking about a dropdown button in the navbar and you are talking about collapsing the whole navbar. Am I missing something?Kwangtung
Thanks man, I spent a lot of time trying to figure out why a simple collapsible menu was not workingAnglia
Personally, I don't think uib-collapse is the wrong way to go for a nav bar. I would rather use uib-dropdown.Laverty
C
8

Not sure if anyone is having the same responsive issue, but it was just a simple css solution for me.

same example

...  ng-init="isCollapsed = true" ng-click="isCollapsed = !isCollapsed"> ...
...  div collapse="isCollapsed"> ...

with

@media screen and (min-width: 768px) {
    .collapse{
        display: block !important;
    }
}
Cetacean answered 13/1, 2014 at 22:1 Comment(1)
You should prepend the .collapse selector with the nav's id so it doesn't screw every collapse in the pageGroark
S
1

My solotion for responsive/dropdown navbar with angular-ui bootstrap (when update to angular 1.5 and, ui-bootrap 1.2.1)
index.html

     ...    
    <link rel="stylesheet" href="/css/app.css">
</head>
<body>


<nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <input type="checkbox" id="navbar-toggle-cbox">
            <div class="navbar-header">
                <label for="navbar-toggle-cbox" class="navbar-toggle" 
                       ng-init="navCollapsed = true" 
                       ng-click="navCollapsed = !navCollapsed"  
                       aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </label>
                <a class="navbar-brand" href="#">Project name</a>
                 <div id="navbar" class="collapse navbar-collapse"  ng-class="{'in':!navCollapsed}">
                    <ul class="nav navbar-nav">
                        <li class="active"><a href="/view1">Home</a></li>
                        <li><a href="/view2">About</a></li>
                        <li><a href="#">Contact</a></li>
                        <li uib-dropdown>
                            <a href="#" uib-dropdown-toggle>Dropdown <b class="caret"></b></a>
                            <ul uib-dropdown-menu role="menu" aria-labelledby="split-button">
                                <li role="menuitem"><a href="#">Action</a></li>
                                <li role="menuitem"><a href="#">Another action</a></li>                                   
                            </ul>
                        </li>

                    </ul>
                 </div>
            </div>
        </div>
    </nav>

app.css

/* show the collapse when navbar toggle is checked */
#navbar-toggle-cbox:checked ~ .collapse {
    display: block;
}

/* the checkbox used only internally; don't display it */
#navbar-toggle-cbox {
  display:none
}
Styrax answered 2/3, 2016 at 9:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.