Quick SharePoint Approvals using list formatting JSON to set field values

This week it came to attention two new possible actions to buttons created using list formatting:

  • setValue: Updates a field value
  • openContextMenu: Displays the default context menu for the list item

With the first one, we can update the values of any field in the list item. And update multiple field values with a single click. 

Not only this but we can use dynamic values and do calculations using the JSON formatting formulas, for example, we could increment/decrement a number value by clicking a custom button created with JSON formatting. 

With that in mind, after seeing some samples on Twitter published by @techan_k, I thought this could be useful for approvals scenarios. For example, we can update the item status and who approved the item with a single click, so as in the example below:

The structure behind the example

Three list columns are needed:

  • A Choice column for the status (Suggested name: ‘Item Status’), with the possible values: Pending, Approved, Rejected. The standard configurable formatting for the Choice column can do the trick as below:
  • A user field to register who approved or rejected the item (Suggested name ‘Approval Action By’)
  • A dummy field to add the JSON template and display the buttons separately. The suggestion is to add a calculated field named ‘Approval‘.

The logic behind the sample

To make the functionality cleaner, the buttons would need to be displayed only when the items have not been approved. So we simply set the CSS display property to ‘none‘ when the status is not empty and is different than ‘Pending‘. And display a text message stating that the item was already approved or rejected.

On each button, we set as the customRowAction, an action using the new setField action, and pass two fields on each by using their internal names. Note that to set the current user as the value, we simply pass the @me formula.

Approval:

"customRowAction": {
              "action": "setValue",
              "actionInput": {
                "ItemStatus": "Approved",
                "ApprovalActionBy": "@me"
              }
}

Rejection:

"customRowAction": {
              "action": "setValue",
              "actionInput": {
                "ItemStatus": "Rejected",
                "ApprovalActionBy": "@me"
              }
}

Full sample

To add this to any SharePoint list, create the columns as stated above, and add the following JSON template to the Approval field (resize it to get the buttons to be displayed horizontally/vertically as you wish). Tweak the internal names as needed in case your list uses different field names:

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
  "elmType": "div",
  "style": {
    "flex-directon": "row",
    "justify-content": "left",
    "align-items": "center",
    "flex-wrap": "nowrap"
  },
  "children": [
    {
      "elmType": "div",
      "style": {
        "display": "=if([$ItemStatus] == 'Pending' || [$ItemStatus] == '', 'inherit','none')",
        "flex-directon": "row",
        "justify-content": "left",
        "align-items": "center",
        "flex-wrap": "wrap"
      },
      "children": [
        {
          "elmType": "button",
          "customRowAction": {
            "action": "setValue",
            "actionInput": {
              "ItemStatus": "Approved",
              "ApprovalActionBy": "@me"
            }
          },
          "attributes": {
            "class": "ms-fontColor-themePrimary ms-fontColor-themeDarker--hover"
          },
          "style": {
            "border": "none",
            "background-color": "transparent",
            "cursor": "pointer",
            "display": "flex",
            "flex-directon": "row",
            "justify-content": "left",
            "align-items": "center",
            "flex-wrap": "wrap"
          },
          "children": [
            {
              "elmType": "span",
              "attributes": {
                "iconName": "SkypeCircleCheck"
              },
              "style": {
                "padding": "4px"
              }
            },
            {
              "elmType": "span",
              "txtContent": "Approve",
              "style": {
                "word-break": "keep-all"
              }
            }
          ]
        },
        {
          "elmType": "button",
          "customRowAction": {
            "action": "setValue",
            "actionInput": {
              "ItemStatus": "Rejected",
              "ApprovalActionBy": "@me"
            }
          },
          "attributes": {
            "class": "ms-fontColor-themePrimary ms-fontColor-themeDarker--hover"
          },
          "style": {
            "border": "none",
            "background-color": "transparent",
            "cursor": "pointer",
            "display": "flex",
            "flex-directon": "row",
            "justify-content": "left",
            "align-items": "center",
            "flex-wrap": "wrap"
          },
          "children": [
            {
              "elmType": "span",
              "attributes": {
                "iconName": "Blocked"
              },
              "style": {
                "padding": "4px"
              }
            },
            {
              "elmType": "span",
              "txtContent": "Reject",
              "style": {
                "word-break": "keep-all"
              }
            }
          ]
        }
      ]
    },
    {
      "elmType": "div",
      "children": [
        {
          "elmType": "span",
          "txtContent": "='This item is ' + toLowerCase([$ItemStatus])",
          "style": {
            "display": "=if([$ItemStatus] == 'Pending' ||[$ItemStatus] == '' , 'none','inherit')",
            "padding-left": "5px",
            "word-break": "keep-all"
          }
        }
      ]
    }
  ]
}

