Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a single {{link-to}} active in Ember

Tags:

ember.js

In my Ember app I have navigation bar with groups. Each unique item appears twice in the bar: in its own group and in "All Items" group:

items

If user selects Item 3 both links become active by getting active CSS class:

item 3 selected

How can I change my code so that the link that user has clicked on becomes active? If user opens /item/3 URL manually the first link only should be active.

Here is my code so far: http://jsbin.com/yidofayoma/3/edit?html,js,output

var App = Ember.Application.create({
  rootElement: '#app'
});

App.Router.map(function() {
  this.route('item', { path: '/item/:item_id' });
});

App.ItemRoute = Ember.Route.extend({
  model: function(params) {
    return params.item_id;  
  }
});

Navigation bar template:

<ul>
  <li>{{#link-to "index"}}Index{{/link-to}}</li>
  <li>
    All items
    <ul>
      <li>{{#link-to "item" 1}}Item 1{{/link-to}}</li>
      <li>{{#link-to "item" 2}}Item 2{{/link-to}}</li>
      <li>{{#link-to "item" 3}}Item 3{{/link-to}}</li>
      <li>{{#link-to "item" 4}}Item 4{{/link-to}}</li>
      <li>{{#link-to "item" 5}}Item 5{{/link-to}}</li>
    </ul>
  </li>
  <li>
    Group A
    <ul>
      <li>{{#link-to "item" 1}}Item 1{{/link-to}}</li>
      <li>{{#link-to "item" 2}}Item 2{{/link-to}}</li>
      <li>{{#link-to "item" 3}}Item 3{{/link-to}}</li>
    </ul>
  </li>
  <li>
    Group B
    <ul>
      <li>{{#link-to "item" 4}}Item 4{{/link-to}}</li>
      <li>{{#link-to "item" 5}}Item 5{{/link-to}}</li>
    </ul>
  </li>
</ul>
<hr />

{{outlet}}

Ember version: 2.4.2

like image 376
Pavel Chuchuva Avatar asked Mar 22 '16 05:03

Pavel Chuchuva


2 Answers

Add group query parameter to item route:

App.ItemRoute = Ember.Route.extend({
  queryParams: {
    group: {}
  },
  model: function(params) {
    return params.item_id;  
  }
});

Next, add group query parameter to each link:

<ul>
  <li>{{#link-to "index"}}Index{{/link-to}}</li>
  <li>
    All items
    <ul>
      <li>{{#link-to "item" 1 (query-params group="all")}}Item 1{{/link-to}}</li>
      <li>{{#link-to "item" 2 (query-params group="all")}}Item 2{{/link-to}}</li>
      <li>{{#link-to "item" 3 (query-params group="all")}}Item 3{{/link-to}}</li>
      <li>{{#link-to "item" 4 (query-params group="all")}}Item 4{{/link-to}}</li>
      <li>{{#link-to "item" 5 (query-params group="all")}}Item 5{{/link-to}}</li>
    </ul>
  </li>
  <li>
    Group A
    <ul>
      <li>{{#link-to "item" 1 (query-params group="a")}}Item 1{{/link-to}}</li>
      <li>{{#link-to "item" 2 (query-params group="a")}}Item 2{{/link-to}}</li>
      <li>{{#link-to "item" 3 (query-params group="a")}}Item 3{{/link-to}}</li>
    </ul>
  </li>
  <li>
    Group B
    <ul>
      <li>{{#link-to "item" 4 (query-params group="b")}}Item 4{{/link-to}}</li>
      <li>{{#link-to "item" 5 (query-params group="b")}}Item 5{{/link-to}}</li>
    </ul>
  </li>
</ul>

This makes only one link active. The downside is an extra query string parameter in all item URLs, e.g. /item/5?group=all.

Demo: http://jsbin.com/josogumaqo/edit?html,js,output

like image 139
Pavel Chuchuva Avatar answered Sep 20 '22 00:09

Pavel Chuchuva


First, I want to say that's a very interesting question, thank you.

You may do as @pavel-chuchuva suggested, or (to avoid extra parameters and make urls user-friendly) create a separate route for each group:

App.Router.map(function() {
  this.route('all', { path: '/all/:item_id' });
  this.route('a', { path: '/a/:item_id' });
  this.route('b', { path: '/b/:item_id' });
});

You may create a mixing to avoid having a 3 copies of the same code

var itemsRoute = Ember.Mixin.create({
  model: function(params) {
    /*return something useful*/
    return params.item_id;  
  }
});

And extend all, a and b routes from that mixin:

App.AllRoute = Ember.Route.extend(itemsRoute, {});
App.ARoute = Ember.Route.extend(itemsRoute, {});
App.BRoute = Ember.Route.extend(itemsRoute, {});

Working example: http://jsbin.com/nibacogeye/edit?html,js,output

like image 30
Gennady Dogaev Avatar answered Sep 18 '22 00:09

Gennady Dogaev