O365 SharePoint Suitenav: Add custom button

Today I want to show you, how you could add custom button to the right side of top Office 365 SharePoint SuiteNav / SuiteBar like in an image above.

For this suitenav we don’t have any official way in SharePoint 2016 like we have at SharePoint 2013 with SuiteLinks Delegate Controls.
Officially you could add only custom tiles on your App Launcher to the left side of SuiteNav named App Launcher Tiles – but only with SharePoint 2016 Feature Pack 1.

So we have to go in own way. I want to share with you how I have done this with JavaScript and a lil’bit hacking.
Just for information -> suitenav links are officially created with JavaScipt too.

All you need is one JavaScript file which run everytime any SharePoint page is loaded. So you have to add it into Master Page (on-prem) or you have to create SPFx Application Customizer (cloud).

In that script you have to put code like that below. Custom button is added between “our custom button START” and “our custom button END” comments.

As you can see you have to wait for suitenav.js file execution and then rewrite _o365sg2c.O365Shell._renderInternal$p render function. But first of all you have to call ClearSuiteLinksCache() function.

ClearSuiteLinksCache();

$(document).ready(function () {
    SP.SOD.executeFunc("suitenav.js", "_o365sg2c.O365Shell._renderInternal$p", function () {

        _o365sg2c._rightMenusMouseRenderer.render = function (j, i) {
            var a = document.createElement("span");
            a.className = "o365cs-nav-rightMenus";
            var b = document.createElement("div");
            b.className = "o365cs-nav-topItem";
            _o365sg2c._rightMenusMouseRenderer._renderShareButton$p(b, i);
            a.appendChild(b);
            var c = document.createElement("div");
            c.className = "o365cs-nav-topItem o365cs-rsp-off-hide o365cs-rsp-m-hide o365cs-rsp-tw-hide o365cs-rsp-tn-hideIfAffordanceOn";
            _o365sg2c._rightMenusMouseRenderer._renderAffordance$p(c);
            a.appendChild(c);
            if (_o365sg2c.O365Shell._$$pf_ShellData$p.WorkloadLinks || _o365sg2c.O365Shell._$$pf_ShellData$p.PinnedApps) {
                var e = document.createElement("div");
                e.className = "o365cs-nav-topItem o365cs-rsp-off-hide o365cs-rsp-m-hide o365cs-rsp-tn-hideIfAffordanceOff";
                _o365sg2c._rightMenusMouseRenderer._renderNavMenu$p(e);
                a.appendChild(e);
            }

			// our custom button START
            var rr87 = document.createElement("div");
            rr87.className = "o365cs-nav-topItem o365cs-rsp-tn-hideIfAffordanceOff";
            _o365sg2c._rightMenusMouseRenderer._renderNotificationCenter$p(rr87);
            a.appendChild(rr87);
			// our custom button END

            var d = document.createElement("div");
            d.className = "o365cs-nav-topItem o365cs-rsp-tn-hideIfAffordanceOff";
            _o365sg2c._rightMenusMouseRenderer._renderSettings$p(d);
            a.appendChild(d);
            var g = document.createElement("div");
            g.className = "o365cs-nav-topItem o365cs-rsp-tn-hideIfAffordanceOff";
            _o365sg2c._rightMenusMouseRenderer._renderHelp$p(g);
            a.appendChild(g);

            if (_o365sg2c.O365Shell._$$pf_ShellData$p.UserDisplayName) {
                var h = document.createElement("div");
                h.className = "o365cs-nav-topItem o365cs-rsp-tn-hideIfAffordanceOn";
                _o365sg2c._rightMenusMouseRenderer._renderMe$p(h);
                a.appendChild(h);
            }
            if (_o365sg2c.O365Shell._$$pf_ClientData$p.SignInLink) {
                var f = document.createElement("div");
                f.className = "o365cs-nav-topItem o365cs-rsp-tn-hideIfAffordanceOn";
                _o365sg2c._rightMenusMouseRenderer._renderSignIn$p(f);
                a.appendChild(f);
            }
            j.appendChild(a);
        };

        _o365sg2c._rightMenusMouseRenderer._renderNotificationCenter$p = function (c) {
            var b = _o365sg2c._controls.button();
            b.id = "O365_MainLink_NotificationCenter";
            _o365sg2c._domElementExtensions.addClass(b, "o365cs-nav-item o365cs-nav-button o365cs-topnavText ms-bgc-tdr-h");
            _o365sg2c._domElementExtensions.ariaHasPopup(b, true);
            _o365sg2c._domElementExtensions.ariaLabel(b, "Notification Center");
            _o365sg2c._domElementExtensions.role(b, "menuitem");
            var f = _o365sg2c._controls.icon(new _o365sg2cm.ShellIconId("bell", 18));
            b.appendChild(f);

            var rr87Nr = $("<div id='O365_MainLink_NotificationCenter_Nr' style='display:none; right:7px; top:8px; position:absolute; border-radius:16px; background-color:white; color:black; min-width:16px; height:16px; text-align:center;'></div>")[0];
            b.appendChild(rr87Nr);

            c.id = "O365_MainLink_NotificationCenter_OuterDiv";
            c.appendChild(b);

            NotificationCenter_GetMyNotifications(c, b);
        };
    });
});

