Tuesday, December 6, 2011

Show or Hide SharePoint Ribbon Tab based on User Permissions

This week I wanted to figure out how to show or hide a custom developed SharePoint Ribbon Tab based on the permissions of a logged in SharePoint user.

I have a custom SharePoint 2010 Ribbon Tab with the title ‘Show or Hide Tab’ and I want to hide the tab if a current logged in user is a member of the ‘Root Visitors’ security group.

I do not want to hide the entire ribbon and I also do not want to hide only the inactive buttons. The ribbon with the ‘Documents’ and ‘Library’ tabs must be visible for all users and audience targeting must be applied to the new custom ribbon tab.

I can imagine that the requirement is quite a common one. You might want to develop a set of custom tabs which are only visible to users who are members of a specific SharePoint group.

I assume that you know how to develop a custom ribbon – if not please follow the great blog series by Chris O’Brien on Ribbon Customizations and ensure that your custom ribbon tab works before you continue with this tutorial.

clip_image001

I could not find a blog with an appropriate example on the web so I used a combination of a few blog posts and added my own logic.

I want to thank Chris O’Brien for his series on Ribbon Customizations and Tobias Lekman for his helpful blog post . Their contributions were extremely helpful during my research.

How it works:

I have a custom ribbon with the title ‘Show or Hide Tab’.I also have a SharePoint Group Called ‘Root Visitors’. I log in to SharePoint as a user who is not a member of this group.

clip_image002

I navigate to the Shared Documents library and do not see the custom ribbon tab.

clip_image003

Now I add the user to the security group

clip_image004

 …and I navigate back to the Shared Documents library. Now the custom ribbon tab is visible.

clip_image005

 Ok, so Let’s Get Started

