I am using a sap.m.List
control in my application that is supposed to show a sequential list. There is a grouping property in each list data that I can use to group similar items together.
I checked this example on the SAP Explored website on list grouping. It uses a sorter
property that has group
set to true
. By default the sorting mode is descending.
However my list has to show the items in a predefined sequence with just similar items grouped together for ease of use. All items in a group occur at one place in the list and a particular group occurs only once. For example, I have to bind the JSON array below to a list in the same order as it is, only grouped by Category
.
steps.json:
{
"Steps": [
{
"Desc": "Open google search",
"Category": "Google"
},
{
"Desc": "Search for Apple Inc.",
"Category": "Google"
},
{
"Desc": "Open Apple website",
"Category": "Apple"
},
{
"Desc": "Search for iPhone",
"Category": "Apple"
},
{
"Desc": "Browse all iPhone models",
"Category": "Phone"
},
{
"Desc": "Choose the one you like",
"Category": "Phone"
}
]
}
The code below is what I would like to do in order to get going except it sorts my list in descending order.
SAPUI5 code:
<List
items="{
path: '/Steps',
sorter: {
path: 'Category',
group: true
}
}"
headerText="Here's what you do">
<StandardListItem title="{Desc}" />
</List>
Is there a way to achieve this?
Thanks.
3rd parameter of the Sorter can be a function which gets the context as a parameter.
API : https://openui5.hana.ondemand.com/#docs/api/symbols/sap.ui.model.Sorter.html
Sample : http://jsbin.com/votesatezu/1/edit?html,js,output
I got a way to resolve my problem. It's similar to the answer provided here but doesn't require to create a Sorter instance in the controller (so saves you from additional coding).
XML view:
<List
items="{
path: '/Steps',
sorter: {
path: 'CategoryId',
group: '.grouper'
},
groupHeaderFactory: '.getGroupHeader'
}"
headerText="Here's what you do">
<StandardListItem title="{Desc}" />
</List>
Instead of passing a boolean, I call a grouper
method in the group
property to build a custom object for groupHeaderFactory
.
Controller:
onInit: function() {
var oModel = new sap.ui.model.json.JSONModel({
"Steps": [
{
"Desc": "Open google search",
"Category": "Google",
"CategoryId": 1
},
{
"Desc": "Search for Apple Inc.",
"Category": "Google",
"CategoryId": 1
},
{
"Desc": "Open Apple website",
"Category": "Apple",
"CategoryId": 2
},
{
"Desc": "Search for iPhone",
"Category": "Apple",
"CategoryId": 2
},
{
"Desc": "Browse all iPhone models",
"Category": "Phone",
"CategoryId": 3
},
{
"Desc": "Choose the one you like",
"Category": "Phone",
"CategoryId": 3
}
]
});
this.getView().setModel(oModel);
}
grouper():
The oGroup object provides the complete model along with the binding path for each row. The binding path is stored in a property called sPath
. I can get the array index from the sPath
and then use it to get the corresponding Category
name.
grouper: function(oGroup) {
return {
key: oGroup.oModel.oData.Steps[oGroup.sPath.split("/")[2]].Category
};
}
Now when the groupHeaderFactory
is called it has the Category
name instead of the CategoryId
.
getGroupHeader():
getGroupHeader: function(oGroup){
return new sap.m.GroupHeaderListItem( {
title: oGroup.key,
upperCase: true
});
}
Note: Make sure you have data-sap-ui-compatVersion="edge"
in your index.html
if you want to try out this example.
Yippee!
You are adding some implicit meta data to your json file which is a custom sort on the category.
The sapui5 list item cannot guess that you have created such a constraint on your data :) I would advice you to simply enrich your model to:
{
"Steps": [
{
"Desc": "Open google search",
"Category": "Google",
"CategoryId": 1
},
{
"Desc": "Search for Apple Inc.",
"Category": "Google",
"CategoryId": 1
},
{
"Desc": "Open Apple website",
"Category": "Apple",
"CategoryId": 2
},
{
"Desc": "Search for iPhone",
"Category": "Apple",
"CategoryId": 2
},
{
"Desc": "Browse all iPhone models",
"Category": "Phone",
"CategoryId": 3
},
{
"Desc": "Choose the one you like",
"Category": "Phone",
"CategoryId": 3
}
]
}
Then group on categoryId instead of category.