2/09/2008

SharePoint: Hiding Menus (not using HideCustomAction)

Hiding SharePoint List and Library Menus

For a recent project I needed to hide several menu items in the document library toolbar, and I wanted to do it as a Feature. The obvious choice from the SDK was HideCustomAction. But... it does not seem to work. A search of the web finds lots of discussion about HideCustomAction and how it only works on a few places, such as those listed in the MSDN article here. There is either not enough info in the table in that article, or that is the complete list of the only items that can be touched with HideCustomAction.

So what else can we do? Fall back to the old tricks, that's what! A little JavaScript routine can find and change what we need. For example, this will find and hide the Explorer View menu:

<script language="JavaScript">
 var doc = document.getElementsByTagName('ie:menuitem'); 
 for (var i = 0; i < doc.length; i++)
  {
    itm = doc[i];
    if (itm.id.match('OpenInExplorer')!=null)
      { itm.hidden=true; }
  } 
</script> 

 

The trick here is to find the menu tags on the page. What we are looking for is this:

      <ie:menuitem id="zz23_OpenInExplorer" ... hidden= ... />

The JavaScript starts by finding all tags named "ie:menuitem" and then looping through those to find the one we need. The hidden attribute is pretty obvious, so we set it to false.

For just one library:

Where do you put this JavaScript? For just one library use SharePoint Designer add this to the bottom of the allitems.aspx for that library. The best place is just before the end tag (</asp:Content>) tag of the "<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">" tag.

 

For all libraries:

To impact all libraries with a single edit you will need to use SharePoint Designer to add this JavaScript at the end of the Master Page (default.master), just before the "</BODY>" tag.

 

What about a Feature?

If you want to control the hiding of the menus by using a Feature so you can turn them on and off at will, and at the farm, application, site collection or site level the you have a little more work to do, but not too much.

I will return here later and add a full step by step, but here's the code you will need:

- A SharePoint Delegate control:

Add this to the bottom of your Master Page just before the </body> tag (The ControlId is up to you, but needs to match the Id used in the elements file):

  <SharePoint:DelegateControl runat="server" ControlId="MiscControls" AllowMultipleControls="true"/>


- A .Net User Control:

HideMenus.ascx

<%@ Control Language="C#" ClassName="HideMenus" %> 
<script language="JavaScript">
  var doc = document.getElementsByTagName('ie:menuitem'); 
  for (var i = 0; i < doc.length; i++)
  {
    itm = doc[i]; 
    if (itm.id.match('MultipleUpload')!=null | itm.id.match('OpenInExplorer')!=null) 
    { itm.hidden=true; }
  } 
</script>

 


- A feature file:

Feature.xml

<Feature
  Id="531F15CD-A646-45e5-AB61-4F8DF89C29D9"
  Title="Hide Menus"
  Description="Sample feature to hide selected menus (from TechTrainingNotes)"
  Scope="Web"
  Hidden="FALSE"
  xmlns="http://schemas.microsoft.com/sharepoint/"> 
 
  <ElementManifests>
    <ElementManifest Location="elements.xml" /> 
  </ElementManifests> 
</Feature>


- An elements file:

Elements.xml

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control 
    ControlSrc="~/_controltemplates/HideMenus.ascx"
    Sequence="100"
    Id="MiscControls">
  </Control>  
</Elements>  

The is a list of items created by a typical WSS Master Page:

Menu item name

Menu

Menu text

PersonalInformation

The Welcome menu

My Settings

LoginAsDifferentUser

The Welcome menu

Sign in as Different User

RequestAccess

The Welcome menu

Request Access

Logout

The Welcome menu

Sign Out

MenuItem_Create

Site Actions

Create

MenuItem_Settings

Site Actions Site Settings

 

This is a list of items created by a typical document library allitems.aspx page:

(all of the above table plus the following)

New0 (zero, not O)

New

New Document (default click)

NewFolder

New

New Folder

Upload

Upload

Upload Document

MultipleUpload

Upload

Upload Multiple Documents

EditInGridButton

Actions

Edit in Datasheet

OpenInExplorer

Actions

Open with Windows Explorer

OfflineButton

Actions

Connect to Outlook

ExportToSpreadsheet

Actions

Export to Spreadsheet

ViewRSS

Actions

View RSS Feed

SubscribeButton

Actions

Alert Me

AddColumn

Settings

Create Column

AddView

Settings

Create View

ListSettings

Settings

Document Library Settings

DefaultView

View

All Documents (in typical library)

View1

View

Explorer View

ModifyView

View

Modify this view

CreateView

View

Create view

10 comments:

Anonymous said...

To support firefox...

var doc = document.getElementsByTagName('ie:menuitem');

for (var i = 0; i < doc.length; i++){
var itm = doc[i];

if (itm.id.match('OpenInExplorer')!=null){
var p = itm.parentNode;
p.removeChild(itm);
}
}


The FlydMaster

Anonymous said...

Nicely written, clearest example I've seen. Got it working in five minutes. I use IE Developer Toolbar to get the menu references.

Little stuck, how would you remove menu items from the individual item context menus, e.g. ID_EditProperties?

thanks

Mike Smith said...

Spartacus55,

Hiding items in the ECB menu is a problem as this menu is not part of the CustomAction framework. ECBs are added using JavaScript found in /_layouts/1033/core.js

Here's the best bet I've found:
http://www.helloitsliam.com/archive/2007/08/10/moss2007-%E2%80%93-item-level-menus-investigation.aspx

Mike

Viggu said...

Excellent Post. Saved lot of time. Thank You

One attribute missing is,
'ExportToDatabase' relating to 'Open With Access'

Anonymous said...

Is it possible to hide toolbar Action menu item called 'connect to outlook' and 'open in explorer'?

Mike Smith said...

Anonymous,

See "OpenInExplorer" and "OfflineButton" in the table above.

Mike

Anonymous said...

Its working fine for sharepoint 2007.Will it work for sharepoint 2010 aswell?

Mike Smith said...

Anonymous,

In general, yes it will work in 2010. Some of the IDs have been changed so you may need to add an "or" (||) to handle both names. See this article:
http://techtrainingnotes.blogspot.com/2011/04/sharepoint-2010-menu-ids.html

Mike

Robert R. said...

Didn't work for me for SharePoint 2013 using IE11. I had to overwrite the dom nodes outerHTML.
Example (not hiding the menu but giving it an other onclick action):
itm.outerHTML = itm.outerHTML.replace("onmenuclick", "onmenuclick=\"GoToPage('" + url + "');\" oldMenuClick");

Mike Smith said...

Robert,

Thanks for the code. 2013 changed much of the HTML in SharePoint.

Mike

Note to spammers!

Spammers, don't waste your time... all posts are moderated. If your comment includes unrelated links, is advertising, or just pure spam, it will never be seen.