UI5ers Buzz #26: Client-side sorting using custom comparator
There will be times that a simple sorting of items (i.e. according to size or alphabetical) is not sufficient, but rather a specific logic is required to achieve the desired result. In addition, when the data used is taken from an external service provider, the great load of work remains on the front-end developer. Again. But hey, it might be fun 🙂
So, sleeves up and explore how client-side sorting works in UI5!
Let’s say we have a data model containing an array of records with gas station information and we want to sort this list based on our current location to find the nearest gas station
To illustrate it in code, step-by-step, we start with defining a simple table displaying the gas station information (City, Street, Company Name and Position given as Longitude and Latitude coordinates) in a XML view.
Now let’s see how to define a custom sorter for the table:
Sorting capabilities come with a model implementation and can be used with list binding. To understand how this works in detail we have a quick glimpse on the API documentation for sap.ui.model.Sorter. There we can read that the constructor of the sorter has four import parameters:
- sPath is a mandatory parameter for defining a sorter and of type string. It determines the binding path to the value in the model that shall be used for the sorting.
In our case this is Position.
- bDescending is optional and of type Boolean. By default it sorts in ascending order, which is fine for us.
- vGroup is optional and can be either of type Boolean or a function. Set to true the grouping is based on the raw model property value defined in sPath. In case a function is provided, the group value can be calculated out of the context independently.
For today, we will skip this part but concentrate on the next parameter.
- fnComparator is optional and allows to define a custom comparator function. It can be used for client-side sorting and overwrites the default comparator methods.
Here we are, this is what we need!
Thus, we must define a custom comparator function and as we are working according to MVC, it has to be implemented in the controller of the view. But how does this comparator function need to look like? This can be derived from the default comparator method sap.ui.model.Sorter.defaultComparator: the comparator gets two values (a and b) and compares them. Depending on the order of the two items it returns the value -1 (a smaller than b), 0 (a equal b) or 1 (a larger than b).
We want to sort our list on distance to the closest gas station starting from a certain point. Value Position includes information about longitude and latitude for a gas station. So we can extract those two coordinates from the position, get the current position, and calculate the distance according to the formula distance:=√(x2-x1)2+(y2-y1)2.
Putting this all together into code our comparator function is as follow:
And finally, we can define the sorter in the list binding of our table in the XML view, which then becomes:
Hope you had fun reading this!
Previous Post: UI5ers Buzz #25
Arnd & Margot
|Arnd is an Expert Developer at SAP. He discovered the art of programming on pocket calculators, legacy home computers and game consoles. Today his focus is mainly on Web development technologies and UI5.|
|Margot is Product Manager for SAP UI technologies and UI5 in particular. She stands up for the developers interests and loves to work with the community to make UI5 one of the best JS frameworks ever. If time is left, Margot enjoys rolling up her sleeves and do all sorts of handicraft work. Another passion of her is traveling to remote parts of the world.|
Hi Arnd & Margot,
Thanks for the post!
Following your guide, I tried to implement a custom comparator. However, the function is never called. Strange: A custom group function works just as expected. (SAPUI5 1.54.4)
Could you provide a minimal working example?
Strange ... did you do it like in the screen shot shown? Do you have some code snippet to see what you tried?
I and was able to create a minimun working example:
In my real app I don't use a local JSON model, instead it's OData. And I forgot to add
I tried to implement a custom comparator. however the custom comparator function was never called
please find the code snippets below
Below is comparator within respective controller
NOTE: custom group functions are getting called and executed as expected
Any help would be highly appreciated, thanks in advance
Hello, Margot Wollny and Arnd vom Hofe ,
Thank you for this great and detailed explanation.
It just helped me to learn how to fix a problem with a UI5 app for my customer.
Looking forward to meeting you at UI5Con!