function NotificationCenter_GetMyNotifications(c, b) {
    var dfd = jQuery.Deferred();

    // dobi število novih zadev
    $.ajax({
        url: "get content for your dropdown of suitenav button",
        data: JSON.stringify({
            outerDivId: c.id
        }),
        type: "POST",
        cache: false,
        dataType: 'json',
        contentType: "application/json; charset=utf-8"
    })
    .done(function (data) {
        var rr87Nr = $("div#O365_MainLink_NotificationCenter_Nr");
        if (data.Data.nrOfNewNotifications > 0) {
            rr87Nr.css("display", "block");
        } else {
            rr87Nr.css("display", "none");
        }
        rr87Nr.text(data.Data.nrOfNewNotifications);

        var a = _o365sg2c._controls.contextMenu(b);
        a.style[_o365sg2c.O365Shell._$$pf_ClientData$p.IsRTL ? "left" : "right"] = "-1px";
        a.style["max-width"] = "460px";

        var rr87 = $("<div style='padding:0px; margin:10px; font-size:12px; text-align:left;'>" + data.Data.render + "</div>")[0];
        a.appendChild(rr87);

        c.style.position = "relative";
        c.appendChild(a);

        dfd.resolve(data.Data.nrOfNewNotifications);
    })
    .fail(function () {
        dfd.reject(-1);
    });

    return dfd.promise();
}

And that is all – “simple as pasulj” 🙂

Happy coding folks!

Cheers!
Gašper Rupnik

{End.}

2 thoughts on “O365 SharePoint Suitenav: Add custom button

Add yours

  1. Thanks for this post. I had to make some modifications to the script to make it work for me, since my script would always run after the initial suitenav render. First, I had to re-render the suitenav in my $(document).ready function:

    //Re-render suitenav
    _o365sg2c._sharedHeaderMouseRenderer.render(_o365sg2c.O365Shell._$$pf_TopElement$p); //TopElement = #suiteBarTop

    Secondly, the tag that styles the suitenav wouldn’t be loaded. Here’s the fix (run this code after the render() function above):

    //Generates the CSS that goes inside the tag for suitenav
    var additionalCssText;
    SuiteNavTheming.WithSuiteThemingCss(function (suiteThemingCss) {
    additionalCssText = suiteThemingCss;
    });

    //Mostly-native SP code that generates + injects the tag for suitenav
    var suiteNavRenderingDiv = document.getElementById(“suiteBarTop”);
    CSSUtil.RemoveClass(suiteNavRenderingDiv, “ms-TopBarBackground-bgColor”);
    if (Boolean(additionalCssText) && suiteNavRenderingDiv != null) {
    var firstChildOfSuiteLinksDiv = suiteNavRenderingDiv.firstChild;
    var styleElement = document.createElement(“style”);

    styleElement.id = “SuiteNavThemeStyle”;
    styleElement.type = “text/css”;
    SPThemeUtils.ReplaceCssTextForElement(styleElement, additionalCssText);
    if (firstChildOfSuiteLinksDiv != null) {
    suiteNavRenderingDiv.insertBefore(styleElement, firstChildOfSuiteLinksDiv);
    }
    else {
    suiteNavRenderingDiv.appendChild(styleElement);
    }
    }

  2. Hi, what is the url format to display the drop-down menu?
    In this line: url: “get content for your dropdown of suitenav button”
    Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: