Reputation: 1071
I'm creating an app that has a listing of items and a series of filter buttons at the top. As the user applies different filters, I want the buttons to change style using CSS classes to show them as enabled/disabled.
I want to be able to write something like the code below, but it doesn't work.
{{#each category in category_options}}
<button {{action "filterCategory" category}} {{bind-attr class=":btn-small isFiltered(category):btn-active:btn-inactive"}}>{{category}}</button>
{{/each}}
In this example, isFiltered is a computed property on the controller, and it looks at the query parameters to determine whether the specified category has been applied as a filter.
From the reading I've done, it sounds like you can't pass parameters to computed properties. I've come across answers mentioning helpers, bound helpers, and components, but I haven't been able to sort out which one I need, or how I would apply it in this situation.
EDIT: To clarify the example, imagine I have a series of buttons that filter on various tags:
Filter for: <Cats> <Dogs> <Rabbits> ... # imagine an arbitrary number of these. dozens, maybe
When a user clicks Cats, it triggers filterCategory, which sets the model.category query parameter to ['Cats']. If he then clicks Dogs, model.category becomes ['Cats','Dogs']
Following the latter case, I want the Cats and Dogs buttons to have the class btn-active.
I would like to define isFiltered like so:
isFiltered: function(buttonname) {
if (this.get('model.categories').containsObject(buttonname)) { # pseudocode
return true;
}
else { return false; }
}
Passing buttonname into the function makes it easy to do the comparison for every button and determine if it's in the filter.
If this overall approach is the wrong way to go about things, what's the right way to do it?
Upvotes: 0
Views: 1084
Reputation: 194
1)As component you can do something like below:
in template
{{#each category in category_options}}
{{category-button category=category selectedCategoies=selectedCategories action="filterCategory"}}
{{/each}}
component template
{{category}}
component
export default Ember.Component.extend({
tagName: 'button',
classNames: 'btn-small',
classNameBindings: 'isFiltered:btn-active:btn-inactive',
isFiltered: Ember.computed('category', 'selectedCategories', function(){
return this.get('selectedCategories').contains(this.get('category'));
}),
click: function(){
this.sendAction('action', this.get('category'));
}
})
2)Or you can make your categories as array of objects like so
[
{name: 'category1', isActive: false},
{name: 'category2', isActive: true},
...
]
And then change isActive
flag as you need.
In controller:
categoryObjects: Ember.computed('category_options', function(){
return this.get('category_options').map(function(category){
Ember.Object.create({name: category, isActive: false});
})
}),
actions: {
filterCategory: function(category){
category.toggleProperty('isActive');
return
}
}
And in template:
{{#each category in categoryObjects}}
<button {{action "filterCategory" category}} {{bind-attr class=":btn-small category.isActive:btn-active:btn-inactive"}}>{{category.name}}</button>
{{/each}}
Upvotes: 1
Reputation: 56
If you were to do this by your approach, you can get it working by making a Computed Property Macro and then looping over the category_options and creating computed properties as isCategory ( isRed, isBlue etc..)
But this won't be the right way to do it, You need to make those button components, which will accept the category_options and model.category and internally decide whether it should be active or not.
Upvotes: 0
Reputation: 1189
I'm not sure how the rest of your code looks like but in general you would use model
hook in your route to get query parameter, process it, if needed, and return with your model, let's say you would return model.category
, then in your controller you would have something like this:
isFiltered: function() {
var category = this.get('model.category');
// do whatever you want here with category to return true or false
}.property('model.category')
then in .hbs
you would be able to write this:
{{#each category in category_options}}
<button {{action "filterCategory" category}} {{bind-attr class=":btn-small isFiltered:btn-active:btn-inactive"}}>{{category}}</button>
{{/each}}
Upvotes: 0