5

I noticed that using EmberJS, if the route you are on matches a link with the same path on your page, it takes automatically the class 'active'.

I'm currently building a navigation bar that is using this, but my concern comes from the fact that not all my routes match my navigation bar.

For example, when I'm in the route /messages, I'd like to make the item /services active. Or when I'm in the route /forums/history, I'd like to make the item /forums/archives active. Even though this route is not in the navigation, I want to highlight an item which is related to it.

My navigation is generated from a json object that looks like that:

[
  {
    "label": "Forums",
    "link": "forums",
    "children": [
      {
        "label": "Latest"
        "link": "forums.latest"
      }
      {
        "label": "Archives"
        "link": "forums.archives"
      }
    ]
  }
]

I had a couple of ideas that I don't like, that's why I'm coming here to have your advises. Here are my ideas:

  • Define a property into the view to define which item should be active in the navigation:

views/forums/history.js:

Ember.View.extend({
  navigationActiveItem: 'forums.archives'
});
  • Define in my json object the list of links that will highlight the item

json file:

[
  {
    "label": "Forums",
    "link": "forums",
    "children": [
      {
        "label": "Archives"
        "link": "forums.archives",
        "makeActive": ["forums.history", "forums.records"] //If you are on one of those route, it will active forums.archives
      }
    ]
  }
]

router.js:

Router.map(function () {
  this.route('forums', function () {
    this.route('latest');
    this.route('archives');
    this.route('history');
  });
});

Do you have any better suggestion to do such a thing? Thanks

alexmngn
  • 9,107
  • 19
  • 70
  • 130

2 Answers2

4

Use the current-when parameter of {{#link-to}}. It will allow you to define alternative routes that cause the link-to to be active.

Since ember 1.8, current-when can accept a space delimited string of routes. For an implementation that works in 1.7, check out Is there a way to pass an array to currentWhen in EmberJS?

Community
  • 1
  • 1
Andreas Andreou
  • 1,332
  • 10
  • 10
  • It does, but you can then add some css rules that will display the links the way you want (i.e. active shown as inactive and everything else as active) – Andreas Andreou Oct 17 '14 at 22:57
  • To have active as an inactive item, that's not really css semantic and more a 'trick' – alexmngn Oct 20 '14 at 19:19
  • Not sure what the issue is. Did you try {{#link-to 'services' current-when='messages'}}Services{{/link-to}} and {{#link-to 'forums.archives' current-when='forums.history'}}Archives{{/link-to}} ? – Andreas Andreou Oct 21 '14 at 13:57
1

The way I do this is by setting properties in my application controller.

(This assumes that your nav bar template is in application.handlebars)

For example, if you want your "Forums" tab to be active on any forums route you could create a property called something like isForums which would look like this:

isForums: function(){
  return this.get('currentPath').split('.')[0] === 'forums';
}.property('currentPath')

You could then access this from application.handlebars like so:

<li {{bind-attr class="isForums:active"}}>
  {{#link-to "forums"}}Forums{{/link-to}}
</li>

This adds the active class to the <li> if isForums evaluates to true.

AJ Gregory
  • 1,589
  • 18
  • 25
  • The issue with this approach is when you have a website with hundred of pages, it starts to be messy to have computed property for all pages you need to define. – alexmngn Oct 13 '14 at 05:16