By using list formatting, we can customise SharePoint view group headers in a similar way as we would do with the view rows or fields.
How to get started customising group headers
To customise the group headers, we need to use list formatting in the same way we would do for the view content, but in this case, we should use the ‘groupProps’ property of the view JSON template and child element ‘headerFormatter‘ to generate our custom group header.
There are a few properties/values that are present on the @group object you can take advantage of when building group header formatters:
@group.columnDisplayName: Use it to show the name of the column in the header. For example, if you build the formatter using this special property, it will display the current group field name, but if you change the field used to group the items, it will adjust automatically to the new field. The field needs to be added to the view for it to work properly.
@group.count: Returns the item count. This can be used on formulas to display different text according to the number of items.
@group.fieldData: This brings the grouped field data. If the grouping is on items with blank values, it will always return ‘Unassigned‘ as a value.
If it’s a simple value as text/number/date the value is returned directly on this property, however, for people fields, as they are returned as objects and have more properties available, it’s possible to access more data as related properties in the JSON template (ex: email, department, jobTitle) as in the sample below for the person field used as the group:
Listing additional people fields properties
In the example below for a Person field, not only the user name is displayed but it’s also displaying the users’ email, department and job title:
Properties used:
- @group.fieldData.title: Returns the primary value of the person field – keep in mind that for the related properties to work properly, you should use as the primary value for the person field either ‘Name (with Presence)‘ or ‘Name (with picture and details)‘
- @group.fieldData.email: Returns the user’s email
- @group.fieldData.jobTitle: Returns the user’s job title (if available)
- @group.fieldData.department: Returns the user’s department (if available)
Using the people additional properties sample
To use this sample, create a list view grouped by a person field, and add this person field to the View. Use the option ‘Format Current View / Advanced mode’ to apply the following JSON format to the view:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json",
"groupProps": {
"headerFormatter": {
"elmType": "div",
"style": {
"display": "inline-flex",
"align-items": "flex-end",
"height": "25px",
"padding-left": "8px",
"padding-top": "5px",
"padding-bottom": "5px",
"border-radius": "10px"
},
"attributes": {
"class": "ms-bgColor-themeLighter"
},
"children": [
{
"elmType": "div",
"txtContent": "=@group.columnDisplayName + ':' ",
"children": [
{
"elmType": "span"
}
],
"style": {
"padding-right": "9px",
"padding-bottom": "3px"
},
"attributes": {
"class": "ms-fontWeight-bold"
}
},
{
"elmType": "img",
"attributes": {
"src": "=getUserImage(@group.fieldData.email, 'small')",
"title": "@group.fieldData.title"
},
"style": {
"width": "25px",
"height": "25px",
"border-radius": "50%"
}
},
{
"elmType": "div",
"style": {
"display": "inline-flex",
"padding-right": "9px",
"padding-bottom": "3px"
},
"children": [
{
"elmType": "span",
"txtContent": "=@group.fieldData.title",
"attributes": {
"title": "=@group.fieldData.title",
"class": "ms-fontWeight-semibold"
},
"style": {
"padding-left": "5px"
}
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"attributes": {
"iconName": "Mail"
},
"style": {
"padding-left": "10px",
"padding-top": "3px"
}
},
{
"elmType": "span",
"txtContent": "=@group.fieldData.email",
"style": {
"padding-left": "5px"
},
"attributes": {
"title": "=@group.fieldData.email"
}
}
],
"style": {
"display": "=if(@group.fieldData.email == '' || @group.fieldData.email == 'Unassigned' ,'none','inherit')"
}
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"attributes": {
"iconName": "Work"
},
"style": {
"padding-left": "10px",
"padding-top": "3px"
}
},
{
"elmType": "span",
"txtContent": "=@group.fieldData.jobTitle",
"style": {
"padding-left": "5px"
},
"attributes": {
"title": "=@group.fieldData.jobTitle"
}
}
],
"style": {
"display": "=if(@group.fieldData.jobTitle == '' || @group.fieldData.jobTitle == 'Unassigned','none','inherit')"
}
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"attributes": {
"iconName": "WorkforceManagement"
},
"style": {
"padding-left": "10px",
"padding-top": "3px"
}
},
{
"elmType": "span",
"txtContent": "=@group.fieldData.department",
"style": {
"padding-left": "5px"
},
"attributes": {
"title": "=@group.fieldData.department"
}
}
],
"style": {
"display": "=if(@group.fieldData.department == '' || @group.fieldData.department == 'Unassigned','none','inherit')"
}
},
{
"elmType": "span",
"style": {
"padding-left": "5px"
},
"attributes": {
"class": "ms-fontWeight-bold"
},
"txtContent": "='(' + @group.count +')'"
}
]
}
]
}
}
}
Note that this sample only displays the additional properties when they are present, the logic on it will hide the elements when the properties are not available.
Conclusion
By using list formatting JSON it’s possible to create custom experiences to display group data and its additional properties and also optionally include custom conditional logic based on those values.
Additional References:
List of Fluent UI icons: Fluent UI Icons Tool
List of Reusable SharePoint CSS classes: https://zerg00s.github.io/sp-modern-classes/
Hi Michel,
Have you tried to create a formatted group – but the grouping uses values from a column formatting (JSON that sets the values – in other words, the view is not grouped from values in the column). Is this even possible?
Thanks in advance,
Dan
Hi Daniel,
It would not be possible to group based in custom values generated by a list formatting JSON.
What is the custom value you are trying to achieve? Maybe a calculated field can help you achieve that without JSON.