Hide the Browse and Edit buttons and/or the Share, Follow, and Focus/Full-Screen buttons from a SharePoint page’s ribbon menu

Photo by Drew Rae from Pexels

I know I’m blogging a lot about CSS changes lately, and it’s not normally something I recommend. But for a very specific project of mine, I’ve been doing a lot of this and am sharing a few tips along the way in case they help others needing to accomplish something similar.

Hide the Browse and Edit buttons/tabs

Click to enlarge

In this post, I’ll share how to hide the Browse and Edit tabs from the ribbon menu of a SharePoint page. This only applies to classic experience pages. To hide these tabs/buttons, add the following CSS inside a <style> tag to the page(s) on which you wish to remove these options.

.ms-cui-tt a[Title='Browse'],.ms-cui-tt a[Title='Edit']{
display:none;
}

If you’re unsure how to add CSS to your page, this post details the steps with a different script. Just use the script above inside <style> tags instead.

You can also hide other tabs like Page, Files, Library, etc. by adding a comma right before the opening brace ({) and then pasting another .ms-cui-tt a[Title=’Page’] (substituting the tab name of course). This only works for some, but not all tabs.

Hide the Share, Follow, and Focus/Full Screen buttons

You may also wish to hide the three buttons on the right side of the ribbon seen here:

Click to enlarge

Similar to above, we’ll just set the #RibbonContainer-TabRowRight ID to not display. This one has to have !important added inside the semi-colon for it to override competing code and take affect as expected.

#RibbonContainer-TabRowRight{
display:none!important;
}

Style embedded html iframe and border so it doesn’t look sunk on the page

Photo by Zukiman Mohamad from Pexels

If left unstyled, your embedded iframe content when working with html pages appears inside “sunken” boxes/frames (browser and context-dependent, of course). I don’t find this look to be very appealing, so I typically adjust the iframe’s properties a bit in the html to give it a little less sink and a little more pop. I add specific width and height values to be exact about where I’m placing it and what it contains, and I use box-shadow instead of border which gives it that “lift” off the page.

Consider the following script just a starting place, then get creative with your own content and design. You’ll want your embedded content to “fit in” with the rest of its page’s contents so try to be consistent if you have other boxed elements/containers on the page (Tip: Use F12 and element selection to see the style properties of other parts of your page).

<iframe src="https://sharepoint.contoso.com/SitePages/MyLinks.aspx" border="0" frameborder="0" style="border-style:none;box-shadow:0px 0px 2px 2px rgba(0,0,0,0.2);width:262.5px;height:250px;" cellspacing="0"></iframe>

P.S. I’m sure I could write this prettier, but it works. For instance, you could reference the iframe in your CSS rather than hard-coding it in the html body.

Make full-width SharePoint hyperlink column clickable beyond just the link text

Photo by Pixabay from Pexels

This is such an obscure topic, but maybe it will help somebody curious out there. I recently had a request to alter a classic experience list with a single hyperlink column so that users could click in the white space of a cell and it takes them to that cell’s hyperlink value as if they’d actually clicked the link.

To illustrate what I mean, notice how the arrow pointer changes to a hand cursor like the whole cell is clickable. And when white (blue) space of the Google link is clicked, it takes us to Google anyway:

Click to enlarge

This was done with the tiniest bit of CSS added to the page inside a <style> tag. Note that this will affect all links in tables on the page to which it’s applied. So if you have more than one table on the page, this could cause issues. But in my case I just had the single-column list I was working with and this sufficed.

td a {
    display:inline-flex;
    width:100%;
}

Good luck!

Solution: SharePoint Designer email action’s To: line has a valid email address, but is removed and doesn’t send when triggered

Photo by Snapwire from Pexels

If you’ve created a workflow in SharePoint Designer and an email action appears to be configured correctly, but emails aren’t being sent to some individuals in the To: line, you may need to turn the email being used into a workflow variable and use that instead of direct addition to the To: line of the email step.

This often happens for group email inboxes or external recipients that aren’t just a “normal user.” If there is a mix of recipients, some may receive the message but the troublesome addresses don’t even appear in the To: line, as if they’re removed before sending.

