4

I am using angular UI-Router and bootstrap collapse panels to build a sidebar for a style guide. My sidebar as is "works" but I'm getting a

Error: Cannot transition to abstract state 'parent'

when clicking the child states. In my real solution there are many parents with child groupings and the parents truly are abstract (i.e. they don't represent a physical page or state). I know I can't link directly to the parent states, and I don't believe I am, I just need to set their ui-sref in the parent panel so that I can get the parent to stay open by setting the ui-sref-active attribute.

I have an example running on plunker: http://plnkr.co/edit/bnvGcaOvzW4que8g3vh7?p=preview

code for reference:

angular.module('app', ['ui.router'])
        .config(function($stateProvider, $urlRouterProvider){
            $urlRouterProvider.otherwise("/");
            $stateProvider
                .state('home', {
                    url: "/",
                    templateUrl: "layout.html"
                })
                .state('parent', {
                    abstract: true,
                    url: '/parent',
                    templateUrl: "layout.html"
                })
                .state('parent.child', {
                    url: "/child",
                    templateUrl: "child.html"
                })
        });

layout.html

<div class="container-fluid">
    <div class="row">
        <div class="col-xs-3">
          <a ui-sref="home">Home</a>
           <div class="panel-group" id="sidebar">
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title">
                      <a data-toggle="collapse"  data-parent="#sidebar" data-target="#parent"
                   class="collapsed">Parent</a>
                  </h4>
                </div>
              <div id="parent" ui-sref="parent" class="panel-collapse collapse" ui-sref-active="in">
                <div class="list-group">
                    <a ui-sref="parent.child" ui-sref-active="active" class="list-group-item">Child</a>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-9">
            <div ui-view></div>
        </div>
    </div>
</div>
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
uuunk
  • 93
  • 1
  • 1
  • 7

1 Answers1

5

Short Answer:

Just remove ui-sref="parent" from your code. This particular ui-sref attribute is not required in order for ui-sref-active to work as you expect.

Long Answer:

ui-sref-active works by finding all child elements with a ui-sref and adding these elements to a states array attached to the element. On $stateChangeSuccess, each element loops through this array and if a state is found that matches the array, then the class is applied.

As an example:

<ul>
    <li ui-sref-active="open">
        <a ui-sref="app.home">Link</a>
        <ul>
            <li>
                <a ui-sref="app.home.this"></a>
            </li>
            <li>
                <a ui-sref="app.home.that"></a>
            </li>
            <li>
                <a ui-sref="app.home.whatever"></a>
            </li>
            <li>
                <a ui-sref="temp"></a>
            </li>
        </ul>
    </li>
</ul>

In the above example, assume app is an abstract. All 4 of those links will trigger the open class on the parent element, as they are contained within. It doesn't matter that they are not all part of the app.home structure.

  • You're right that does work at a simple HTML tag level (with ul/li), and it makes perfect sense. For whatever reason, it does not work in my example using the bootstrap collapse panel. I [forked the plunker](http://plnkr.co/edit/M4JZP7iQV5oj9u7c8EZs?p=preview) to show. I think it might have to do with bootstrap's javascript getting in the way. – uuunk Jun 01 '15 at 22:46
  • I'm not following. It appears that all directives are working in that Plunker? – joshuahiggins Jun 06 '15 at 19:55
  • It is working for the list-item section in the way you described above, successfully adding the `text-uppercase` class. But in the bootstrap collapse panel example above it, when clicking on the child page, the collapse panel does not stay open after the new page. The `ui-sref-active="in"` is not successfully added to the `class="panel-collapse collapse"` attribute. – uuunk Jun 08 '15 at 14:44