"Cannot transition to abstract state'" when trying to highlight parent in sidebar

13,250

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.

Share:
13,250
uuunk
Author by

uuunk

Software Architect for On Point Technology, Inc.

Updated on August 22, 2022

Comments

  • uuunk
    uuunk over 1 year

    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>
    
  • uuunk
    uuunk almost 9 years
    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 to show. I think it might have to do with bootstrap's javascript getting in the way.
  • joshuahiggins
    joshuahiggins almost 9 years
    I'm not following. It appears that all directives are working in that Plunker?
  • uuunk
    uuunk almost 9 years
    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.