I'm using ember-drag-drop to implement a sortable list. This worked fine until I needed to implement a text filter on the list.
{{#sortable-objects sortableObjectList=filteredItems enableSort=true}}
{{#each filteredItems as |item index|}}
{{#draggable-object content=item isSortable=true isDraggable=true}}
{{item.name}}
{{/draggable-object}}
{{/each}}
{{/sortable-objects}}
The filteredItems is a computed property which filters the original list based on a user's text input.
filteredItems: computed('items', 'term', function() {
let term = this.get('term');
let items = this.get('items');
if (term.length > 0) {
return items.filter(item => item.conditions.some(cond => cond.field.toLowerCase().indexOf(term) > -1 || (cond.term && cond.term.toLowerCase().indexOf(term) > -1)));
} else {
return items;
}
}),
The problem is that a computed can't (normally) be written back to. The actual drag and drop works (the items appear in a different order in the browser), however, the data original order of the items
doesn't change.
How can I still allow sorting of the original items data set while still allowing filtering?
Ember's computed properties can also be setted. In your case, you need to define your computed by enabling the set function (from this working twiddle) like this:
filteredItems: Ember.computed('items', 'term', {
get(key) {
let term = this.get('term');
let items = this.get('items');
if (term && term.length > 0) {
let filteredItems = items.filter(item => item.name.indexOf(term) > -1);
return filteredItems;
} else {
return items;
}
},
set(key, value) {
let items = this.get('items');
let filteredItemsCount = 0;
let newItems = Ember.makeArray();
items.forEach(function(item, index){
if(value){
if(value && value.indexOf(item) > -1){
newItems[index] = value[filteredItemsCount];
filteredItemsCount++;
}
else{
newItems[index] = items[index];
}
}
else{
newItems[index] = items[index];
}
});
this.set('items', newItems);
return value;
}
})