Components from Components - Dynamic List Sorter
Bear with me this one is a little longer than normal.
The component will automatically get each header from a list, which then can be moved to create a sort order. This sort order is then applied to the original list.
List
|
SortOrder
|
Sorted List
|
To start we need to create a collection of the headers that we will use in the sort component (normally on the OnStart/OnVisible).
//Hide Sort Popup
Set(vbShowSort,false);
//Get SharePoint list
ClearCollect(colTeams,ShowColumns(Staff,Name,Active,Role));
//Get Headers
Set(vcHeaders,
ColumnNames(
ParseJSON(JSON(First(colTeams)))
)
);
//Coy headers to collection with direction and order field
Clear(colHeaders);
ForAll(Sequence(CountRows(vcHeaders)),
Collect(colHeaders,{
Header:Index(vcHeaders.Value,ThisRecord.Value).Value,
Direction:SortOrder.Ascending,
Order:ThisRecord.Value,
ID:1
})
);
The ColumnNames expression only works in untyped objects, so we have to untype it by stringfying it and then parseing it back. We also need to add 2 extra fields, the sort order (so we can set if it ascends or descends) and a order field (so that we can sort the collection in the order we want it).
The Sort popup is a gallery that uses the colHeaders collection, it has the header as the label and 3 buttons:
Direction
This changes on click and Patches colHeaders directions:
Icon
If(ThisItem.Direction=SortOrder.Ascending,Icon.ArrowUp,Icon.ArrowDown)
OnSelect
If(ThisItem.Direction=SortOrder.Ascending,
Patch(colHeaders,ThisItem,{Direction:SortOrder.Descending})
,
Patch(colHeaders,ThisItem,{Direction:SortOrder.Ascending})
)
Move Up
The move up swaps the items Order number with the Item below/after it.
OnSelect
ClearCollect(colHeaders,SortByColumns(colHeaders,"Order"));
Patch(colHeaders,
If(Self.Visible,
Index(colHeaders,ThisItem.Order-1)
,
First(colHeaders)
)
,
{Order:ThisItem.Order}
);
Patch(colHeaders,ThisItem,
{Order:ThisItem.Order-1}
)
The visibility is set to false if it's the first.
Move Down
Move down does the opposite, and swaps it with the item above/before.
OnSelect
ClearCollect(colHeaders,SortByColumns(colHeaders,"Order"));
Patch(colHeaders,Index(colHeaders,ThisItem.Order+1),
{Order:ThisItem.Order}
);
Patch(colHeaders,ThisItem,
{Order:ThisItem.Order+1}
)
The visibility is set to false if its the last.
Now for the clever bit, how do we sort by the colHeaders collection. As the ForAll expression does not allow setting variables or sorting collections we have to use the select function trick. The trick is to move the collection sorting to a button, which we press to run the code. We then use a counter variable to increment over the colHeaders (in reverse so the last sort is the priority sort).
//reset counter for the buSort function
Set(viCounter,1);
//loop over headers in reverse order
ClearCollect(colHeaders,Sort(colHeaders,Order,SortOrder.Descending));
ForAll(colHeaders,
//use select to trigger code that can't run in a ForAll
Select(buSort);
);
//close popup
Set(vbShowSort,false);
Then on a invisible button called buSort we have:
ClearCollect(colTeams,
SortByColumns(colTeams,
Index(colHeaders,viCounter).Header
,
Index(colHeaders,viCounter).Direction
)
);
Set(viCounter,viCounter+1);
And that's it, you can now dynamically sort any collection, you can do something similar with filters too. A copy of the solution is attached.
>--------------------------------------------
This is a series of short blogs designed to help create new components from existing components, keep your eyes out for more
Stacked Notification Toasts
l also do long form and broader Power Platform blogs here https://dev.to/wyattdave
*This post is locked for comments