SOLVED

How can you customize list headers in a modern page? (View Formatting)

Copper Contributor

View formatting with rowFormatter and column formatting has been a godsend, but I can't find any way short of SPFx injection to reformat the headers to match my column layouts. The problem with SPFx is that I'm only an SCA and I don't see how I can deploy a solution without local admin rights on the tenant. 

 

In Classic, I'd just insert a bit of javascript into the page to hide the existing headers and build new sticky/floating headers over top of them. But I don't have that option in Modern. 

 

Is there any other option to customizing the list headers in a Modern page? It seems like a massive oversight when there's so much flexibility in customizing the list content. 

 

 

5 Replies

Hi @jbenfield,

 

I know I'm not answering your question directly but you reference "sticky headers" in your post. If that is all the functionality you need it should be or is coming to your tenant soon. It was announced via the SharePoint blog.

Coming in March 2019.  Libraries and lists can get extremely large – up to 30 million items in a single list.  Soon, as you scroll down through ever-larger lists, SharePoint keeps the column headers pinned at the top of the scrolling window.  This helps you identify list values as you move vertically and horizontally through the view.  Column headers will also remain in place inside the list/library web parts.

It's in my tenant and works well.

 

I hope this helps.

 

Norm

Thanks for that, @Norman Young 

 

I really do appreciate that Microsoft is adding in some of the most common "hacks" that people have been using over the years. But I wish that they'd left jslink in place so that we had some alternatives while they filled out the feature set. 

 

Now if I can just make those headers match my customized data views, I'll be all set :)

 

Thanks, again!

 

best response confirmed by jbenfield (Copper Contributor)
Solution

So, I found a kind of ugly way to do what I needed by adding titles to every record block and then hiding them if they're not the first display row. 

 

"display": "=if(@rowIndex == 0, 'flex', 'none')",

 

Here''s the raw list:

2019-07-26_13-21-09.png

Formatted "pseudo-headers" and data.

2019-07-26_14-31-11.png

Unfortunately, the headers aren't responsive, it's not inherited by QuickEdit and it's missing the sorts and filtering of the real headers. But you could conceivably add the code to do it if needed. They also aren't sticky/floating. But it's still functional for what I needed. 

 

The full json view formatting for the example is below. 

 

 

{
    "$schema": "<a href="<a href="https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json" target="_blank">https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json</a>" target="_blank"><a href="https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json</a" target="_blank">https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json</a</a>>",
    "hideSelection": true,
    "hideColumnHeader": true,
    "rowFormatter": {
        "elmType": "div",
        "_comment_": "div-RecBlock",
        "style": {
            "display": "flex",
            "flex-direction": "column",
            "flex-wrap": "nowrap",
            "flex-align": "flex-start",
            "text-align": "center",
            "width": "250px",
            "margin-bottom": "10px",
            "background-color": "lightgrey",
            "border-radius": "8px"
        },
        "children": [
            {
                "elmType": "div",
                "_comment_": "div-title-row",
                "style": {
                    "display": "=if(@rowIndex == 0, 'flex', 'none')",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap",
                    "background-color": "blue",
                    "color" : "white",
                    "font-weight": "bold",
                    "border-radius": "4px"
                },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-title-col1",
                        "txtContent": "Index",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-title-col2",
                        "txtContent": "Text",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            },
            {
                "elmType": "div",
                "_comment_": "div-data-row1",
                "style": {
                    "display": "flex",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap"
                 },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-data-col1",
                        "txtContent": "=[$ID]",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-col-col2",
                        "txtContent": "=[$Title]",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            },
            {
                "elmType": "div",
                "_comment_": "div-data-row2",
                "style": {
                    "display": "flex",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap"
                 },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-data-col1",
                        "txtContent": " ",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-col-col2",
                        "txtContent": "=[$Line2]",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            },
            {
                "elmType": "div",
                "_comment_": "div-data-row3",
                "style": {
                    "display": "flex",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap"
                 },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-data-col1",
                        "txtContent": " ",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-col-col2",
                        "txtContent": "=[$line3]",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            }

        ]
    }
}

 

 

