Add an Icon Progress Bar to Microsoft Lists

I am always inspired by the JSON column formatting samples available on the PnP List-Formatting GitHub repository. I recently came across Icon Progress Bar by Julien Seguin and immediately knew that this would be a great addition to one of my daily use Lists.

The Icon Progress Bar sample uses a numeric value to indicate its progression towards completion. For my purposes I want the same functionality but to be driven by status values (Complete, In progress etc.) in the multiple columns that represent the major milestones in the process that I am tracking. This approach requires that the major milestones are manually specified (aka hard-coded) in the column formatting.

My demo List includes the following columns and looks like the image below.

NameTypePurpose
TitleSingle line of textProcess entry that we are tracking
ProgressNumberShow the Icon Progress Bar
Milestone 1Choice with options: “Complete” and “In progress”Significant step in the process
Milestone 2Choice with options: “Complete” and “In progress” Significant step in the process
Milestone 3Choice with options: “Complete” and “In progress” Significant step in the process
Milestone 4Choice with options: “Complete” and “In progress” Significant step in the process
Milestone 5Choice with options: “Complete” and “In progress” Significant step in the process
Demo  list

The number-icon-progressbar.json code uses the @currentField variable to evaluate the stored numeric value. Our approach replaces @currentField with the major milestone columns and instead of evaluating numeric values we are evaluating Choice column values.

Code sample

Here is my sample code:

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
  "elmType": "div",
  "style": {
    "font-size": "16px"
  },
  "children": [
    {
      "elmType": "span",
      "attributes": {
        "title": "Milestone 1",
        "iconName": "=if([$Milestone1] == '', 'CircleRing', 'SkypeCircleCheck')",
        "class": "='ms-fontColor-' + if([$Milestone1] == 'Complete', 'neutral', 'neutralLight')"
      },
      "style": {
        "padding": "0 2px"
      }
    },
    {
      "elmType": "span",
      "attributes": {
        "title": "Milestone 2",
        "iconName": "=if([$Milestone2] == '', 'CircleRing', 'SkypeCircleCheck')",
        "class": "='ms-fontColor-' + if([$Milestone2] == 'Complete', 'neutral', 'neutralLight')"
      },
      "style": {
        "padding": "0 2px"
      }
    },
    {
      "elmType": "span",
      "attributes": {
        "title": "Milestone 3",
        "iconName": "=if([$Milestone3] == '', 'CircleRing', 'SkypeCircleCheck')",
        "class": "='ms-fontColor-' + if([$Milestone3] == 'Complete', 'neutral', 'neutralLight')"
      },
      "style": {
        "padding": "0 2px"
      }
    },
    {
      "elmType": "span",
      "attributes": {
        "title": "Milestone 4",
        "iconName": "=if([$Milestone4] == '', 'CircleRing', 'SkypeCircleCheck')",
        "class": "='ms-fontColor-' + if([$Milestone4] == 'Complete', 'neutral', 'neutralLight')"
      },
      "style": {
        "padding": "0 2px"
      }
    },
    {
      "elmType": "span",
      "attributes": {
        "title": "Milestone 5",
        "iconName": "=if([$Milestone5] == '', 'CircleRing', 'SkypeCircleCheck')",
        "class": "='ms-fontColor-' + if([$Milestone5] == 'Complete', 'neutral', 'neutralLight')"
      },
      "style": {
        "padding": "0 2px"
      }
    }
  ]
}

If you attempt to replicate this column formatting be sure to update the highlighted sections below for each major milestone column in your list.

A) title is the column name that will display on icon mouse-over.

B) iconName controls the icon used. The if statement checks for empty values in the milestone column. If the column is blank the icon will be CircleRing otherwise it will be SkypeCircleCheck.

C) class controls the color used with the icon. The if statement checks if the milestone column value is Complete, and if so sets the icon color to neutral otherwise it will be neutralLight.

My update code snippet.

You should notice in my updated code that there is child section for each major milestone column that I want to track. The column names in the code must match the internal column names within the list. You can find the internal column name by editing each column from within List Settings. The internal name is shown in the URL path.

Internal column name

To apply the column formatting:

  • select Column settings and then click Format this column.
Format this column
  • Click Advanced mode.
Advanced mode
  • Replace the existing JSON code with our updated code and then click Preview to confirm functionality and then Save to complete the update.
Updated JSON

If all goes well your Progress column should like the image below.

Progress icon!

I was drawn to the Icon Progress Bar sample because it can easily convey current state information for my users without them having to scroll through the entire list to figure where things stand. I can follow the original code well enough to make changes but I would never consider myself a developer so I am grateful to Microsoft Tech Community members like Julien Seguin for sharing the good work that they do. #SharingIsCaring

I hope this column formatting sample inspires you as much as it did for me and be sure to check out the PnP List-Formatting GitHub repository

Thanks for reading!

NY

