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.}

Advertisements

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: