1

Hey guys hope everyone's winning at life

Has anyone ever had to format the File Size column for a view?

I know how to process a bytes file length into friendly "1.5 MB" and etc. using a myriad of other languages like JavaScript, C# etc, enjoying the use of functions e.g.

function getFileSize(size) {
    var i = Math.floor( Math.log(size) / Math.log(1024) );
    return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
};

But how could I achieve this in the JSON for a modern SharePoint List View format, please? I see that it offers operators and etc but how can I achieve it without a function?

The raw value of $File_x0020_Size is a long number, and adding .displayText outputs the same number, sadly.

Here's a preview of my Gallery view format and the JSON

preview of Gallery view card

{
    "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json",
    "hideSelection": true,
    "height": 175,
    "width": 650,
    "fillHorizontally": true,
    "hideColumnHeader": true,
    "formatter": {
        "elmType": "div",
        "style": {
            "text-align": "left",
            "display": "flex",
            "font-family": "Arial",
            "padding": "20px 20px 20px 20px",
            "border": "solid 1px #e6e6e6",
            "margin-top": "21px"
        },
        "children": [
            {
                "elmType":"img",
                "style": {
                    "max-width": "200px",
                    "min-height": "100px"
                },
                "attributes":{
                    "src": "[$ProductImage.serverRelativeUrl]"
                }
            },
            {
                "elmType": "div",
                "style": {
                    "flex": "1",
                    "margin-left": "20px",
                    "line-height": "1.62em"
                },
                "children": [
                    {
                        "elmType": "div",
                        "children": [
                            {
                                "elmType": "img",
                                "style": {
                                    "width": "32px",
                                    "height": "32px"
                                },
                                "attributes": {
                                    "src": "='https://spoprod-a.akamaihd.net/files/fabric/assets/item-types/40/'+[$File_x0020_Type]+'.svg'"
                                }
                            },
                            {
                                "elmType": "a",
                                "style": {
                                    "font-size": "16px",
                                    "color": "#0078d4",
                                    "text-decoration": "none",
                                    "font-weight": "bold"
                                },
                                "attributes": {
                                    "target": "_blank",
                                    "href": "[$FileRef]"
                                },
                                "txtContent": "[$FileLeafRef]"
                            }
                        ]
                    },
                    {
                        "elmType": "div",
                        "style": {
                            "margin-top": "15px",
                            "color": "#444444",
                            "font-size": "16px"
                        },
                        "children": [
                            {
                                "elmType": "span",
                                "txtContent": "='Estimated cost price: ' + toString([$EstimatedPrice])"
                            }
                        ]
                    },
                    {
                        "elmType": "div",
                        "style": {
                            "margin-top": "15px",
                            "color": "#444444",
                            "font-size": "11px"
                        },
                        "children": [
                            {
                                "elmType": "span",
                                "txtContent": "=[$File_x0020_Size] + ' bytes'"
                            },
                            {
                                "elmType": "span",
                                "style": {
                                    "margin-left": "20px"
                                },
                                "txtContent": "='Last modified ' + toLocaleDateString([$Modified])"
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

Thanks in advance

1 Answer 1

1

Unfortunately, because there are neither variables or custom functions available in List Formatting, the solution will never be as elegant as other languages. But... it can be done!

Couple of things to note:

  • The [$File_x0020_Size] column returns its value as a string representing the number of bytes
  • The [$File_x0020_Size] column returns an empty string for things like folders
  • There is no precision formatting option so you either have to use ceiling or floor to remove decimals or use string manipulation to leave them in
  • substring doesn't care if the index is outside the bounds of the string which saves us some trouble when trying to get that precision right
  • The maximum upload size in SharePoint Online is 250 GB so the formula doesn't go up to TBs

Here is the expression by itself (for "simplicity"):

"txtContent": "=if([$File_x0020_Size] == '', '', if(Number([$File_x0020_Size]) < 1024, [$File_x0020_Size] + ' B', if(Number([$File_x0020_Size]) < pow(1024,2), if(indexOf(toString(Number([$File_x0020_Size])/1024),'.') == -1, Number([$File_x0020_Size])/1024, substring(toString(Number([$File_x0020_Size])/1024),0,indexOf(toString(Number([$File_x0020_Size])/1024),'.')+3)) + ' kB', if(Number([$File_x0020_Size]) < pow(1024,3), if(indexOf(toString(Number([$File_x0020_Size])/pow(1024,2)),'.') == -1, Number([$File_x0020_Size])/pow(1024,2), substring(toString(Number([$File_x0020_Size])/pow(1024,2)),0,indexOf(toString(Number([$File_x0020_Size])/pow(1024,2)),'.')+3)) + ' MB', if(indexOf(toString(Number([$File_x0020_Size])/pow(1024,3)),'.') == -1, Number([$File_x0020_Size])/pow(1024,3), substring(toString(Number([$File_x0020_Size])/pow(1024,3)),0,indexOf(toString(Number([$File_x0020_Size])/pow(1024,3)),'.')+3)) + ' GB'))))",

The formula is a series of nested if statements that compare the size of the value starting with bytes (less than 1024) and then applies some formatting when applicable. For anything greater than bytes, string inspection is used to have a maximum of 2 decimal places.

1
  • WOW I am blown away you were able to solve this so quickly - I had begun creating something like your solution trying to create a big nested query on several lines but I was probably months away from solving it that way - thank you VERY much, I owe you a beer or a few
    – Keegatron
    Aug 18, 2021 at 9:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.