Prerequisites (…you need the following in place before you start coding):

    1. the ID of the Ribbon Tab which you want to hide ( I created a custom ribbon tab –see elements file contents below)
    2. the name of the SharePoint Security Group which can see the ribbon item
    3. jquery-1.6.2.min.js (download from http://docs.jquery.com/Downloading_jQuery)
    4. jquery.SPServices-0.6.2.js - this is a jQuery library which abstracts SharePoint’s Web Services and makes them easier to use. It also includes functions which use the various Web Service operations to provide more useful (and cool) capabilities. It works entirely client side and requires no server install. http://spservices.codeplex.com

Development Tasks (…you will code the following):

    1. Construct the JQuery to hide the ribbon tab
    2. Register the JQuery to hide the ribbon tab
    3. Verify that it all works fine

 

Prerequisites:

1.       Get the ID of the Ribbon Tab which you want to hide:

If you have a custom ribbon tab then you can get the ID value from the Elements.xml file. In the example below the ID of my custom ribbon is ‘DemoHideRibbonTab’

       ?xml version="1.0" encoding="utf-8"?>

       <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

        <CustomAction

         Id="DemoHideRibbonTab"

As an alternative you can use the following handy piece of JQuery to view the IDs of all the Ribbon Tabs on a page.

Copy the JQuery code below and paste it inside a Content Editor Web Part on the SharePoint library AllItems.aspx page and save the page. 

<script type="text/javascript">

   $("a.ms-cui-tt-a").each(function ()

   {

     var objTabTitle = $(this).parent().attr("id");

     alert( objTabTitle );

   });

</script>

When you refresh the page the JQuery will iterate through all the ribbon tabs and display their IDs.

You should see the IDs of the different ribbon tabs:

clip_image006 

2.       Get the name of the SharePoint Security Group:

The security group for which you must hide the ribbon tab must be a SharePoint group –it’s simple, you must have the name of the group. 

3.       Download and distribute jquery-1.6.2.min.js

The jQuery library is a single JavaScript file, containing all of its common DOM, event, effects, and Ajax functions. It can be included within a SharePoint page by linking to a local copy.

Download jquery-1.6.2.min.js from http://docs.jquery.com/Downloading_jQuery and distribute into the 14-hive of your SharePoint web-front-end server.

Example: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\HideRibbonSample\Scripts\ jquery-1.6.2.min.js

4.       Download and distribute jquery.SPServices-0.6.2.js

This is a jQuery library which abstracts SharePoint’s Web Services and makes them easier to use. It also includes functions which use the various Web Service operations to provide more useful (and cool) capabilities. It works entirely client side and requires no server install.

Download jquery.SPServices-0.6.2.js from http://spservices.codeplex.com and distribute into the 14-hive of your SharePoint web-front-end server.

Exanple: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\HideRibbonSample\Scripts\ jquery.SPServices-0.6.2.js

 

Development Tasks:

1.       Construct the JQuery to hide the ribbon tab

We now have all the prerequisites in place and we can start coding the JQuery which will hide the ribbon tab.

Create a new empty file and save the file to the 14-hive of your SharePoint web-front-end server.

Exanple: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\HideRibbonSample\Scripts\HideRibbonSample.js 

Add the following JQuery to the file.

function checkIfUserIsInGroup()

{

$(document).ready(function() { $().SPServices({ 

      operation: "GetGroupCollectionFromUser", 

      userLoginName: $().SPServices.SPGetCurrentUser(), 

      async: false, 

      completefunc: function(xData, Status) { 

      if($(xData.responseXML).find("Group[Name='Root Visitors']").length == 1) 

         { 

                       return "true";

         } 

      else

         {

HideTab();

                       return "false";

         }

       } 

     });

     });

}

 

function HideTab()

{

$("a.ms-cui-tt-a").each(function ()

{

var objTabTitle = $(this).parent().attr("id");

if(objTabTitle == "DemoHideRibbonTab-title")

{

$(this).parent().hide();

}

});

}

 

var ribbonSelected;

function checkRibbonState() {

       var id = $("li.ms-cui-tt-s").attr("id");

        if (ribbonSelected != id)

       { 

              ribbonSelected = id;

              checkIfUserIsInGroup();

       }

}

 

function beginCheckRibbon()

{

var checkRibbonStateInterval = setInterval("checkRibbonState()", 10);

 }

$(document).ready(function ()

{

        setTimeout("beginCheckRibbon()", 1000);

});

 

2.       Register the JQuery as a custom action on the relevant ribbon tab

Open the elements.xml file in which your custom ribbon tab is defined.

You have to register the JQuery scripts in the correct sequence.

Use the ScriptLink class to register the following scripts:

1.       The jquery-1.6.2.min.js script.

2.       The jquery.SPServices-0.6.2.js script.

3.       Your custom JQuery Hide Ribbon script. 

 

<CustomAction Id="JohanJQuery.Script" Location="ScriptLink" ScriptSrc ="/_layouts/HideRibbonSample/Scripts/jquery-1.6.2.min.js" Sequence="100"/>

 

<CustomAction Id="SPS_SERVICE_JohanJQuery.Script" Location="ScriptLink" ScriptSrc ="/_layouts/HideRibbonSample/Scripts/jquery.SPServices-0.6.2.js" Sequence="101"/>

 

<CustomAction Id="JohanHideTab_JohanJQuery.Script" Location="ScriptLink" ScriptSrc ="/_layouts/HideRibbonSample/Scripts/HideRibbonSample.js" Sequence="102"/> 

 

My complete Ribbon Tab definition with the script registration is as follows:

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <CustomAction

    Id="DemoHideRibbonTab"

    Location="CommandUI.Ribbon"

    RegistrationId="101"

    RegistrationType="List">

    <CommandUIExtension>

      <CommandUIDefinitions>

        <CommandUIDefinition

          Location="Ribbon.Tabs._children">

          <Tab Id="DemoHideRibbonTab" Title="Show or Hide Tab" Description="Show or Hide Tab" Sequence="501">

            <Scaling

              Id="DemoHideRibbonTab.Scaling">

              <MaxSize

                Id="DemoHideRibbonTab.OneLargeGroupMaxSize"

                GroupId="DemoHideRibbonTab.OneLargeGroupExample"

                Size="OneLarge"/>

            </Scaling>

         

            <Groups Id="DemoHideRibbonTab.GeneralControls.Groups">

              <Group

                Id="DemoHideRibbonTab.OneLargeGroupExample"

                Description="Contains custom controls"

                Title="Show Message"

                Sequence="55"

                Template="Ribbon.Templates.OneLarge">

                <Controls Id="DemoHideRibbonTab.OneLargeGroupExample.Controls">

                  <Button

                      Id="DemoHideRibbonTab.OneLargeGroupExample.Controls.Button"

                      LabelText="Show Message"

                      Image16by16="/_layouts/images/newtargetapp16.png"

                      Image32by32="/_layouts/images/newtargetapp32.png"

                      Command="COB.Command.SayHello"

                      Sequence="10"

                      TemplateAlias="custLarge1" />

                </Controls>

              </Group>

            </Groups>

          </Tab>

        </CommandUIDefinition>

        <CommandUIDefinition Location="Ribbon.Templates._children">

          <GroupTemplate Id="Ribbon.Templates.OneLarge">

            <Layout

              Title="OneLarge"

              LayoutTitle="OneLarge">

              <Section Alignment="Top" Type="OneRow">

                <Row>

                  <ControlRef DisplayMode="Large" TemplateAlias="custLarge1" />

                </Row>

              </Section>

            </Layout>

          </GroupTemplate>

        </CommandUIDefinition>

      </CommandUIDefinitions>

      <CommandUIHandlers>

        <CommandUIHandler

       Command="COB.Command.SayHello"

       CommandAction="javascript:alert('Hello World');" />

      </CommandUIHandlers>

    </CommandUIExtension>

  </CustomAction>

 

  <CustomAction Id="JohanJQuery.Script" Location="ScriptLink" ScriptSrc ="/_layouts/HideRibbonSample/Scripts/jquery-1.6.2.min.js" Sequence="100"/>

  <CustomAction Id="SPS_SERVICE_JohanJQuery.Script" Location="ScriptLink" ScriptSrc ="/_layouts/HideRibbonSample/Scripts/jquery.SPServices-0.6.2.js" Sequence="101"/>

  <CustomAction Id="JohanHideTab_JohanJQuery.Script" Location="ScriptLink" ScriptSrc ="/_layouts/HideRibbonSample/Scripts/HideRibbonSample.js" Sequence="102"/>

</Elements>

 

3.       Verify that it works fine

Build, Package and Deploy your custom ribbon feature.

Deactivate and Activate the feature in your site and refresh the SharePoint page on which the ribbon should appear (because the registration ID of my ribbon is ‘101’ the page which I should see the ribbon tab is http://demoweb/Shared%20Documents/Forms/AllItems.aspx.

If I am a member of the ‘Root Visitors’ group then the tab is visible.

clip_image005 

If I am not a member of the ‘Root Visitors’ group then the tab is not visible.

clip_image003

 

Enjoy!!

 

References:

Once again, thanks for the contributions made by members of the community.

Chris O’Brien: Ribbon Customizations

Tobias Lekman: Hiding Inactive Ribbon Commands in SharePoint 2010  

 

6 comments:

Anonymous said...

Is it possible to utilise this functionality for a single button rather than for a tab?

JimK said...

This is what I'm trying to find. I'm currently deploying this on a custom list, but apparently when I select on list item, the tab would pop out.

Anonymous said...

Nice post...
Pls just change:
"userLoginName: $().SPServices.SPGetCurrentUser()," to
"userLoginName: $().SPServices.SPGetCurrentUser,",
lose 4h to fine where is problem in code.

Anonymous said...

Thanks Johan!

Anonymous said...

I did everything as it is written but custom Ribbon Tab is shown for all SP users...
SP version 2013. What could be wrong?

Unknown said...

Do not dwell in the past, do not dream of the future, concentrate the mind on the present moment. See the link below for more info.

#moment
www.ufgop.org



Post a Comment