Note: If you’re sending to external recipients specifically and this post doesn’t solve your problem, check out my other post for additional help: Sending emails via SharePoint Designer workflow to external recipients using Gmail, Yahoo, Hotmail, etc. addresses

To “variablize” an email (this is using a SP 2010 platform workflow type):

1. Set a new workflow variable of type string to the email address(es) that aren’t receiving emails as expected.

Click to enlarge
Click to enlarge
Click to enlarge

2. Now in your email settings, use the “Workflow Lookup for a User” option and select your new variable from “Workflow Variables and Parameters” data source.

Click to enlarge
Click to enlarge
Click to enlarge

3. Publish the changes to your workflow and test.

SharePoint conditional column formatting with JSON: Beginner, intermediate, and advanced background colors example

I borrowed from Microsoft’s documentation on conditional column formatting recently to modify a modern experience list in SharePoint 2019. This also works for SharePoint Online/O365, but will not work in classic experiences (or pre-2019 server versions). I modified Microsoft’s example on conditional background colors for a numeric range and created a similar conditional column formatting result for text values.

In this example, I have a list for upcoming training opportunities. There’s a column named “Level” which is a choice field of either Beginner, Intermediate, or Advanced. The JSON code at the bottom of this post changes the column’s background color value to green, yellow, or red respectively based on the level selection. Here’s a demonstration of the result:

Click to enlarge.

You could modify this code to suit your own column’s values/options, then paste it into the Column Formatting section of that column’s settings (List settings > Select column from Columns section). Do not change @currentField in the JSON code – that’s just a reference to whichever column you add it to and doesn’t need to be your column’s name.

Click to enlarge
{  
  "elmType": "div",  
  "txtContent": "@currentField",  
  "style": {  
    "color": "#fff",  
    "padding-left": "14px",  
    "background-color": {  
      "operator": "?",  
      "operands": [  
        {  
          "operator": "==",  
          "operands": [  
            "@currentField",  
            "Beginner"  
          ]  
        },  
        "#2ECC71",  
        {  
          "operator": "?",  
          "operands": [  
            {  
              "operator": "==",  
              "operands": [  
                "@currentField",  
                "Advanced"  
              ]  
            },  
            "#E74C3C",  
            {  
              "operator": "?",  
              "operands": [  
                {  
                  "operator": "==",  
                  "operands": [  
                    "@currentField",  
                    "Intermediate"  
                  ]  
                },  
                "#F1C40F",""
              ]  
            }  
          ]  
        }  
      ]  
    }  
  }  
}

Auto-approval of Microsoft Teams Shifts requests using Power Automate

Today I happily stumbled across a collection of Power Automate templates for auto-approval of different types of Microsoft Teams Shifts requests, such as time off requests, open shift requests, and swap requests.

Not familiar with Shifts? Check out my write-up.

The ability to auto-approve removes the current reliance on a Team owner to approve requests. In less formal Teams, this would be an excellent improvement to speed up the process and give autonomy to your team members.

While most of the templates’ triggers are set to use “Recurrence” (regularly reviewing requests and approving on the hour), you can also create your own flow using Shifts itself as a trigger instead.

Note: In high-activity Teams, using Recurrence as the trigger might cut down the number of runs/flows you use if that’s a consideration for you. Using Shifts as the trigger as seen below will run every time a request is made, but provides a faster response to your users.

Click to enlarge.

The templates for Power Automate auto-approval of Shifts requests range from simple flows to more complex flows. Check them out below:

  1. Auto Approve Offer Shift Requests
  2. Auto Approve Open Shift Requests
  3. Auto Approve Swap Shifts Requests and Send Email Notification
  4. Auto Convert Shift to Open Shift
  5. Share My Shifts as iCalendar Feed
Auto Approve Offer Shift Request
Image taken from Auto Approve Swap Shifts Requests and Send Email Notification template example. Click to enlarge.

Delete random blank Excel cells and shift remaining cells left to fill the gaps

Photo by Andrea Albanese from Pexels

I love learning new things. Today I was using a CSV export of data in Excel and was just using Excel to reassemble the data. At one point it resembled something like:

