Why?
Column Formatting is one of those features that have made SharePoint even easier to improve the user experience. The default Content Approval of SharePoint has been a strong document collaboration functionality for many years now. With the recent release of hover cards in the formatting options, I wanted to combine all these features in a nice example 👍
What?
This post will give an example code of Column Formatting on the default Approval Status column for a SharePoint Site. It will give any column a nice representative icon with a color depending on the Approval Status. We can use any icon from Office UI Fabric Icons! 💪
When hovering over the column, it will show a hover card as a very short timeline:
I even added a final little bonus that if the document is in a Draft status –> the column will act as a button. Pressing this button under this condition, you can start a Power Automate Flow on the selected document 😎.
How?
If needed you can see the needed steps explained more in detail on the Column Formatting documentation page (Column formatting – SharePoint (microsoft.com)). You can also find a lot of examples in the Column Formatting JSON Reference page (Use column formatting to customize SharePoint | Microsoft Docs).
1) First you need to make sure that Content Approval is enabled within the Versioning Settings of the SharePoint Document Library. This will give you the Approval Status column.
2) Secondly you need to add at least two columns to any used View: the Approval Status ([$_ModerationStatus]) column and the Modified ([$Modified]) column. We will use these two columns as dynamic data in our visualization.
3) Finally you can simply copy this code As-Is and paste it in any column present in the view:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "button",
"customRowAction": {
"action": "executeFlow",
"actionParams": "=if([$_ModerationStatus]=='Draft', '{\"id\": \"2100ec15-e270-48c8-8838-cce3183e780b\"}', 'null')"
},
"attributes": {
"class": "ms-fontColor-themePrimary ms-fontColor-themeDarker--hover",
"title": "=if([$_ModerationStatus]=='Draft', 'An Approval Request can be submitted', if([$_ModerationStatus]=='Pending', 'An Approval Request is already submitted','The last Approval Request had the outcome: ' + [$_ModerationStatus]))"
},
"style": {
"border": "none",
"background-color": "transparent",
"cursor": "pointer"
},
"children": [
{
"elmType": "span",
"attributes": {
"iconName": "=if([$_ModerationStatus]=='Draft', 'Flow', if([$_ModerationStatus]=='Pending','WorkFlow','CircleStopSolid')",
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending', 'neutralSecondaryAlt', if([$_ModerationStatus] == 'Approved', 'neutralSecondaryAlt',if([$_ModerationStatus] == 'Rejected', 'red','orange')))"
},
"style": {
"padding-right": "6px"
}
},
{
"elmType": "span",
"txtContent": "=if([$FlowStatus]=='',[$_ModerationStatus],if([$FlowStatus]=='Completed',if([$FlowTrigger]=='Yes','Flow started',[$_ModerationStatus]),if([$_ModerationStatus]=='Draft','To be started',@currentField)))"
}
],
"customCardProps": {
"formatter": {
"elmType": "div",
"children": [
{
"elmType": "div",
"children": [
{
"elmType": "div",
"style": {
"padding": "15px 45px 15px 15px"
},
"children": [
{
"elmType": "div",
"children": [
{
"elmType": "div",
"style": {
"font-size": "18px",
"font-weight": "550",
"text-align": "center",
"margin-bottom": "10px"
},
"txtContent": "Approval Status details"
}
]
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"style": {
"font-size": "16px",
"font-weight": "600",
"padding-left": "15px"
},
"txtContent": " ",
"attributes": {
"iconName": "=if([$_ModerationStatus] == 'Draft', 'StatusCircleQuestionMark',if([$_ModerationStatus] == 'Approved', 'StatusCircleCheckmark',if([$_ModerationStatus] == 'Rejected', 'StatusCircleCheckmark', 'StatusCircleCheckmark')))",
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending', 'green', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'green','neutralSecondaryAlt')))"
}
},
{
"elmType": "span",
"style": {
"font-size": "16px",
"font-weight": "600",
"margin-left": "-16px"
},
"txtContent": " ",
"attributes": {
"iconName": "CircleRing",
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending', 'green', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'green','neutralSecondaryAlt')))"
}
},
{
"elmType": "span",
"style": {
"font-size": "=if([$_ModerationStatus] == 'Draft', '16px', '')",
"font-weight": "=if([$_ModerationStatus] == 'Draft', '600', ''",
"padding-left": "9px"
},
"txtContent": "=if([$_ModerationStatus] == 'Draft', 'Ready to start flow', if([$_ModerationStatus] == 'Pending', 'Flow started',if([$_ModerationStatus] == 'Rejected', 'Flow run','Flow run')))",
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending', 'green', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'green','neutralSecondaryAlt')))"
}
},
{
"elmType": "div",
"style": {
"font-size": "=if([$_ModerationStatus] == 'Draft', '10px', '')",
"font-weight": "=if([$_ModerationStatus] == 'Draft', '600', ''",
"text-align": "center",
"border-left-style": "solid",
"border-left-color": "='ms-borderColor-' + if([$_ModerationStatus] == 'Draft', 'neutralSecondaryAlt', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'green','neutralSecondaryAlt')))",
"margin-left": "21px"
},
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Draft', 'neutralSecondaryAlt', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'green','neutralSecondaryAlt')))"
},
"txtContent": "=if([$_ModerationStatus] == 'Draft', 'This could be now', if([$_ModerationStatus] == 'Approved', '',if([$_ModerationStatus] == 'Rejected', '','')))"
}
]
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"style": {
"border-left-style": "solid",
"border-left-color": "='ms-borderColor-' + if([$_ModerationStatus] == 'Pending','green',if([$_ModerationStatus] == 'Approved','green',if([$_ModerationStatus] == 'Rejected','green','neutralSecondaryAlt')))",
"text-align": "center",
"margin-left": "21px"
},
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending','green',if([$_ModerationStatus] == 'Approved','green',if([$_ModerationStatus] == 'Rejected','green','neutralSecondaryAlt')))"
}
}
]
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"style": {
"font-size": "16px",
"font-weight": "600",
"padding-left": "15px"
},
"txtContent": " ",
"attributes": {
"iconName": "=if([$_ModerationStatus] == 'Pending', 'StatusCircleQuestionMark',if([$_ModerationStatus] == 'Approved', 'StatusCircleCheckmark',if([$_ModerationStatus] == 'Rejected', 'StatusCircleCheckmark', 'CircleRing')))",
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending','orange',if([$_ModerationStatus] == 'Approved','green',if([$_ModerationStatus] == 'Rejected','green','neutralSecondaryAlt')))"
}
},
{
"elmType": "span",
"style": {
"font-size": "16px",
"font-weight": "600",
"margin-left": "-16px"
},
"txtContent": " ",
"attributes": {
"iconName": "CircleRing",
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending','orange',if([$_ModerationStatus] == 'Approved','green',if([$_ModerationStatus] == 'Rejected','green','neutralSecondaryAlt')))"
}
},
{
"elmType": "span",
"style": {
"font-size": "=if([$_ModerationStatus] == 'Pending', '16px', ''",
"font-weight": "=if([$_ModerationStatus] == 'Pending', '600', ''",
"padding-left": "9px"
},
"txtContent": "=if([$_ModerationStatus] == 'Pending','Pending',if([$_ModerationStatus] == 'Approved','Assessed',if([$_ModerationStatus] == 'Rejected','Assessed','To be assessed')))",
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending','orange',if([$_ModerationStatus] == 'Approved','green',if([$_ModerationStatus] == 'Rejected','green','neutralSecondaryAlt')))"
}
},
{
"elmType": "div",
"style": {
"font-size": "10px",
"font-weight": "600",
"text-align": "center",
"border-left-style": "solid",
"border-left-color": "='ms-borderColor-' + if([$_ModerationStatus] == 'Pending', 'neutralSecondaryAlt', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))",
"margin-left": "21px"
},
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Pending', 'neutralSecondaryAlt', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))"
},
"txtContent": "=if([$_ModerationStatus] == 'Pending', ' since ' +toLocaleDateString([$Modified]), if([$_ModerationStatus] == 'Approved', '',if([$_ModerationStatus] == 'Rejected', '','')))"
}
]
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"style": {
"border-left-style": "solid",
"border-left-color": "='ms-borderColor-' + if([$_ModerationStatus] == 'neutralSecondaryAlt', 'Outcome', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))",
"margin-left": "21px"
},
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'neutralSecondaryAlt', 'Outcome', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))"
}
}
]
},
{
"elmType": "div",
"children": [
{
"elmType": "span",
"style": {
"font-size": "16px",
"font-weight": "600",
"padding-left": "15px"
},
"txtContent": " ",
"attributes": {
"iconName": "=if([$_ModerationStatus]== 'Approved', 'StatusCircleCheckmark', if([$_ModerationStatus]== 'Rejected', 'Cancel','CircleRing'))",
"class": "='ms-fontColor-' +if([$_ModerationStatus] == 'neutralSecondaryAlt', 'Outcome', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))"
}
},
{
"elmType": "span",
"style": {
"font-size": "16px",
"font-weight": "600",
"margin-left": "-16px"
},
"txtContent": " ",
"attributes": {
"iconName": "CircleRing",
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'neutralSecondaryAlt', 'Outcome', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))"
}
},
{
"elmType": "span",
"style": {
"font-size": "=if([$_ModerationStatus] == 'Approved', '16px', if([$_ModerationStatus] == 'Rejected', '16px',''))",
"font-weight": "=if([$_ModerationStatus] == 'Approved', '600', if([$_ModerationStatus] == 'Rejected', '600',''))",
"padding-left": "9px"
},
"txtContent": "=if([$_ModerationStatus] == 'Draft', 'Outcome', if([$_ModerationStatus] == 'Approved', 'Approved',if([$_ModerationStatus] == 'Rejected', 'Rejected','Outcome')))",
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'neutralSecondaryAlt', 'Outcome', if([$_ModerationStatus] == 'Approved', 'green',if([$_ModerationStatus] == 'Rejected', 'red','neutralSecondaryAlt')))"
}
},
{
"elmType": "div",
"style": {
"font-size": "10px",
"font-weight": "600",
"text-align": "center",
"margin-left": "21px"
},
"attributes": {
"class": "='ms-fontColor-' + if([$_ModerationStatus] == 'Approved', 'black', 'black')"
},
"txtContent": "=if([$_ModerationStatus] == 'Pending', '', if([$_ModerationStatus] == 'Approved', ' on ' + toLocaleDateString([$Modified]),if([$_ModerationStatus] == 'Rejected', ' on ' + toLocaleDateString([$Modified]),'')))"
}
]
}
]
}
]
}
]
},
"openOnEvent": "hover",
"directionalHint": "bottomCenter",
"isBeakVisible": true
}
}
Please note that the Column Formatting code is referencing the SharePoint Approval Status values by language specific translations: in my case English. At the moment we need to have a language specific setup. Should you need a different language, you can just Find & Replace the English terminology and it should work the same.
The part:
"customRowAction": {
"action": "executeFlow",
"actionParams": "=if([$_ModerationStatus]=='Draft', '{\"id\": \"2100ec15-e270-48c8-8838-cce3183e780b\"}', 'null')"
},
is where you can use the GUID of your own flow to start that specific flow on the selected document. Just change the id to the id of your own flow and it will open up the right side panel to start the flow. If you do not want to use the Power Automate Flow part, you can simply remove this small part from the code without breaking it. More details on this Power Automate Flow integration with SharePoint Column Formatting check out: Advanced formatting concepts | Microsoft Learn.
Is it possible to do it without enabling content approval? Thing is that I created power automate workflow without this versioning stuff and but I need this column formatting to be on my sharepoint library.
Thanks
Definitely possible but then this example will not work.
You would need to create your own formatting for your own scenario. The links above should help!
That is great!
But this magic button doesnt work for me. I replaced the id with my PowerAutomate App but nothing happens
“Pressing this button under this condition, you can start a Power Automate Flow on the selected document”
Hi Lukasz, did you see that there is a condition in my example?
To verify you can check out the link, I just added about near the specific customRowAction snippet.
Also make sure you use the GUID of the Power Automate Flow.
Is there a way to add more details to the hover card? Like the approvers name and or any comments??
Definitely! See the reference page mentioned above to see all kind of examples.
In your case you just need to make sure that you have an Approver Column and a Comments Column so you can incorporate this in the Hover Card part.
Thank you this makes the approval status column looks professional!