Back to view formats
View formattingSharePoint Online

Rating in Tiles

This sample demonstrates how to create a clickable rating experience in the view Tile mode. It allows users to rate the item/document when in the tile mode.

screenshot of the sample
Sample preview · View original animation

Copy. Apply. Make it yours.

Get this format

1 definition

Review the requirements below, then paste this JSON into the matching formatting panel. Show me where.

Use your list's internal column names and replace any tenant-specific URLs or flow IDs. Formatting is presentation, not a way to secure data.

View formatting
Download JSON
{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json",
  "height": 546,
  "width": 254,
  "hideSelection": true,
  "fillHorizontally": true,
  "formatter": {
    "elmType": "div",
    "attributes": {
      "class": "sp-card-container"
    },
    "children": [
      {
        "elmType": "div",
        "attributes": {
          "class": "sp-card-defaultClickButton"
        },
        "customRowAction": {
          "action": "defaultClick"
        }
      },
      {
        "elmType": "div",
        "attributes": {
          "class": "ms-bgColor-white sp-css-borderColor-neutralLight sp-card-borderHighlight sp-card-subContainer"
        },
        "children": [
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-previewColumnContainer"
            },
            "children": [
              {
                "elmType": "div",
                "attributes": {
                  "class": "sp-card-imageContainer"
                },
                "children": [
                  {
                    "elmType": "div",
                    "attributes": {
                      "class": "ms-bgColor-neutralLight sp-card-imagePreviewBackground"
                    },
                    "children": [
                      {
                        "elmType": "img",
                        "style": {
                          "display": "=if([$Image] == '', 'none', '')"
                        },
                        "attributes": {
                          "src": "=getThumbnailImage([$Image], 400, 400)",
                          "title": "[$Image.fileName]",
                          "class": "sp-card-imagePreview"
                        }
                      },
                      {
                        "elmType": "svg",
                        "style": {
                          "display": "=if([$Image] == '', '', 'none')"
                        },
                        "attributes": {
                          "preserveAspectRatio": "none",
                          "viewBox": "0 0 210 105",
                          "class": "sp-card-defaultImage ms-bgColor-themeLighter"
                        },
                        "children": [
                          {
                            "elmType": "path",
                            "attributes": {
                              "id": "sp-card-defaultImage-path1",
                              "d": "M0 25.7896L126.5 53.8817L96 105H0V25.7896Z"
                            }
                          },
                          {
                            "elmType": "path",
                            "attributes": {
                              "id": "sp-card-defaultImage-path2",
                              "d": "M96 105L158.7 0H204C207.314 0 210 2.68629 210 6V105H96Z"
                            }
                          }
                        ]
                      },
                      {
                        "elmType": "svg",
                        "style": {
                          "display": "=if([$Image] == '', '', 'none')"
                        },
                        "attributes": {
                          "class": "sp-card-defaultImageOverlay",
                          "viewBox": "0 0 40 40"
                        },
                        "children": [
                          {
                            "elmType": "path",
                            "attributes": {
                              "id": "sp-card-defaultImageOverlay-path1",
                              "d": "M 4 4 H 37 V 37 H 4 L 4 4"
                            }
                          },
                          {
                            "elmType": "path",
                            "attributes": {
                              "id": "sp-card-defaultImageOverlay-path2",
                              "d": "M24.17 21.151L21.66 24.741L17.54 19.191C17.3322 18.914 17.0062 18.751 16.66 18.751C16.3137 18.751 15.9877 18.914 15.78 19.191L9.20997 28.051C8.97126 28.3786 8.93818 28.813 9.12453 29.173C9.31088 29.533 9.68465 29.7567 10.09 29.751H29.91C30.3085 29.7562 30.6769 29.5396 30.866 29.1887C31.0551 28.8378 31.0335 28.411 30.81 28.081L26 21.151C25.7991 20.8407 25.4546 20.6533 25.085 20.6533C24.7153 20.6533 24.3709 20.8407 24.17 21.151Z"
                            }
                          },
                          {
                            "elmType": "path",
                            "attributes": {
                              "id": "sp-card-defaultImageOverlay-path3",
                              "d": "M28 15.751C29.3807 15.751 30.5 14.6317 30.5 13.251C30.5 11.8703 29.3807 10.751 28 10.751C26.6193 10.751 25.5 11.8703 25.5 13.251C25.5 14.6317 26.6193 15.751 28 15.751Z"
                            }
                          },
                          {
                            "elmType": "path",
                            "attributes": {
                              "id": "sp-card-defaultImageOverlay-path4",
                              "d": "M4.5 37.251H35.5C36.3284 37.251 37 36.5794 37 35.751V4.75098C37 3.92255 36.3284 3.25098 35.5 3.25098H4.5C3.67157 3.25098 3 3.92255 3 4.75098V35.751C3 36.5794 3.67157 37.251 4.5 37.251ZM4 4.75098C4 4.47483 4.22386 4.25098 4.5 4.25098H35.5C35.7761 4.25098 36 4.47483 36 4.75098V35.751C36 36.0271 35.7761 36.251 35.5 36.251H4.5C4.22386 36.251 4 36.0271 4 35.751V4.75098Z"
                            }
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-displayColumnContainer"
            },
            "children": [
              {
                "elmType": "p",
                "attributes": {
                  "class": "ms-fontColor-neutralSecondary sp-card-label"
                },
                "txtContent": "[!Title.DisplayName]"
              },
              {
                "elmType": "p",
                "attributes": {
                  "title": "[$Title]",
                  "class": "ms-fontColor-neutralPrimary sp-card-content sp-card-highlightedContent",
                  "role": "heading",
                  "aria-level": "3"
                },
                "txtContent": "=if ([$Title] == '', '–', [$Title])"
              }
            ]
          },
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-displayColumnContainer"
            },
            "children": [
              {
                "elmType": "p",
                "attributes": {
                  "class": "ms-fontColor-neutralSecondary sp-card-label"
                },
                "txtContent": "[!Link.DisplayName]"
              },
              {
                "elmType": "a",
                "attributes": {
                  "title": "[$Link]",
                  "class": "ms-fontColor-neutralPrimary sp-card-content sp-card-urlContent  sp-card-keyboard-focusable",
                  "href": "[$Link]",
                  "target": "=if ([$Link] == '', '', '_blank')"
                },
                "style": {
                  "pointer-events": "=if ([$Link] == '', 'none', 'auto')",
                  "text-decoration": "=if ([$Link] == '', 'none', 'auto')"
                },
                "txtContent": "=if ([$Link.desc] == '', '–', [$Link.desc])"
              }
            ]
          },
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-displayColumnContainer"
            },
            "children": [
              {
                "elmType": "p",
                "attributes": {
                  "class": "ms-fontColor-neutralSecondary sp-card-label"
                },
                "txtContent": "[!Tags.DisplayName]"
              },
              {
                "elmType": "p",
                "attributes": {
                  "title": "[$Tags]",
                  "class": "ms-fontColor-neutralPrimary sp-card-content "
                },
                "txtContent": "=if ([$Tags] == '', '–', [$Tags])"
              }
            ]
          },
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-displayColumnContainer"
            },
            "children": [
              {
                "elmType": "p",
                "attributes": {
                  "class": "ms-fontColor-neutralSecondary sp-card-label"
                },
                "txtContent": "[!Tried.DisplayName]"
              },
              {
                "elmType": "p",
                "attributes": {
                  "title": "=if ([$Tried.displayValue] == '', '–', [$Tried.displayValue])",
                  "class": "ms-fontColor-neutralPrimary sp-card-content "
                },
                "txtContent": "=if ([$Tried.displayValue] == '', '–', [$Tried.displayValue])"
              }
            ]
          },
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-displayColumnContainer"
            },
            "children": [
              {
                "elmType": "p",
                "attributes": {
                  "class": "ms-fontColor-neutralSecondary sp-card-label"
                },
                "txtContent": "[!AverageRating.DisplayName]"
              },
              {
                "elmType": "div",
                "attributes": {
                  "class": "ms-fontColor-neutralPrimary sp-card-content "
                },
                "children": [
                  {
                    "elmType": "div",
                    "attributes": {
                      "class": "ms-fontColor-neutralPrimary sp-card-content "
                    },
                    "children": [
                      {
                        "elmType": "span",
                        "forEach": "rating in split('1,2,3,4,5',',')",
                        "children": [
                          {
                            "elmType": "span",
                            "attributes": {
                              "class": "=if([$AverageRating] >= [$rating] , 'sp-card-starRating ms-bgColor-communicationPrimary--hover', if([$AverageRating] > [$rating] -1 && [$AverageRating]  < [$rating], 'sp-card-starRating sp-card-halfFillStar ms-bgColor-communicationPrimary--hover', 'sp-card-starRating sp-card-emptyFillStar ms-bgColor-communicationPrimary--hover'))",
                              "iconName": "FavoriteStarFill"
                            },
                            "customRowAction": {
                              "action": "setValue",
                              "actionInput": {
                                "RatingCount": "=if(indexOf([$RatedBy.email], @me) == -1, Number([$RatingCount]) + 1, Number([$RatingCount]))",
                                "Ratings": "=if(indexOf([$RatedBy.email], @me) == -1, ([$Ratings] + [$rating] + ','), substring([$Ratings], 0,indexOf(split(replaceAll([$RatedBy.email],' ',''), ';'), @me)*2) + [$rating] + substring([$Ratings],   indexOf(split(replaceAll([$RatedBy.email],' ',''), ';'), @me)*2+1, indexOf([$Ratings] + '^', '^')))",
                                "RatedBy": "=if(indexOf([$RatedBy.email], @me) == -1, appendTo([$RatedBy.email], @me),[$RatedBy])",
                                "AverageRating": "=if(indexOf([$RatedBy.email], @me) == -1, ((Number([$AverageRating])*Number([$RatingCount])) + Number([$rating]))/(Number([$RatingCount]) + 1),((Number([$AverageRating])*Number([$RatingCount]) + Number([$rating]) - Number(substring([$Ratings],indexOf(split(replaceAll([$RatedBy.email],' ',''), ';'), @me)*2,indexOf(split(replaceAll([$RatedBy.email],' ',''), ';'), @me)*2+1)))/Number([$RatingCount])))"
                              }
                            }
                          }
                        ]
                      },
                      {
                        "elmType": "span",
                        "attributes": {
                          "class": "sp-card-ratingCount"
                        },
                        "txtContent": "= ' ' + length([$RatedBy])"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "elmType": "div",
            "attributes": {
              "class": "sp-card-previewColumnContainer"
            },
            "children": [
              {
                "elmType": "p",
                "attributes": {
                  "class": "ms-fontColor-neutralSecondary sp-card-label"
                },
                "txtContent": "[!RatedBy.DisplayName]"
              },
              {
                "elmType": "div",
                "style": {
                  "display": "flex"
                },
                "children": [
                  {
                    "elmType": "p",
                    "attributes": {
                      "class": "sp-card-userEmptyText"
                    },
                    "txtContent": "=if(length([$RatedBy]) == 0, '–', '')"
                  },
                  {
                    "forEach": "personIterator in [$RatedBy]",
                    "elmType": "a",
                    "attributes": {
                      "class": "=if(loopIndex('personIterator') >= 5, 'sp-card-userContainer', 'sp-card-userContainer sp-card-keyboard-focusable')"
                    },
                    "style": {
                      "display": "=if(loopIndex('personIterator') >= 5, 'none', '')"
                    },
                    "children": [
                      {
                        "elmType": "img",
                        "defaultHoverField": "[$personIterator]",
                        "attributes": {
                          "src": "=getUserImage([$personIterator.email], 'S')",
                          "title": "[$personIterator.title]",
                          "class": "sp-card-userThumbnail"
                        },
                        "style": {
                          "display": "=if(length([$RatedBy]) > 5 && loopIndex('personIterator') >= 4, 'none', '')"
                        }
                      },
                      {
                        "elmType": "div",
                        "attributes": {
                          "class": "ms-bgColor-neutralLight ms-fontColor-neutralSecondary sp-card-userOthers"
                        },
                        "style": {
                          "display": "=if(length([$RatedBy]) > 5 && loopIndex('personIterator') == 4, '', 'none')"
                        },
                        "customCardProps": {
                          "formatter": {
                            "elmType": "div",
                            "attributes": {
                              "class": "sp-card-personCallout"
                            },
                            "children": [
                              {
                                "forEach": "personIterator in [$RatedBy]",
                                "elmType": "div",
                                "attributes": {
                                  "class": "sp-card-userContainer sp-card-userCustomCard"
                                },
                                "style": {
                                  "display": "=if(loopIndex('personIterator') < 4, 'none', '')"
                                },
                                "children": [
                                  {
                                    "elmType": "img",
                                    "defaultHoverField": "[$personIterator]",
                                    "attributes": {
                                      "src": "=getUserImage([$personIterator.email], 'S')",
                                      "title": "[$personIterator.title]",
                                      "class": "sp-card-userThumbnail"
                                    }
                                  }
                                ]
                              }
                            ]
                          },
                          "openOnEvent": "hover"
                        },
                        "children": [
                          {
                            "elmType": "span",
                            "txtContent": "='+' + toString(length([$RatedBy]) - (4))"
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "elmType": "div",
                    "attributes": {
                      "class": "sp-card-userTitle sp-card-keyboard-focusable"
                    },
                    "style": {
                      "display": "=if(length([$RatedBy]) == 1, '', 'none')"
                    },
                    "defaultHoverField": "[$personIterator]",
                    "txtContent": "[$RatedBy.title]"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}
Schema compatibility review notes

This historical definition differs from the pinned Microsoft schema. This may indicate an unsupported pattern or a schema limitation. Check the original requirements and test in your tenant before use.

  • /formatter/children/1/children/0/children/0/children/0/children/1/children/0/attributes must NOT have additional properties

From the contributor

How to use this sample

Summary

This sample demonstrates how to create a clickable rating experience in the view Tile mode. It allows users to rate the item/document when in the tile mode.

screenshot of the sample

View requirements

Create a list using the template Recipe Tracker

screenshot of create list

Enabling the ratings feature (Only communication site)

The ratings feature is available by default in the team site, but not in the communication site. If you want to use the ratings feature in the list of communication sites, you need to enable the feature GUID 915c240e-a6cc-49b8-8b2c-0bff8b553ed3. The following is an example of how to enable it using PnP PowerShell.

$targetURL = "https://<tenent name>.sharepoint.com/sites/<site name>"
Connect-PnPOnline -Url $targetURL -Interactive
Enable-PnPFeature –identity 915c240e-a6cc-49b8-8b2c-0bff8b553ed3 -Scope site
Disconnect-PnPOnline

Add a ratings feature to the list

  1. Click gear icon

  2. Click List Settings

  3. Under General Settings, click Rating Settings.

    screenshot of how to add the ratings feature

  4. Under Rating Settings, click Yes.

  5. Under Which voting/rating experience you would like to enable for this list?, click Rating.

  6. Click OK.

    screenshot of how to add the ratings feature

Adding rating fields to the default view

The following is an example of how to add the rating related fields to the default view using PnP PowerShell.

$targetURL = "https://<tenant name>.sharepoint.com/sites/<site name>"
$listName = "<list title>" # Recipe Tracker

Connect-PnPOnline -Url $targetURL -Interactive

$list = Get-PnPList -Identity $listName
$list.DefaultView.ViewFields.Add("RatingCount")
$list.DefaultView.ViewFields.Add("Ratings")
$list.DefaultView.ViewFields.Add("RatedBy")
$list.DefaultView.Update()
Invoke-PnPQuery

After this the default view should look like: screenshot list view columns

Sample

Solution Author(s)
rating-in-tiles.json Luís Ribeiro

Version history

Version Date Comments
1.0 October 22, 2023 Initial release

Disclaimer

THIS CODE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.


Additional notes

None