In case you're wondering, this is what I was trying to produce:

It's not pretty, but I'm trying to get a team onto sharepoint and this what they're used to seeing in the old system. Baby steps. When they click on the "site name", it invokes EditProps which takes them to a more "SharePoint-esque" PowerApps form. 

 

2019-07-26_14-39-06.png

@Chris Kent, might you be able to assist @jbenfield, myself, and others who need to modify/style/customize the headers for modern lists? I've not been able to find examples or guidance via https://sharepoint.github.io/sp-dev-list-formatting/ or Google Search.

 

For example:

Hi, does anyone know of plans to add sticky headers to list view webparts? This would be great, or if anyone knows of a work around. Thanks!
1 best response

Accepted Solutions
best response confirmed by jbenfield (Copper Contributor)
Solution

So, I found a kind of ugly way to do what I needed by adding titles to every record block and then hiding them if they're not the first display row. 

 

"display": "=if(@rowIndex == 0, 'flex', 'none')",

 

Here''s the raw list:

2019-07-26_13-21-09.png

Formatted "pseudo-headers" and data.

2019-07-26_14-31-11.png

Unfortunately, the headers aren't responsive, it's not inherited by QuickEdit and it's missing the sorts and filtering of the real headers. But you could conceivably add the code to do it if needed. They also aren't sticky/floating. But it's still functional for what I needed. 

 

The full json view formatting for the example is below. 

 

 

{
    "$schema": "<a href="<a href="https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json" target="_blank">https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json</a>" target="_blank"><a href="https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json</a" target="_blank">https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json</a</a>>",
    "hideSelection": true,
    "hideColumnHeader": true,
    "rowFormatter": {
        "elmType": "div",
        "_comment_": "div-RecBlock",
        "style": {
            "display": "flex",
            "flex-direction": "column",
            "flex-wrap": "nowrap",
            "flex-align": "flex-start",
            "text-align": "center",
            "width": "250px",
            "margin-bottom": "10px",
            "background-color": "lightgrey",
            "border-radius": "8px"
        },
        "children": [
            {
                "elmType": "div",
                "_comment_": "div-title-row",
                "style": {
                    "display": "=if(@rowIndex == 0, 'flex', 'none')",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap",
                    "background-color": "blue",
                    "color" : "white",
                    "font-weight": "bold",
                    "border-radius": "4px"
                },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-title-col1",
                        "txtContent": "Index",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-title-col2",
                        "txtContent": "Text",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            },
            {
                "elmType": "div",
                "_comment_": "div-data-row1",
                "style": {
                    "display": "flex",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap"
                 },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-data-col1",
                        "txtContent": "=[$ID]",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-col-col2",
                        "txtContent": "=[$Title]",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            },
            {
                "elmType": "div",
                "_comment_": "div-data-row2",
                "style": {
                    "display": "flex",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap"
                 },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-data-col1",
                        "txtContent": " ",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-col-col2",
                        "txtContent": "=[$Line2]",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            },
            {
                "elmType": "div",
                "_comment_": "div-data-row3",
                "style": {
                    "display": "flex",
                    "flex-direction": "row",
                    "flex-wrap": "nowrap"
                 },
                "children": [
                    {
                        "elmType": "div",
                        "_comment_": "div-data-col1",
                        "txtContent": " ",
                        "style": {
                            "width": "40px"
                        }
                    },
                    {
                        "elmType": "div",
                        "_comment_": "div-col-col2",
                        "txtContent": "=[$line3]",
                        "style": {
                            "width": "210px"
                        }
                    }
                ]
            }

        ]
    }
}

 

 

In case you're wondering, this is what I was trying to produce:

It's not pretty, but I'm trying to get a team onto sharepoint and this what they're used to seeing in the old system. Baby steps. When they click on the "site name", it invokes EditProps which takes them to a more "SharePoint-esque" PowerApps form. 

 

2019-07-26_14-39-06.png

View solution in original post