ember-cli-selectize
ember-cli-selectize copied to clipboard
Respect optionValuePath when multiple
This adds support for optionValuePath
when multiple: true
.
Use Case
I often want to have a select that is populated with Ember Data objects but only care about selecting one of their values, such as their id
. This is especially useful when using a select as a way of populating query params.
For example, imagine you have a search controller:
export default Ember.Controller.extend({
queryParams: ['tagIds'],
tags: [],
tagIds: []
});
The value for tags
comes from a collection of Ember Data objects set in the route:
export default Ember.Route.extend({
setupController: function(controller, model) {
this._super(controller, model);
var tags = this.store.find('tag');
set(controller, 'tags', tags);
}
});
Your API might expect to receive an array of tag ids in the query params. To support this, you'd want to add something like the following to the search template:
{{ember-selectize selection=tagIds
content=tags
optionLabelPath="content.name"
optionValuePath="content.id"}}
This could also be handled by adding an observer to set the tagIds
whenever the tags
array changes but that adds up really quickly when there are a lot of these on one page and, IMO is a much less elegant solution.
TL;DR;
It's confusing and limiting that setting the optionValuePath
is not respected by ember-selectize. If you want to select the entire object rather than one of its properties, you can simply not specify an optionValuePath
or specify 'content'
as its value.
This an interesting topic. If we take a closer look at the README, we find:
selection
- Ember-selectize will set this property to the selection that was made. Usually some property on a model, for example. If multiple is true, then it should be an array.
value
- Ember-selectize will set this property to the value of the selection that was made. It is not currently supported in multiple selection mode.
The idea is that selection
holds the whole objects and value
holds only the values according to optionValuePath
. Maybe that wasn't completely clear.
Also, value
isn't supported in multiple mode at the moment.
#16 has some interesting research on the topic. Specifically:
After reading the docs it seems that Ember.Select provides both
value
andselection
bindings.selection
will have the selected object.value
will have the selected value.
One of this project's goal is to be completely interchangeable with Ember.Select (although not necessarily in very rigid way).
So, I would say that we only need to support value
in multiple mode, and your problem is solved, right?
So, selecting multiple tag ids would be like:
{{ember-selectize value=tagIds
content=tags
multiple=true
optionLabelPath="content.name"
optionValuePath="content.id"}}
Selecting entire tag objects would be like:
{{ember-selectize selection=seletctedTags
content=tags
multiple=true
optionLabelPath="content.name"
optionValuePath="content.id"}}
On a separate note, we need to have optionValuePath
because of the way selectize works. The addItem(value, silent)
must take a unique value in (you are passing the entire object, which is ok for primitive types, but I think it can go wrong for objects when there is no optionValuePath
). There might be another way to do this. But that's a different problem.
OK, cool. I agree that it would be best to try to stay interchangeable with Ember.select
.
While using value
instead of selection
to accomplish this is more in line with the way Ember.select
currently works, it still won't make it interchangeable because Ember.select
doesn't support multiple with optionValuePath
and optionLabelPath
. http://emberjs.jsbin.com/pifame/2/edit?html,js,console,output
So, would you still be open to a PR that adds support for multiple
with value
and optionValuePath
and optionLabelPath
?
You mean that Ember.Select doesn't support value when multiple = true? No, it doesn't support. It is actually stated in the docs:
value
String In single selection mode (when multiple is false), value can be used to get the current selection's value or set the selection by its value.It is not currently supported in multiple selection mode.
Default: null
It wouldn't be interchangeable, yes, but what I meant from that is "someone that goes from Ember.Select to ember-selectize will get things working". In other words, every Ember.Select feature maps to ember-selectize, but not every feature of ember-selectize maps to Ember.Select. That is expected since selectize supports more features.
I would be very grateful for such a PR. :smiley:
I would be very grateful for such a PR. :smiley:
And so would I! I have to do this all the time, and I'm always going in circles figuring out how to do it..
Maybe:
{{ember-selectize content=listOfObjects
optionValuePath='content.id'
optionLabelPath='content.name'
selection=listOfIds
selectionToValues=true}}
or valueSelection=listOfIds
Either way, setting the selection
or valueSelection
would display the correct pre-selected content.
@miguelcobain, @HeroicEric is there any other way in the existing version to get it working? looks like it could take some time for this PR to be merged.
If you're looking for a way to have value
working with multiple, you can do it with a computed property:
values: Ember.computed.mapBy('model.someArray', 'id')
where 'model.someArray'
is whatever array you're binding in ember-selectize like {{ember-selectize selection=model.someArray}}
(doesn't necessarily need to be within model
).
So, would you still be open to a PR that adds support for multiple with value and optionValuePath and optionLabelPath?
Of course, this would be the way to go. :) I currently don't have the time needed, but I'll try to poke this if no one jumps in.
and it will be like {{ember-selectize value=values selection=selectionModel content=contentArray}} ?
selectionModel
in your example is just a "proxy" property that the values
computed property uses. So it could be named anything you want, as long as it is also in the Ember.computed
dependent properties.
The computed property would be placed in your controller, for example.