Option to Show the SharePoint 2010 ribbon when hidden by default

At work we’ve been working on a new intranet project with SharePoint 2010 being our platform of choice. This site is mainly a view only type of site but we also wanted users to have the ability to create alerts and other similar activities. One of the requirements of this project was to remove the ribbon on every page. This brought complications for SP 2010 because so much is done in the ribbon. We decided to hide the ribbon by default and show a caret (or chevron) at the upper right of the screen to allow the ribbon to be shown and hidden by all users.

There are many solutions I’ve seen on the interwebs around hiding the ribbon for some and not hiding it for others so they were a good starting point for us but I couldn’t find anyone talking about having the ribbon being optional for everyone. This brought a few challenges such as keeping the ribbon shown on postbacks and displaying the ribbon when clicking on a list webpart.

The first challenge was easy to accomplish. Using a cookie to set whether the user currently has the ribbon open or closed allows the ribbon to “remember” that setting as a user is browsing and editing items in SP.

 var val = 'False';
 try { val = GetCookie('ShowHideRibbon'); } catch (err) { }
 var showRibbon = document.getElementById('ShowRibbon');
 var hideRibbon = document.getElementById('HideRibbon');
 var ribbon = document.getElementById('s4-ribbonrow');

 if (val == 'True') {
  ribbon.style.display = 'block'; ;
  if (showRibbon != null)
   showRibbon.style.display = 'none';
  if (hideRibbon != null)
   hideRibbon.style.display = 'block';
 }
 else {
  if (hideRibbon != null)
   hideRibbon.style.display = 'none';
  if (showRibbon != null)
   showRibbon.style.display = 'block';
 }

The second issue was more difficult and wasn’t initially obvious. The issue was that in SP 2010, when you click on a list view webpart it automatically activates the ribbon. This is great when using the checkboxes to select items or documents. Normal behavior is when the ribbon is activated it will hide the site level breadcrumbs / title bar and the top navigation to use that space for the ribbon itself. But with the ribbon being hidden, this causes the whole top part of the page to disappear including our caret to reopen the ribbon.