8 thoughts on “Add an Icon Progress Bar to Microsoft Lists

  1. great post! I was struggling trying to figure something like this out. so in your code, as well as mine even more I see there are repetitive if statements. is there a way to consolidate them…
    “iconName”: “=if([$Milestone4] == ‘Complete’, ‘SkypeCircleCheck’, ‘CircleRing’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone4] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    in this mock up the if statements repeat. Is there a way to do one if statement and the result of that provide the output to iconName and class?
    thanks again!

    Like

    1. Hi cookieking2021,

      I couldn’t find anything that would indicate that it is possible. If it were I would not have used it because the processes I tend to track have multiple metadata columns that don’t necessarily reflect milestones in the process. I believe there is always going to be an element of hard-coding of the process in the formatting.

      Thanks for reading!

      NY

      Like

  2. Hi first of all great code!
    However I have an issue that I cannot solve, I have used your code and added two new milestones by coping your code. But for some reason I cannot make the last two process indicators work. I can see that the milestones 5+6 have been added and that two circles has been added to the progress line. But no matter what I add in milestones (5+6) progress/completed it does not change anything, while the first 4 works fine. I don’t know what the issue is, can somebody help me?

    This is the code that I have is this:
    {
    “$schema”: “https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json”,
    “elmType”: “div”,
    “style”: {
    “font-size”: “16px”
    },
    “children”: [
    {
    “elmType”: “span”,
    “attributes”: {
    “title”: “Milestone 1”,
    “iconName”: “=if([$Milestone1] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone1] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    },
    “style”: {
    “padding”: “0 2px”
    }
    },
    {
    “elmType”: “span”,
    “attributes”: {
    “title”: “Milestone 2”,
    “iconName”: “=if([$Milestone2] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone2] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    },
    “style”: {
    “padding”: “0 2px”
    }
    },
    {
    “elmType”: “span”,
    “attributes”: {
    “title”: “Milestone 3”,
    “iconName”: “=if([$Milestone3] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone3] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    },
    “style”: {
    “padding”: “0 2px”
    }
    },
    {
    “elmType”: “span”,
    “attributes”: {
    “title”: “Milestone 4”,
    “iconName”: “=if([$Milestone4] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone4] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    },
    “style”: {
    “padding”: “0 2px”
    }
    },
    {
    “elmType”: “span”,
    “attributes”: {
    “title”: “Milestone 5”,
    “iconName”: “=if([$Milestone5] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone5] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    },
    “style”: {
    “padding”: “0 2px”
    }
    },
    {
    “elmType”: “span”,
    “attributes”: {
    “title”: “Milestone 6”,
    “iconName”: “=if([$Milestone6] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
    “class”: “=’ms-fontColor-‘ + if([$Milestone6] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
    },
    “style”: {
    “padding”: “0 2px”
    }
    }
    ]
    }

    Like

    1. Hi maily944312,

      The quotes are wrong in the Milestone6 if statement.

      =if([$Milestone6] == ”

      Should be:

      =if([$Milestone6] == ”

      Full JSON below.

      Thanks for reading!

      NY

      {
      “$schema”: “https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json”,
      “elmType”: “div”,
      “style”: {
      “font-size”: “16px”
      },
      “children”: [
      {
      “elmType”: “span”,
      “attributes”: {
      “title”: “Milestone 1”,
      “iconName”: “=if([$Milestone1] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
      “class”: “=’ms-fontColor-‘ + if([$Milestone1] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
      },
      “style”: {
      “padding”: “0 2px”
      }
      },
      {
      “elmType”: “span”,
      “attributes”: {
      “title”: “Milestone 2”,
      “iconName”: “=if([$Milestone2] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
      “class”: “=’ms-fontColor-‘ + if([$Milestone2] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
      },
      “style”: {
      “padding”: “0 2px”
      }
      },
      {
      “elmType”: “span”,
      “attributes”: {
      “title”: “Milestone 3”,
      “iconName”: “=if([$Milestone3] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
      “class”: “=’ms-fontColor-‘ + if([$Milestone3] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
      },
      “style”: {
      “padding”: “0 2px”
      }
      },
      {
      “elmType”: “span”,
      “attributes”: {
      “title”: “Milestone 4”,
      “iconName”: “=if([$Milestone4] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
      “class”: “=’ms-fontColor-‘ + if([$Milestone4] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
      },
      “style”: {
      “padding”: “0 2px”
      }
      },
      {
      “elmType”: “span”,
      “attributes”: {
      “title”: “Milestone 5”,
      “iconName”: “=if([$Milestone5] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
      “class”: “=’ms-fontColor-‘ + if([$Milestone5] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
      },
      “style”: {
      “padding”: “0 2px”
      }
      },
      {
      “elmType”: “span”,
      “attributes”: {
      “title”: “Milestone 6”,
      “iconName”: “=if([$Milestone6] == ”, ‘CircleRing’, ‘SkypeCircleCheck’)”,
      “class”: “=’ms-fontColor-‘ + if([$Milestone6] == ‘Complete’, ‘neutral’, ‘neutralLight’)”
      },
      “style”: {
      “padding”: “0 2px”
      }
      }
      ]
      }

      Like

  3. I am trying to track my projects (work items) by calendar quarter. the calendar view is too close in. I like the progress bar above but i would like to use it for the next 6 quarters. some projects would start on quarter 1 end on quarter 3. Another project might start on quarter 4 and end on quarter 6.

    Like

Leave a comment