This is, of course, after some manipulation. Basically I removed the parts of a URL column expanded by delimiter (“/”) I didn’t want. This left awkward gaps and all I wanted was to quickly delete the gaps and shift contents of remaining cells to the left to sort of “reconstruct” each row without gaps. Since they didn’t line up in neat columns, I needed a different method.

I found a great article that helped. To summarize the steps:

  1. Select the range for which you’ll delete blank cells and shift data left.
  2. Press Ctrl+G.
  3. Click Special… (lower left of dialog)
  4. Choose the Blanks radio button
  5. Click OK.
  6. All blank cells in the selected range remain highlighted. Now right-click any of the selected blank cells.
  7. Choose Delete.
  8. Select Shift cells left.
  9. Click OK.

Here’s an animated GIF showing the process on my example data:

Click to enlarge

Export a report of all SharePoint lists, libraries, discussion boards, calendars, and more from all site collections with PowerShell

Photo by Tiger Lily from Pexels

I wanted to get an idea of how many people were using discussion boards in my SharePoint Server environment and in what sites. I modified a script I found to create the sort of inventory list I needed and ended with a script that:

  • Provides a list within PowerShell of each URL, site name, and list name found matching a specific list type.
  • Provides a total count and save location confirmation at the end.
  • Exports a CSV file of the details to a specified location.

Find the Template ID for the list you’re searching for

List template ID options are as follows, taken from this Docs article. You’ll need the Template ID of the type of list you wish to search in your SharePoint environment.

List template typeTemplate IDBase typeDescription
Custom List1000A basic list that can be adapted for multiple purposes.
Document Library1011Contains a list of documents and other files.
Survey1024Fields (2) on a survey list represent questions that are asked of survey participants. Items in a list represent a set of responses to a survey.
Links1030Contains a list of hyperlinks and their descriptions.
Announcements1040Contains a set of simple announcements.
Contacts1050Contains a list of contacts used for tracking people in a site (2).
Calendar1060Contains a list of single and recurring events. An events list has special views for displaying events on a calendar.
Tasks1070Contains a list of items that represent finished and pending work items.
Discussion Board1080Contains discussions entries and their replies.
Picture Library1091Contains a library adapted for storing and viewing digital pictures.
DataSources1101Contains data connection description files.
Form Library1151Contains XML documents. An XML form library can also contain templates for displaying and editing XML files through forms, as well as rules for specifying how XML data is converted to and from list items.
No Code Workflows1171Contains additional workflow definitions that describe new processes that can be used in lists. These workflow definitions do not contain advanced code-based extensions.
Custom Workflow Process1180Contains a list used to support custom workflow process actions.
Wiki Page Library1191Contains a set of editable Web pages.
CustomGrid1200Contains a set of list items with a grid-editing view.
No Code Public Workflows1221A gallery for storing workflow definitions that do not contain advanced code-based extensions.
Workflow History1400Contains a set of history items for instances of workflows.
Project Tasks1500Contains a list of tasks with specialized views of task data in the form of Gantt chart.
Public Workflows External List6000An external list for viewing the data of an external content type.
Issues Tracking11005Contains a list of items to track issues.
Table of list template IDs taken from https://docs.microsoft.com/en-us/openspecs/sharepoint_protocols/ms-wssts/8bf797af-288c-4a1d-a14b-cf5394e636cf.

Modify the PowerShell script to suit your needs

Once you have the list template ID you wish to query from the table above, modify the PowerShell script found below as follows:

  1. Replace the $ListTemplateId variable value with your desired template ID.
  2. Replace the -WebApplication parameter’s URL value with your own SharePoint web app address.
  3. Replace the $saveCSVLocation value inside the double-quotes with the path to where you’d like the export to be written.

Get all SharePoint list types in one report

Want it all? You could modify the script by replacing -eq $ListTemplateId on line 15 with -gt 0. Then replace line 21 with:

@{Site=$web.Title;ListName=$list.Title;Type=$list.BaseTemplate;URL=($web.Url + "/" + $i.DefaultView.Url)}) | % { New-Object object | Add-Member -NotePropertyMembers $_ -PassThru }