This resulted in a very bad user experience. I spent a lot of time debugging JavaScript trying to find the right SP JS function to “override” in order to tap into this action and unhide the ribbon first before the ribbon is activated. I got no where asking the google and ended up searching all of the SharePoint JS debug files and finally finding the function OnRibbonMinimizedChanged in init.js.

 function OnRibbonMinimizedChanged(ribbonMinimized)
 {ULSxSy:;
  var ribbonElement=GetCachedElement("s4-ribbonrow");
  var titleElement=GetCachedElement("s4-titlerow");
  if (ribbonElement)
  {
   ribbonElement.className=ribbonElement.className.replace("s4-ribbonrowhidetitle", "");
   if(titleElement)
   {
    titleElement.className=titleElement.className.replace("s4-titlerowhidetitle", "");
    if (ribbonMinimized)
    {
     titleElement.style.display="block";
    }
    else
    {
     titleElement.style.display="none";
    }
   }
  }
...

I overrode the function with my own where I unhide the ribbon and then called the original function in init.js.

 function SetupEventHandler_HideShowRibbon() {
  if (original_functionEvent == null) {
   original_functionEvent = OnRibbonMinimizedChanged;
  }
  OnRibbonMinimizedChanged = OnRibbonMinimizedChanged_Delegate;
 }

 function OnRibbonMinimizedChanged_Delegate(ribbonMinimized) {
  if (IsRibbonHidden_HideShowRibbon() &&
   false == ribbonMinimized) {
   showRibbon__HideShowRibbon();
  }
  original_functionEvent(ribbonMinimized);
 }

I put all of my JS code into a user control which I added to my masterpage inside a SP delegate control. This allows me to use features to swap this code out with something different. For instance you could have a user control which can hide the ribbon by default and only show the caret / chevron when a user has certain permissions.

<%@ Control Language="C#"    compilationMode="Always" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="uc" TagName="ShowHideRibbonCore" src="~/_controltemplates/Custom/ShowHideRibbon.ascx" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<!-- Show / Hide Ribbon -->
<Sharepoint:SPSecurityTrimmedControl ID="SecurityTrimHideShowRibbonCurrentItem" runat="server" PermissionsString="AddAndCustomizePages" PermissionContext="CurrentItem">
    <uc:ShowHideRibbonCore ID="HideShowRibbonCoreCurrentItem" runat="server"/>
</Sharepoint:SPSecurityTrimmedControl>
<Sharepoint:SPSecurityTrimmedControl ID="SecurityTrimHideShowRibbonCurrentWeb" runat="server" PermissionsString="AddAndCustomizePages" PermissionContext="CurrentSite">
    <uc:ShowHideRibbonCore ID="HideShowRibbonCoreCurrentSite" runat="server"/>
</Sharepoint:SPSecurityTrimmedControl>

 

The code that we ended up doing is below. We hide the ribbon using CSS in the user control and then output the javascript.

<%@ Control Language="C#"    compilationMode="Always" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="uc" TagName="ShowHideRibbon" src="~/_controltemplates/Custom/ShowHideRibbon.ascx" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<!-- Hide Ribbon -->
<style type="text/css">
#s4-ribbonrow
{
    display:none;
}
</style>
<uc:ShowHideRibbonCore ID="HideShowRibbon" runat="server"/>

And here is my full code that I put in the user control ShowHideRibbon.ascx

<%@ Control Language="C#"    compilationMode="Always" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<!-- Show / Hide Ribbon Core -->
<script type="text/javascript">
    if (testForRibbon_HideShowRibbon == null) {
        var original_functionEvent = null;

        var testForRibbon_HideShowRibbon = function () {

            if (IsRibbonHidden_HideShowRibbon()) {
                ExecuteOrDelayUntilScriptLoaded(SetupEventHandler_HideShowRibbon, "init.js");

                var val = 'False';
                try { val = GetCookie('ShowHideRibbon'); } catch (err) { }
                var showRibbon = document.getElementById('ShowRibbon');
                var hideRibbon = document.getElementById('HideRibbon');
                var ribbon = document.getElementById('s4-ribbonrow');

                if (val == 'True' ||
                   (IsRibbonHidden_HideShowRibbon() &&
                    IsTitleRowHidden_HideShowRibbon())) {
                    ribbon.style.display = 'block';
                    if (showRibbon != null)
                        showRibbon.style.display = 'none';
                    if (hideRibbon != null)
                        hideRibbon.style.display = 'block';
                }
                else {
                    if (hideRibbon != null)
                        hideRibbon.style.display = 'none';
                    if (showRibbon != null)
                        showRibbon.style.display = 'block';
                }
            }
        }

        function IsRibbonHidden_HideShowRibbon() {
            return IsElementHidden_HideShowRibbon('s4-ribbonrow');
        }

        function IsTitleRowHidden_HideShowRibbon() {
            return IsElementHidden_HideShowRibbon('s4-titlerow');
        }

        function IsElementHidden_HideShowRibbon(elementId) {
            var computedStyle = function (el, style) {
                var cs;
                if (typeof el.currentStyle != 'undefined') {
                    cs = el.currentStyle;
                } else {
                    cs = document.defaultView.getComputedStyle(el, null);
                }
                return cs[style];
            }
            var element = document.getElementById(elementId);
            if (element != null &&
				computedStyle(element, 'display') == 'none') {
                return true;
            }
            return false;
        }

        function SetupEventHandler_HideShowRibbon() {
            if (original_functionEvent == null) {
                original_functionEvent = OnRibbonMinimizedChanged;
            }
            OnRibbonMinimizedChanged = OnRibbonMinimizedChanged_Delegate;
        }

        function OnRibbonMinimizedChanged_Delegate(ribbonMinimized) {
            if (IsRibbonHidden_HideShowRibbon() &&
				false == ribbonMinimized) {
                showRibbon__HideShowRibbon();
            }
            original_functionEvent(ribbonMinimized);
        }

        function makeDoubleDelegate_HideShowRibbon(function1, function2) {
            return function () {
                if (function1)
                    function1();
                if (function2)
                    function2();
            }
        }

        function getDocHeight_HideShowRibbon() {
            var D = document;
            return Math.max(
            Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
            Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
            Math.max(D.body.clientHeight, D.documentElement.clientHeight)
        );
        }

        function showRibbon__HideShowRibbon() {
            var newHeight = getDocHeight_HideShowRibbon();
            var ribbon = document.getElementById('s4-ribbonrow');
            ribbon.style.display = 'block';
            try {
                SetCookie('ShowHideRibbon', 'True', '/');
            } catch (err) { };
            document.getElementById('ShowRibbon').style.display = 'none';
            document.getElementById('HideRibbon').style.display = 'block';

            newHeight = newHeight - ribbon.offsetHeight;
            var ver = navigator.appVersion;
            if (ver.indexOf("MSIE") != -1) {
                newHeight = newHeight - 4;
            }
            document.getElementById('s4-workspace').style.height = newHeight + 'px';
        }

        function hideRibbon__HideShowRibbon() {
            document.getElementById('s4-ribbonrow').style.display = 'none';
            try {
                SetCookie('ShowHideRibbon', 'False', '/');
            } catch (err) { };
            document.getElementById('HideRibbon').style.display = 'none';
            document.getElementById('ShowRibbon').style.display = 'block';
            var newHeight = getDocHeight_HideShowRibbon();
            var ver = navigator.appVersion;
            if (ver.indexOf("MSIE") != -1) {
                newHeight = newHeight - 4;
            }
            document.getElementById('s4-workspace').style.height = newHeight + 'px';
        }

        window.onload = makeDoubleDelegate_HideShowRibbon(window.onload, testForRibbon_HideShowRibbon);

        document.write('<a id="ShowRibbon" href="#" onclick="showRibbon__HideShowRibbon(); return false;"><img src="/_layouts/images/downarrow.png" title="Show Ribbon" border="0"/></a>');
        document.write('<a id="HideRibbon" href="#" onclick="hideRibbon__HideShowRibbon(); return false;"><img src="/_layouts/images/uparrow.png" title="Hide Ribbon" border="0"/></a>');
    }
</script>
<style type="text/css">
#ShowRibbon
{
	position:fixed;
	top:0;
	right:15px;
	display: none;
	z-index: 100;
}

#HideRibbon
{
	position:fixed;
	top:45px;
	right:15px;
	display: none;
	z-index:100;
}
</style>

Update 4-6-2012

I realized there are instances when visiting a page (like dispform.aspx) where the ribbon is supposed to be open by default but instead showed the same bad behavior from above. I’ve updated my code above to now check if s4-titlerow is hidden in addtion to the s4-ribbonrow. If so, I unhide the ribbon. But I do not cookie this change. The only time this app “remembers” your setting is if you actually click the up or down arrow at the top right.

16 Replies to “Option to Show the SharePoint 2010 ribbon when hidden by default”

  1. Good article!
    Could you let us know how you are implementing GetCookie() and SetCookie()?
    I have a similar implementation of the SharePoint toggle to hide the ribbon, but was having some issues getting my SetCookie implementation to work properly on IE and Chrome (worked fine in Firefox).

    Thanks!
    -Victor

  2. I am using the GetCookie() and SetCookie() functions that SharePoint provides. SetCookie is in core.js and GetCookie() is in init.js so you can find how MS implemented it there.

  3. Hi Steve,

    I was trying to implement this without using the Controls, by placing the JS code in the MasterPage.

    However, I have run into a few issues.

    If I load it with the chevron’s the page respects the cookie, the doubledelegate triggers, but the page doesn’t scroll and content is cuttoff.

    If I remove the document.write for the chevron’s the page scrolls, but the cookie never gets read because the double delegate doesn’t trigger.

    I am using the codeplex Publishing Starterpage, using a fixed width with “s4-nosetwidth”.

    Any thoughts on how to correct this?

    Thanks!
    -Victor

  4. FYI

    The workaround I have used for my previous comment is to remove the additional document.write and added the testForRibbon_HideShowRibbon() call in the body onload declaratively.

    -Victor

  5. Hi I am kinda a new developer.
    I am trying your solution.
    Created a visual web part project and added the above code in the user control file and deployed in the farm when added the web part it doesn’t displays anything. i checked the URL of the image in the code that looks fine to me.
    I tried to register it as a prefix in Master page and added in one of the div TOO but still it doesn’t works i don’t see anything.
    Is there a way i can make it work in my environment.
    I am still not able to make it work.
    this solutions looks very promising to me in my scenario…
    IF i can get it done please any help…..

  6. Roy, the way I implemented mine was creating a delegate control in my masterpage and then using a feature to use my hide ribbon ascx for that delegate control. There should be plenty of examples on how to do this on the interwebs. A webpart is not the way to go here.

  7. I am trying something like this,
    i have achieved almost everything,
    but my dialog windows are not rendering well.
    can you put some light,please,

    by default i have hidden the ribbon row and title row from the page and added fixed width to the s4-workspace,
    i have these style classes in the master page

    [CODE]

    body.v4master {
    height: auto !important;
    overflow: auto !important;
    width: auto !important;
    }

    body #s4-workspace {
    left: inherit !important;
    overflow-x: inherit !important;
    overflow-y: inherit !important;
    overflow: inherit !important;
    position: inherit !important;
    }

    .s4-ca
    {
    margin-left:0px;
    }

    .ms-dialog .globalWrapper{
    margin-left:0 !important;
    margin-right:0 !important;
    min-height:0 !important;
    min-width:0 !important;
    width:auto !important;
    height:auto !important;
    padding: 0px !important;
    overflow:visible!important;
    }

    .ms-dialog .contentWrapper{
    padding-bottom: 4px;
    }

    [/CODE]
    then i have the user control to hide and display
    [CODE] _spBodyOnLoadFunctionNames.push(“checkcookie”);
    function checkcookie() {
    var val = GetCookie(‘ShowHideRibbon’);
    if (val == ‘True’) {
    $(“#s4-ribbonrow”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘width’, ‘135px’);
    $(“.s4-ca “).css(‘margin-left’, ‘135px’); //change width of margin-left to fit your leftpanel
    $(“#hide”).css(‘display’, ‘block’);
    $(“#show”).css(‘display’, ‘none’);

    }

    if (val == ‘False’) {
    $(“#s4-ribbonrow”).css(‘display’, ‘none’);
    $(“#s4-leftpanel”).css(‘display’, ‘none’);
    $(“.s4-ca “).css(‘margin-left’, ‘0px’);
    $(“#show”).css(‘display’, ‘block’);
    $(“#hide”).css(‘display’, ‘none’);

    }
    }

    //Display the Ribbon and Set Cookie Value to True
    function show() {
    $(“#s4-ribbonrow”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘width’, ‘135px’);
    $(“.s4-ca “).css(‘margin-left’, ‘135px’); //change width of margin-left to fit your leftpanel
    $(“#hide”).css(‘display’, ‘block’);
    $(“#show”).css(‘display’, ‘none’);
    SetCookie(‘ShowHideRibbon’, ‘True’, ‘/’)

    }
    //Hide the Ribbon and set cookie value to false
    function hide() {
    $(“#s4-ribbonrow”).css(‘display’, ‘none’);
    $(“#s4-leftpanel”).css(‘display’, ‘none’);
    $(“.s4-ca “).css(‘margin-left’, ‘0px’);
    $(“#show”).css(‘display’, ‘block’);
    $(“#hide”).css(‘display’, ‘none’);
    SetCookie(‘ShowHideRibbon’, ‘False’, ‘/’)

    }

    [/CODE]
    but i dont want anything to be changed in the pop up windows….any idea how can i achieve this,
    i get scrolls in pop up windows which is
    vertical in IE and in both sides in FireFox,
    any help would be highly appreciated

  8. i am implementing something like this.
    i have j query in my user control which shows and hides the ribbon.
    my problem is when i travel the pages then every time it reloads the ribbon.
    i wanted to make it persistent so that once the ribbon is enabled it remains enabled unless user hides it.
    so what i am looking is once the ribbon is loaded then until it is hidden the page doesn’t reloads it again.
    here is my code any idea….
    [CODE]

    //var url = this.parent.url;

    // Check the Cookie of the current Page

    _spBodyOnLoadFunctionNames.push(“checkcookie”);

    function checkcookie() {
    var isInIFrame = (window.location != window.parent.location) ? true : false;

    if (!isInIFrame) {

    var val = GetCookie(‘ShowHideRibbon’);

    if (val == ‘True’) {
    $(“#s4-ribbonrow”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘width’, ‘135px’);
    $(“.s4-ca “).css(‘margin-left’, ‘135px’); //change width of margin-left to fit your leftpanel
    $(“#hide”).css(‘display’, ‘block’);
    $(“#show”).css(‘display’, ‘none’);

    }

    if (val == ‘False’) {
    $(“#s4-ribbonrow”).css(‘display’, ‘none’);
    $(“#s4-leftpanel”).css(‘display’, ‘none’);
    $(“.s4-ca “).css(‘margin-left’, ‘0px’);
    $(“#show”).css(‘display’, ‘block’);
    $(“#hide”).css(‘display’, ‘none’);

    }
    }

    }

    //Display the Ribbon and Set Cookie Value to True
    function show() {

    $(“#s4-ribbonrow”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘display’, ‘block’);
    $(“#s4-leftpanel”).css(‘width’, ‘135px’);
    $(“.s4-ca “).css(‘margin-left’, ‘135px’); //change width of margin-left to fit your leftpanel
    $(“#hide”).css(‘display’, ‘block’);
    $(“#show”).css(‘display’, ‘none’);
    SetCookie(‘ShowHideRibbon’, ‘True’, ‘/’)

    }
    //Hide the Ribbon and set cookie value to false
    function hide() {

    $(“#s4-ribbonrow”).css(‘display’, ‘none’);
    $(“#s4-leftpanel”).css(‘display’, ‘none’);
    $(“.s4-ca “).css(‘margin-left’, ‘0px’);
    $(“#show”).css(‘display’, ‘block’);
    $(“#hide”).css(‘display’, ‘none’);
    SetCookie(‘ShowHideRibbon’, ‘False’, ‘/’)

    }

    Welcome

    Welcome

    [/CODE]

  9. Hi Dustin,This information is gereanlly applicable for situations where you are using SharePoint hosted by a 3rd-party (i.e. you are not using integrated Active Directory authentication because your local computer is not in the same domain as the server running SharePoint). If your SharePoint site is hosted off-site, it should not matter whether they are in your office or at home, as it is still accessed the same. So I don’t have any specific advice for your situation, as there could be a lot of different factors involved. Good luck; I hope you are able to work through the problem!

  10. Is it possible to use JavaScript or jQuery to capture and I click event to a web part and then store that in a Boolean variable. This variable within the passed into a cookie to display the ribbon? I’m currently using a similar solution created by another SharePoint developer, located at the following URL: http://www.blogger.com/comment.g?blogID=7599218781305366419&postID=2879781993148375516&page=1&token=1349108966939 , which is very similar to your example. What I like to do is capture that click event of the web part to unhide the ribbon. Its current state in order to unhide the ribbon I need to press CTRL-G keys. Sore right now if I were to click on a calendar web part I would not be able to see the ribbon controls because the ribbon is still hidden. So I would like to continue using this example but also add the additional functionality of when a web part receives focus to unhide the ribbon. Do you have any suggestions of how I could accomplish this?

  11. I am using a similar cookie technique, but the ribbon hide/show is activated by a keyboard shortcut CTRL-G. I am having difficulty showing the OOTB ribbon functionality to display the ribbon when a web part receives focus, such as the calendar web part. By using the particular keyboard cookie solution, I need to press the keyboard keys even after clicking on the web part to show the ribbon.Is there a way around this? I will be glad to post the source URL, but I don’t want my question removed because the URL is posted.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*