3

I'm using Angularjs and Bootstrap 2.3.2 to create a menu system with submenus. This works great until I'm using the responsive design on narrow devices and the collapsed version of the menu system has a problem. Specifically the menu does not collapse after selecting one of the menu items. Interestingly the SUB menus collapse even when the main does not. The menu CAN be collapsed if you click on the icon-bar thing, but the menu items themselves will not do this.

I retrieve the menus ( which are user specific) via $resource and they are created by the following template:

<div class="navbar navbar-inverse navbar-fixed-top hidden-print">
    <div class="navbar-inner">
        <div class="container">
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
            </button>
            <a class="brand" href="#">BRAND HERE</a>
            <div ng-controller="MenuController" class="nav-collapse collapse">
                <div ng-repeat="menu in menus">
                <ul  class="nav" role="navigation">
                    <li ng-show="menu.submenus" class="dropdown" class="active">
                        <a class="dropdown-toggle" href="{{menu.route}}">{{menu.title}}<i class="icon-caret-down"></i><b class="caret"></b></a>
                        <ul class="dropdown-menu">
                            <li ng-repeat="submenu in menu.submenus"><a href="{{submenu.route}}">{{submenu.title}}</a></li>
                        </ul>
                    </li>
                    <li ng-hide="menu.submenus"><a href="{{menu.route}}">{{menu.title}}</a></li>
                </ul>
                </div>
            </div>
            <!--/.nav-collapse -->
        </div>
        <!--/ container -->
    </div>
</div>
<!--/ navbar -->

The menus object looks something like this:

[
    {
        "title": "Setup",
        "route": "#",
        "submenus": [
            {
                "title": "one",
                "route": "#/one",
                "submenus": null
            },
            {
                "title": "two",
                "route": "#/two",
                "submenus": null
            }        ]
    },
    {
        "title": "special",
        "route": "#/special",
        "submenus": null
    },
    {
        "title": "boring",
        "route": "#/boring",
        "submenus": null
    }
]

1 Answer 1

1

Ok, I think I figured this out. Inspiration thanks to this question's answers:

Twitter Bootstrap Navbar with AngularJS - Collapse Not Functioning

I converted from using the bootstrap javascript to "angular" style. Specifically, the template becomes:

<div class="navbar navbar-inverse navbar-fixed-top hidden-print">
    <div class="navbar-inner">
        <div class="container">
            <div ng-controller="MenuController" >
            <button type="button" class="btn btn-navbar" ng-init="isCollapsed=true" ng-click="isCollapsed = !isCollapsed" >
                <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
            </button>
            <a class="brand" href="#">BRAND HERE</a>
            <div  class="nav-collapse" collapse="isCollapsed">
                <div ng-repeat="menu in menus">
                <ul class="nav" role="navigation">
                    <li ng-show="menu.submenus" class="dropdown" class="active">
                        <a class="dropdown-toggle" href="{{menu.route}}">{{menu.title}}<i class="icon-caret-down"></i><b class="caret"></b></a>
                        <ul class="dropdown-menu">
                            <li ng-repeat="submenu in menu.submenus"><a ng-click="doCollapse()" href="{{submenu.route}}">{{submenu.title}}</a></li>
                        </ul>
                    </li>
                    <li ng-hide="menu.submenus"><a ng-click="doCollapse()" href="{{menu.route}}">{{menu.title}}</a></li>
                </ul>
                </div>
            </div>
            </div>
            <div class="navbar-text pull-right" id="logout" ng:controller="LogoutController">
                <span id="loggedinGreeting" ng-show="isLoggedIn()">Hello {{curUser.getCurUser().username}} &nbsp; &nbsp; <a href="" ng-click="logout()" >logout</a> </span>
                <span id="loginlink" ng-hide="isLoggedIn()"><a href="" ng-click="gotoLogin()" >login</a>&nbsp; &nbsp;<a id="signuplink" href="/signup.htm" >signup</a></span>
            </div>
            <!--/.nav-collapse -->
        </div>
        <!--/ container -->
    </div>
</div>

I removed the data-toggle and data-target attributes and replaced them with an ng-click directives which points to a controller based method which forced the collapse. The javascript addition to the MenuController is as follows:

$scope.doCollapse = function() {
       $scope.isCollapsed=true;
}

The solution seems so obvious now that it's working. I guess I kept banging my head on doing it the bootstrap way. I suppose this could be simplified even further by moving the action of the doCollapse function into the ng-click itself, but I'm happy the way it is.

Sign up to request clarification or add additional context in comments.

1 Comment

What's the collapse="isCollapsed" attribute for? I've run into the same problem and am trying to get your fix working. Not sure if you left any necessary code out of this example (like a directive or something).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.