And replace line 25 with:

write-Output ($web.Title + "," + $list.Title + "," + $list.BaseTemplate + "," + $web.Url + "/" + $i.DefaultView.Url) | Out-File $SaveLocationFinal -Append

Now your report will include all list types, and an added column to specify that list type. Note that this will take a while to run in larger environments.

You could also modify the script to only display in PowerShell (delete lines 23-25 and 31-33) or only export to CSV (delete lines 19-22 and 31-33) but I wanted both outputs for my purposes.

Idea: Take it further with Power BI

Take this to the next level by automating the PowerShell script to run on a schedule exporting results to a folder Power BI reads on an automatic refresh. This is an easy way to get a hands-off dashboard of SharePoint usage by list type.

Set default value of multiple lines of text (enhanced rich text type) field in SharePoint new item forms using jQuery

A recent project tasked me with providing a default value for an enhanced rich text field. Most field types allow you to set a default value out of the box. With enhanced rich text (multi-line text field type) there’s no option to set a default value.

I decided jQuery was the route I wanted to go on this one. After Googling for a fair while I finally found a response that helped.

Modifying the answer provided there, I simplified the code that worked to:

<script src="https://sharepoint.contoso.com/SiteAssets/jquery.min.js" type="text/javascript"></script>
<script>
$(function () {
                $('div[id$="TextField_inplacerte"').text("Test");
});        
</script>

Just save that code as a .js file you upload to your site. Then reference the saved .js filepath via a Content Editor Web Part placed on the new item page (newform.aspx).

Not familiar with jQuery?

The first line of the script needs to reference jQuery. In some environments this needs to be hosted in your site (I typically use Site Assets for this). In other cases, you can just reference it hosted elsewhere (not recommended, but could work for testing/short-term in some environments). I used the code from http://code.jquery.com/jquery-latest.min.js and saved its contents as a .js file of my own that I uploaded to Site Assets. Then just replace the URL in the first line of the script with the URL of the file you uploaded to Site Assets.

More than one enhanced rich text field?

The script looks for any enhanced rich text field, and in my case I only had one in the form so it was fine. If you have more than one, just replace TextField_inplacerte with the full ID of the rich text text field on your form.

Hint: User developer tools with F12 in the browser then select the field. The ID you want will end with TextField_inplacerte and likely start with your field name.

Create a custom permission level in SharePoint

Photo by Markus Spiske from Pexels

I’m often asked for a way to modify permissions beyond what’s available out of the box, but without using workflows.

There are settings that allow item-level permissions in lists (List Settings > Advanced Settings > Item-level Permissions) so that users can only see and/or edit their own items, but this may not solve your need. If so, ta-da! If not, keep reading.

Click to enlarge

In this post, I’ll cover one solution in which we create a custom permission level at the site level that we’ll assign to a group on a specific list’s permissions. This new, custom permission level will be the same as the Contribute level (out of the box) but removes the ability for users to delete items or versions.

Creating a custom permission level involves a couple main steps:

  1. Create the new permission level.
  2. Change permissions on the list so that the group of users who should have the new permission level are assigned the new permission level.

Create the new, custom permission level

1. Go to Site Settings

2. Under Users and Permissions, select Site permissions

3. Click Permission Levels

4. You could click Add a Permission Level but I typically prefer to copy an existing level (like Contribute) and just make a couple small changes. For this tutorial, I’m going to select Contribute.

Click to enlarge

If copying a level, scroll down to the bottom after selecting a level and click Copy Permission Level.

5. Name and describe the new permission level, then check and uncheck as needed to create the permission level desired. In my example, I want to copy Contribute, but remove the delete ability so I’ve unchecked the two options involving deletion of items and versions.

Click to enlarge

6. Scroll down and click Create.

Change permissions on the list

Now we need to assign our new permission level to users on the list for which we’re preventing deletion.

1. Go to List Settings.

2. Under Permissions and Management, select Permissions for this list.

3. Select the box next to the name of the group for which you’re modifying permissions.

4. Click Edit User Permissions from the top ribbon menu.

5. Uncheck the current permission level assigned to the group, and check the new custom permission level.

6. Click OK.