I’m using the reorderable-repeat (with great success).
I am trying to use a simple filter valueConverter to filter the results, but I’m getting warned
Inner Error:
Message: ValueConverter is not supported in reorderable-repeat
Is there any way to apply a filter to the list?
The filter is nothing more than
export class MachinesFilterValueConverter {
public toView(list: IMachineListItem[], search: string) {
if (!search) {
return list;
}
return list.filter(c => c.name.toLowerCase().includes(search.toLowerCase()));
}
}
1 Like
You want to apply custom sorting to a filtered list, which is basically a snapshot, where the backing data can change at any time, this isn’t a straightforward thing to do in any framework that I know of, because you don’t have a real reference to the list you want to reorder.
I never used reorderable-repeat
, but I’m guessing the plugin modifies the underlying array order as well, therefore you will need to bind to a ‘static’ array reference in order for this to work like you want.
You could achieve this by listening to changes on your original array, using a Collection Observer, and executing your filter when the list changes, populating a new list containing only the filtered values, and using reorderable-repeat
on that list.
If you want to persist the custom ordering of the items when your source array changes, you should also write some logic that applies the custom sorting to the newly filtered list.
A lot of work IMO, might be worth reevaluating this requirement
Perhaps you could hack something together by not really filtering the list but hiding the elements you don’t want to see instead, then you could in theory just bind to your source array. You can’t use if
though, so performance might be an issue
1 Like
Thanks for your thoughts. I hadn’t really thought it through that well…
I’m going with
Blockquote
A lot of work IMO, might be worth reevaluating this requirement
1 Like
You have to ask yourself what’s the expected result of reordering a filtered subarray of an array? I am not sure what exactly you want here.
reorderable-repeat mutates an array, that’s why it needs the original array.
1 Like
I use reorderable-repeat in it’s absolutely simplest form for a single list which the user is able to manually re-order.
On reorderable-after-reordering
it calls
protected orderChanged() {
const sectorAreaIds = this.model.sectorAreaDetails.map(c => c.id);
this.model.sectorAreaIds = sectorAreaIds;
}
or
this.model.sectorAreaDetails.forEach((c,idx)=>{
c.sortOrder = idx;
}
The original list is then saved back to the server with the new sortOrders.
The filtered view does not mutate the original list - it just provides a filtered view of the list
public toView(list: IMachineListItem[], search: string) {
if (!search) {
return list;
}
return list.filter(c => c.name.toLowerCase().includes(search.toLowerCase()));
}
In practice, I have many lists with say 20-30 items which have a sort order which can only be defined by the user. The user can sort the list into the desired order, and then select the required item. To make his life easier he should be able to quickly filter his list to find what he’s looking for
In this list the user needs to sort by Machine Group
in the order as shown in the list. As you can see other than setting a manual sortOrder, I cannot use alphabetical or numeric sorting. The list reflects the movement of products as they flow through a production process. (This particular list will end up growing to some 300 items).
As the list grows, the user should be able to filter by any text on the page, i.e. by sector, sector area or machine group.
I hope this explains my use case.
1 Like
Alternatively use a normal repeater and a sort value converter along with your filter value converter.
I use something like:
export class SortValueConverter {
toView(array, config = {propertyName: 'order', direction: 'ascending', asFloat: false}) {
let factor = config.direction === 'ascending' ? 1 : -1;
if (Array.isArray(array)) {
return array.sort((a, b) => {
if (config.asFloat) {
return (parseFloat(a[config.propertyName]) - parseFloat(b[config.propertyName])) * factor;
} else {
return (a[config.propertyName] - b[config.propertyName]) * factor;
}
});
}
}
}
R
4 Likes
If I understand you correctly, @robertb’s suggestion is correct way to go.
When filter is off, it’s a reorderable-repeat on original list.
When filter is on, it’s a normal repeat on filtered list, without the drag-and-drop UI feature. Remember to remove the UI handler (your bars icon) for drag-and-drop, so that you would not mislead user to reorder the filtered list.
2 Likes
I hadn’t thought of doing that!
Many thanks
2 Likes