Reputation: 1888
How can I specify a class to an item when clicked with Ember. I am using a Handlebars action on the elements of a table to sort by properties. I want to add a class to the property being sorted so I can show the user the current property being sorted. How can I do this?
I have an ember controller shown below:
App.UsersController = Ember.ArrayController.extend
title: 'Users'
count: Ember.computed.alias 'length'
sortProperties: ['username']
actions:
sort: (property) ->
console.log property
if @get('sortProperties')[0] is property
@set('sortAscending', !@get 'sortAscending')
else
@set 'sortProperties', [property]
@set('sortAscending', true)
The controller allows me to click on headings in a table to sort the table. The html is shown below:
<thead>
<tr>
<th>Action</th>
<th class="sort" {{action sort 'last'}}>Last</th>
<th class="sort" {{action sort 'first'}}>First</th>
<th class="sort" {{action sort 'username'}}>Username</th>
<th class="sort" {{action sort 'email'}}>Email</th>
</tr>
</thead>
Upvotes: 2
Views: 480
Reputation: 10726
currentSort
property (optional)First, I created a currentSort
property on your App.UsersController
which cleans a little bit the code. We'll use it later.
App.UsersController = Ember.ArrayController.extend
sortProperties: ['username']
currentSortBinding: 'sortProperties.firstObject'
actions:
sort: (sort) ->
if sort is @get('currentSort')
@toggleProperty 'sortAscending'
else
@setProperties
currentSort: sort
sortAscending: true
<th>
You'll then have to define a custom view for the <th>
which will do 2 things:
active-sort
when the sort of the view is the currentclick
ing the viewIt will looks like this:
App.SortView = Ember.View.extend
template: Ember.Handlebars.compile('{{view.sortName}}')
tagName: 'th'
sortName: null # (will be different for each <th> : `last`, `first`,..)
classNameBindings: [ ':sort', 'isCurrent:active-sort' ]
isCurrent: (->
@get('sortName') is @get('controller.currentSort')
).property('sortName', 'controller.currentSort')
click: ->
var newSort = @get('sortName');
@get('controller').send('sort', newSort);
Here we customized the view class names, and we handled click
event on the view.
This is really simple to insert views in templates:
<thead>
<tr>
{{view App.SortView sortName="default"}}
{{view App.SortView sortName="price"}}
{{view App.SortView sortName="alphabetical"}}
</tr>
</thead>
You can test all of this in a working JSBin
Upvotes: 2
Reputation: 1264
I don't know if this is the best workaround, but you could have some "sort flag" that you could bind CSS on.
In your controller (in "classic" javascript) :
sortedByLast : function() { return this.get("sortProperties")[0] === "last" }.property("sortProperties.@each")
// etc ...
In your template :
<th {{bind-attr class=":sort sortedByLast:current-sort"}} {{action sort 'last'}}>Last</th>
So the sort
class would always be on, and the current-sort
would only be there if it match its proper flag.
Upvotes: 0