Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

emberjs - how to mark active menu item using router infrastructure

I'm trying to create navigation tabs (taken from Twitter Bootstrap):

<ul class="nav nav-tabs">
    <li class="active"><a href="#">Home</a></li>
    <li><a href="#">Profile</a></li>
    <li><a href="#">Messages</a></li>
</ul>

The active tab is marked with class="active".

There is great example of static navbar and Router/Outlet feature at http://jsfiddle.net/schawaska/pfbva/, but I can't understand how to create a dynamic navbar/menu/tab view.

As far as I understand, it is possible to use class bindings in each menu item:

 classNameBindings: ['isActive:active']

But where is the right place to switch isActive attributes ?

like image 999
coxx Avatar asked Jul 24 '12 10:07

coxx


4 Answers

Ember 1.11+:

{{#link-to "dashboard" tagName="li"}}
  <a href="{{view.href}}">Dashboard</a>
{{/link-to}}

Ember < 1.11 (bind-attr required):

{{#link-to "dashboard" tagName="li"}}
  <a {{bind-attr href="view.href"}}>Dashboard</a>
{{/link-to}}
like image 128
lesyk Avatar answered Oct 22 '22 05:10

lesyk


If you're using Ember >= 1.11, then https://stackoverflow.com/a/14501021/65542 below is the correct answer.


I would create a NavigationView, see http://jsfiddle.net/pangratz666/z8ssG/:

Handlebars:

<script type="text/x-handlebars" data-template-name="navigation">
    <ul class="nav nav-tabs">
        {{#view view.NavItemView item="home" }}
            <a {{action gotoHome}} >Home</a>
        {{/view}}
        {{#view view.NavItemView item="profiles" }}
            <a {{action gotoProfiles}} >Profiles</a>
        {{/view}}
        {{#view view.NavItemView item="messages" }}
            <a {{action gotoMessages}} >Messages</a>
        {{/view}}        
    </ul>
</script>

JavaScript:

App.NavigationView = Em.View.extend({
    templateName: 'navigation',
    selectedBinding: 'controller.selected',
    NavItemView: Ember.View.extend({
        tagName: 'li',
        classNameBindings: 'isActive:active'.w(),
        isActive: function() {
            return this.get('item') === this.get('parentView.selected');
        }.property('item', 'parentView.selected').cacheable()
    })
});

And inside your route's connectOutlets you have to set the current navigation item via router.set('navigationController.selected', 'home'); ...


Also take a look at the ember-bootstrap repository, which wraps this and more features of Bootstrap inside Ember.js

like image 24
pangratz Avatar answered Oct 22 '22 06:10

pangratz


Some of the above suggestions are still valid for twitter bootstrap case. You can also try something like this

{{#link-to 'dashboard' tagName='li'}} 
  {{#link-to 'dashboard'}}Link Title{{/link-to}}
{{/link-to}}
  1. The link-to with li tagName applies the active class to the li
  2. The inner link-to would be a anchor element which gives you Open in New Tab functionality when right-clicked
like image 17
selvagsz Avatar answered Oct 22 '22 06:10

selvagsz


Recently an Ember-cli addon came available to just do this. It is called ember-cli-active-link-wrapper.

Install: ember install ember-cli-active-link-wrapper

You can use it like this:

{{#active-link}}
  {{link-to "Index" "index"}}
{{/active-link}}

which results in:

<li class='active'>
    <a href="/" class='active'>Index</a>
</li>
like image 10
Willem de Wit Avatar answered Oct 22 '22 05:10

Willem de Wit