Conclusion

By using list formatting and the new setValue action, we can now update field values, expanding a lot the possibilities of what can be done in SharePoint/Microsoft Lists without the need of the SharePoint Framework field customizers or other techniques (calling a Flow for example). This example is just a simple one to show how to update two fields at the same time and use the native formulas as values, but the possibilities now have expanded massively.

Note: For this approach to work correctly, all fields used in the JSON template need to be added to the list view where the custom buttons will be added.

34 comments

  1. Great post!
    I’m tried and worked for me following your instructions. Now I’ll try to add the approval/denial date to the list.

    Thank you!

    1. I think so as it is on the official documentation. Also, I’ve just tried it on a tenant using Standard Release and it works fine. What error do you get?

  2. Hi Michel,

    I tried using your solution for a multiuser approval, also adding the possibility via a second button to delete the choice done by the user and return to Approve/reject status. The only issue I am finding is that using the operation “removeFrom” I am not able to remove the @me from the user array. Any thoughts?

    Thanks for this magnificent use case.

    Thank you,
    Davide

  3. Hi,
    When the item is “Rejected”, is it possible to show the comments field to put some description which is required field?. Please let me know this can be accomplish?

  4. Hi Michel,
    Please. help with issue below.
    After I click Approved or Rejected – only one fileld is changing: ApprovalActionBy.
    Other fields are not changing.
    Any suggestions?

  5. Hi Michel,

    Thank you for the awesome post.

    I managed to make it in the list view. and also tried it a gallery view. However the buttons no longer work.

    Could you please advise? Thank you.

  6. What is the approval calculated off of? I am confused as I left the formula blank and SPO will not allow it be blank…Do I need to create an approval and rejection column…?

    1. It’s a dummy calculated column only to show the buttons (and not to be displayed in edit forms).
      You can add it with a simple formula as: = “APPROVAL”, just to be able to add it, and then it will be used only to render the buttons.

  7. Hello!
    Short question:
    Where do I have to insert your Code?
    In the Formula of the Column “Approval” or in the Column Formatting?
    This function would really help us in the project!

    Thank you!

    1. its working now! One more question: if I open the List in my app I can’t click on approved or rejected.
      Is there a way to implement the same function in the app?

      Thank you!!

    2. Hi Max, you have to add the code to the Column formatting, not to the formula…
      In the formula value you can add any dummy value as it will be hidden by the JSON formatting…

  8. Hello Nice Work!! Can we do something like this for content approval for submitted items? Like have a button to approve or reject the item? or to popup the form to approved or reject the item?

    Thank you in advanced

    1. Hi Obed, yes you can…This is sample is just to demonstrate the capability, but you can use different statuses…
      And also you can add a button to open the item in a Form…what do you need to do exactly?

  9. This has the potential to solve a huge problem for me! Buttons are available and my approved by column is populating correctly. However, I am unable to get the choices in the Item Status column to appear and when I select approve/reject, the text message does not populate. I think this may be because I have not set the customRowAction for Approve/Reject? Can you clarify where that code should be inserted?

    1. Hi Melissa, not sure if I understood your problem…You need to use the customRowAction, otherwise nothing will happen (field is not updated)…How did you use the JSON template exactly?

  10. Does it have to use a button? What if I wanted it to just update a column based on a value that already exists in another column? Thx

    1. Do you mean when you change a value in this column update another? If so you would need to use a custom form built with Power Apps or a Power Automate flow. The setValue option in list formating works when called from clicks on custom elements in the view/button formatter.

  11. How do you change an Items Status from Approved to Rejected or Back to Pending once the approval button has been already been selected. Example, I am the approver and after selecting Approved I realize that I need to reject instead and now I want to change the status to rejected. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *