4

So the problem comes when trying the project I'm working on the phone, the links I have inside my navbar are all with hash tag links (#) since it's AngularJS... Now I did find a way to make it to work perfectly in jQuery

$('.nav li a').not('.dropdown-toggle').on('click', function(){
    $('.navbar-ex1-collapse').removeClass('in').addClass('collapse');
});

but since they always say to stop using plain jQuery or DOM manipulation...so how am I suppose to do this? I'm new to AngularJS and I'm not to good at starting to create my own directive, or should I just have $watch? but then how can I watch a certain class to be clicked then? I tried to do this example
twitter-boostrap-navbar-with-angular-js-collapse-not-functioning
but it was made specifically for Bootstrap 2.3 and some properties have changed too, so I'm getting a little confused. I could leave the jQuery, but you know...I'm trying to learn the proper way of doing... :)

Oh and if that help, my navbar Bootstrap 3 menu looks like this

<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
    <div class="container">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>

      <!-- Collect the nav links, forms, and other content for toggling -->
      <div class="collapse navbar-collapse navbar-ex1-collapse">
        <ul class="nav navbar-nav">
            <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Portfolio<b class="caret"></b></a>
                <ul class="dropdown-menu">
                    <li><a href="#/new">Add</a></li>
                    <li><a href="#/undo">Undo</a></li>
                    <li><a href="#/list">List</a></li>
                </ul>
            </li> 
        </ul>
      </div><!-- /.navbar-collapse -->
    </div><!-- /.container -->
</nav>
Community
  • 1
  • 1
ghiscoding
  • 12,308
  • 6
  • 69
  • 112

3 Answers3

6

Probably a bit late, but here is a bootstrap 3.x version of the answer I gave in the question you referenced - http://jsfiddle.net/N99dQ/

This time, I have used ng-init instead of a controller, but both ways will work. Also worth mentioning, if you are not using the dropdowns, you'll only need to include ['ui.bootstrap.collapse']

HTML:

<nav id="navbar-example" class="navbar navbar-inverse navbar-static" role="navigation">
  <div class="container-fluid">
    <div class="navbar-header">
      <button class="navbar-toggle" type="button" ng-init="isCollapsed = true" ng-click="isCollapsed = !isCollapsed">
        <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="#">Project Name</a>
    </div>
    <div collapse="isCollapsed" class="navbar-collapse bs-js-navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="dropdown">
          <a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Something else here</a></li>
            <li role="presentation" class="divider"></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Separated link</a></li>
          </ul>
        </li>
        <li class="dropdown">
          <a href="#" id="drop2" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
          <ul class="dropdown-menu" role="menu" aria-labelledby="drop2">
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Something else here</a></li>
            <li role="presentation" class="divider"></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Separated link</a></li>
          </ul>
        </li>
      </ul>
      <ul class="nav navbar-nav navbar-right">
        <li id="fat-menu" class="dropdown">
          <a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
          <ul class="dropdown-menu" role="menu" aria-labelledby="drop3">
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Something else here</a></li>
            <li role="presentation" class="divider"></li>
            <li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.nav-collapse -->
  </div><!-- /.container-fluid -->
</nav>

Javascript:

var myApp = angular.module('myApp', ['ui.bootstrap']);
Sean McClory
  • 4,195
  • 3
  • 32
  • 35
  • It's never too late :) I'll take a look at it when I get back home tonight. Seems nice since I'm already using `UI.Bootstrap` When you say include, do you mean to add it inside the module call? Is it like this then: `['ui.bootstrap','ui.bootstrap.collapse']`? Nice logo noducks...hehe – ghiscoding Feb 03 '14 at 14:46
  • Yes. So the javascript would just be - `var myApp = angular.module('myApp', ['ui.bootstrap.collapse']);` – Sean McClory Feb 03 '14 at 19:01
  • Depending what you are using, you could type `var myApp = angular.module('myApp', ['ui.bootstrap.collapse', 'ui.bootstrap.dropdownToggle', 'ui.bootstrap.typeahead']);` etc. Here's a fiddle with the dropdowns and collapse working- http://jsfiddle.net/53aCw/ – Sean McClory Feb 03 '14 at 19:04
  • So I finally got home and I'm trying your code, but I have a little issue with it, I copied some pieces here and there and got the dropdown working but the problem remains that whenever I click (choose) an item from the menu, the stays open... I want it to close since I chose a page... I tried your jsfiddle and it does the same thing :( – ghiscoding Feb 04 '14 at 03:42
  • You can add `ng-click="isCollapsed=true"` to each of the menu links, and that will close it. http://jsfiddle.net/enJUz/ – Sean McClory Feb 04 '14 at 08:51
  • Hmm yes ok it does work but wow that is becoming so much code especially if I have 100 links, I would need 100x of that `ng-click`... I will upvote it as it works, but I can't approve it as a valid answer though. – ghiscoding Feb 04 '14 at 14:01
  • You can also move the href logic into a controller using the `$location` service. i.e. `ng-click="go(somewhere)'` http://jsfiddle.net/dWJQJ/ - Alternatively, use a directive to handle each menu item. i.e `somewhere` – Sean McClory Feb 04 '14 at 16:14
  • If you have lots of links, another alternative is to use ng-repeat and iterate over an array of the displayed text and their corresponding links. One ng-repeat for each group of menu-items. I think you could get the html fairly small by doing that. – Sean McClory Feb 04 '14 at 16:27
  • Finally - a working example. Have spent ages searching and tweaking. Thanks :) – JsAndDotNet Aug 21 '14 at 14:18
  • In ui-bootstrap 0.12.0 dropdown's in navbar are broken. 0.11.0 works fine. – Dirk Mar 01 '15 at 09:09
1

As an alternate to my previous answer, this one uses ng-repeat to condense the html. http://jsfiddle.net/m5TZw/

HTML

  <div class="container-fluid">
    <div class="navbar-header">
      <button class="navbar-toggle" type="button" ng-click="isCollapsed = !isCollapsed">
        <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="#">Project Name</a>
    </div>
    <div collapse="isCollapsed" class="navbar-collapse bs-js-navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="dropdown">
          <a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
              <li ng-repeat="m in menu1" role="presentation"><a ng-click="go(m.link)" role="menuitem" tabindex="-1">{{m.text}}</a></li>
          </ul>
        </li>
        <li class="dropdown">
          <a href="#" id="drop2" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
          <ul class="dropdown-menu" role="menu" aria-labelledby="drop2">          
              <li ng-repeat="m in menu1" role="presentation"><a ng-click="go(m.link)" role="menuitem" tabindex="-1">{{m.text}}</a></li>
          </ul>
        </li>
      </ul>
      <ul class="nav navbar-nav navbar-right">
        <li id="fat-menu" class="dropdown">
          <a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
          <ul class="dropdown-menu" role="menu" aria-labelledby="drop3">
              <li ng-repeat="m in menu1" role="presentation"><a ng-click="go(m.link)" role="menuitem" tabindex="-1">{{m.text}}</a></li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</nav>

JS

var myApp = angular.module('myApp', ['ui.bootstrap.collapse', 'ui.bootstrap.dropdownToggle']);

function NavBarCtrl($scope, $location) {

$scope.isCollapsed = true;

$scope.menu1 = [
    {text: 'first', link : '/first'},
    {text: 'second', link : '/second'},    
    {text: 'third', link : '/third'},
    {text: 'fourth', link : '/fourth'},    
    {text: 'fifth', link : '/fifth'}
];

$scope.go = function(path) {
    $scope.isCollapsed = true;
    $location.path('#/' + path);
}     
}
Sean McClory
  • 4,195
  • 3
  • 32
  • 35
  • Thanks for your time noducks, if I had to choose between the 2 answers you gave, I would probably take the first answer. This answer is nice but I think links should remain on the menu page so the first is better in that case. Thanks again – ghiscoding Feb 07 '14 at 14:00
0

Rather importing a heavy "ui.bootstrap" I feel that this will be simple JS fix:

//for close, opened dropdown.
$(".nav a").click(function () {
    if ($(".navbar-collapse").hasClass("in")) {
        $('[data-toggle="collapse"]').click();
    }
});

If this code is not working correctly then see that it's binding correctly, so place it in controller that loads page.

Syed
  • 15,657
  • 13
  • 120
  • 154
  • I already use this jquery code and it's already part of my original question, but my question was more like... how to do it the real angular way, not using jQuery. – ghiscoding Dec 06 '14 at 21:01