3

I am trying to find the Top Navigation menu elements that are in the top part of my master page. So at the bottom of my master page I have added a script to fine the element on the page as follows:

var menulist = document.getElementById("zz14_RootAspMenu");

However, the value of menulist is always undefinded. If appears the content page has not finished loaded yet.

I have tried the following to delay the execution of the script but none have worked so far:

SP.SOD.executeFunc('sp.js', function () 
ExecuteOrDelayUntilScriptLoaded(processmenu(), "sp.js");
$(document).ready(function () 

Any suggestions would be greatly appreciated.

UPDATE ----- Here is the html from the rendered page that contains the element I an trying to get a reference to:

<div class=" noindex ms-core-listMenu-horizontalBox" id="zz13_V4QuickLaunchMenu" onclick="return AjaxNavigate$OnClickHook(event, this);">
    <ul class="root ms-core-listMenu-root static" id="zz14_RootAspMenu">
        <li class="static selected"><a tabindex="0" class="static selected menu-item ms-core-listMenu-item ms-displayInline ms-core-listMenu-selected ms-navedit-linkNode" href="/"><span class="additional-background ms-navedit-flyoutArrow"><span class="menu-item-text">Home</span><span class="ms-hidden">Currently selected</span></span></a></li><li class="static"><a tabindex="0" class="static menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" href="/SitePages/Association.aspx"><span class="additional-background ms-navedit-flyoutArrow"><span class="menu-item-text">Association</span></span></a></li><li class="static"><a tabindex="0" class="static ms-quicklaunch-dropNode menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode ms-droppable" aria-dropeffect="move" href="/SitePages/Board of Directors.aspx" DropId="4"><span class="additional-background ms-navedit-flyoutArrow"><span class="menu-item-text">Board</span></span></a></li><li class="static dynamic-children"><span tabindex="0" class="static dynamic-children menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode"><span class="additional-background ms-navedit-flyoutArrow dynamic-children" aria-haspopup="true"><span class="menu-item-text">Recent</span></span></span><ul class="dynamic">
            <li class="dynamic"><a tabindex="0" class="dynamic ms-quicklaunch-dropNode menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode ms-droppable" aria-dropeffect="move" href="/Policies/Forms/AllItems.aspx" DropId="5"><span class="additional-background ms-navedit-flyoutArrow"><span class="menu-item-text">Policies Library</span></span></a></li><li class="dynamic"><a tabindex="0" class="dynamic ms-quicklaunch-dropNode menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode ms-droppable" aria-dropeffect="move" href="/Contracts/Forms/ActiveContracts.aspx" DropId="6"><span class="additional-background ms-navedit-flyoutArrow"><span class="menu-item-text">Contracts Library</span></span></a></li>
        </ul></li><li class="static ms-verticalAlignTop ms-listMenu-editLink ms-navedit-editArea"><span class="ms-navedit-editSpan" id="zz13_V4QuickLaunchMenu_NavMenu_Edit"><a class="ms-navedit-editLinksText" id="zz13_V4QuickLaunchMenu_NavMenu_EditLinks" onclick="g_QuickLaunchMenu = null; EnsureScriptParams('quicklaunch.js', 'QuickLaunchInitEditMode', 'zz13_V4QuickLaunchMenu', 1, 2, 0, 'sid:1025'); cancelDefault(event); return false;" href="#"><span class="ms-displayInlineBlock"><span class="ms-navedit-editLinksIconWrapper ms-verticalAlignMiddle"><img class="ms-navedit-editLinksIcon" src="/_themes/6/spcommon-B35BB0A9.themedpng?ctag=8"></span><span class="ms-metadata ms-verticalAlignMiddle">Edit Links</span></span></a><span class="ms-navedit-menuLoading ms-hide" id="zz13_V4QuickLaunchMenu_NavMenu_Loading"><a title="This animation indicates the operation is in progress. Click to remove this animated image." id="zz13_V4QuickLaunchMenu_NavMenu_GearsLink" onclick="HideGears(); return false;" href="#"><img id="zz13_V4QuickLaunchMenu_NavMenu_GearsImage" src="/_layouts/15/images/loadingcirclests16.gif?rev=23"></a></span><div class="ms-navedit-errorMsg" id="zz13_V4QuickLaunchMenu_NavMenu_ErrorMsg">

        </div></span></li>
    </ul>
</div>

UPDATE -- So have created a js file that I am trying to have run after the content of the master page loads using the RegisterModuleInit function. All my code is below:

Type.registerNamespace('MenuStuff')
MenuStuff.Functions = MenuStuff.Functions || {};
MenuStuff.ibUserInRole = false;

MenuStuff.Functions.menutohide = function (menutext) {
    var menulist = document.getElementById("zz14_RootAspMenu");

    alert("menulist :" + menulist);
    // Iterate LIs
    for (var itemi = 0; itemi < menulist.childNodes.length; itemi++) {
        var item = menulist.childNodes[itemi];
        if (item.nodeName == "LI" && item.innerHTML.indexOf(menutext) !== -1) {
            item.style.display = "none";
            break;
        }
    }
}

MenuStuff.Functions.checkRights = function (groupId) {
    try {
        MenuStuff.ibUserInRole = false;
        var userId = _spPageContextInfo.userId;
        var requestHeaders = { "accept": "application/json; odata=verbose" };

        $.ajax({
            url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/sitegroups(" + groupId + ")/users/getbyid(" + userId + ")",
            contentType: "application/json;odata=verbose",
            headers: requestHeaders,
            success: userInRole,
            error: userNotInRole
        });
        function userInRole(data, request) {
            // if we reach here, the current user belongs to the group Id 7 for the example
            MenuStuff.ibUserInRole = true;
        }
        function userNotInRole(error) {
            MenuStuff.ibUserInRole = false;
        }
    }
    catch (err) {
        alert("Error: " + err);
    }
}

MenuStuff.Functions.processmenu = function () {
    //error here
    MenuStuff.Functions.checkRights(6);  
    if (MenuStuff.ibUserInRole == false) {
        MenuStuff.Functions.menutohide("Board");
    }
}

RegisterModuleInit(
    _spPageContextInfo.siteServerRelativeUrl + 'Site Assets/newmenuscript.js',
    MenuStuff.Functions.processmenu);

alert("Before ProcessMenu again");
MenuStuff.Functions.processmenu();

 

 

I am using an Ajax Namespace per the information in this article [http://www.wictorwilen.se/the-correct-way-to-execute-javascript-functions-in-sharepoint-2013-mds-enabled-sites][1]

However my menulist is still null. Any suggestions??

UPDATE: I used the sample code the Alan provided and added the following to the end of my master page right before the end body tag. I updated the element to find as the ID of the item had changed.

<script type="text/javascript">
    _spBodyOnLoadFunctionNames.push("menuToHide");

    function menuToHide()
    { 
        var menulist = document.getElementById("zz13_V4QuickLaunchMenu");
        alert("menulist: " + menulist); 
    }
</script>

With this code, when Minimal Download Strategy (MDS) was enabled, the alert never occurred. When I disabled MDS, the alert worked. Any suggestions?

6
  • Can you post a snippet of HTML that shows the zz14_RootAspMenu element you are trying to retrieve? Is this element loaded when the page is rendered, or loaded dynamically? Commented Aug 10, 2017 at 16:55
  • Is this SP 2010 or 2013?
    – Graham
    Commented Aug 10, 2017 at 17:36
  • SP Foundation 2013 - Oslo Master Page. I will update the question also Commented Aug 10, 2017 at 19:08
  • Paste a full snippet of your javascript code also. Commented Aug 10, 2017 at 19:28
  • Jim I posted the line of code that is generating the error. It is the get element by ID. I know this works correctly because if I copy the HTML I provided into a HTML page in Visual Studio, remove all the CSS Class information, then add the get element by ID line in a script block at the end of the page, I can debug the page and it finds the element.. Commented Aug 10, 2017 at 19:57

2 Answers 2

1

I could not get anything to fire AFTER all the content was loaded. What I had to do was use a JavaScript setTimeout function and wait for the content to finish loading. For anyone that this can help, my final code is below. I placed in a .js file in my Site Assets library and included it after the jquery library at the end of my Oslo master page. So far things seem to be working

var iobj_menuList = null;
var ii_Count = 0;
var ib_UserIsAdmin = false;
var ib_UserIsARB = false;
var is_BoardMenuItem = '<li class="static"><a tabindex="0" class="static menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" href="/Site Board Pages/Board Of Directors.aspx"><span class="additional- background ms- navedit - flyoutArrow"><span class="menu- item - text">Board</span></span></a></li>';
var is_ARBMenuItem = '<li class="static"><a tabindex="0" class="static menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" href="/Site ARB Pages/Architectural Review Board.aspx"><span class="additional- background ms- navedit - flyoutArrow"><span class="menu- item - text">ARB</span></span></a></li>';

function checkRights() {
    try {
        var userId = _spPageContextInfo.userId;
        var requestHeaders = { "accept": "application/json; odata=verbose" };
        var groupID1 = 6;

        $.ajax({
            url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/sitegroups(" + groupID1 + ")/users/getbyid(" + userId + ")",
            contentType: "application/json;odata=verbose",
            headers: requestHeaders,
            success: userIsAdmin,
            fail: userNotAdmin,
            error: userNotAdmin
        });

        function userIsAdmin(data, request) {
            // if we reach here, the current user belongs to the group Id 7 for the example
            ib_UserIsAdmin = true;
            processmenu();
        }
        function userNotAdmin() {
            var groupID2 = 35;
            $.ajax({
                url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/sitegroups(" + groupID2 + ")/users/getbyid(" + userId + ")",
                contentType: "application/json;odata=verbose",
                headers: requestHeaders,
                success: userIsARB,
                fail: UserNotInARB,
                error: UserNotInARB
            });
            function userIsARB(data, request) {
                // if we reach here, the current user belongs to the group Id 7 for the example
                ib_UserIsARB = true;
                processmenu();
            }
            function UserNotInARB(error) {
                //user is not a member
            }
        }
        function AdminPermissionError(error) {
            alert("AdminPermissionError: " + error);
        }

    }
    catch (err) {
        alert("Error: " + err);
    }
}


function processmenu() {

    setTimeout(function () {
        if ($(".ms-quickLaunch") === "undefined" || ii_Count > 10) {
            ii_Count = ii_Count + 1;
            processmenu();
        }
        else if (ii_Count > 10) {
            alert("Menu Load timed out.")
        }
        else {
            //Append the board menu option
            var lobj_ItemToAdd = null;

            if (ib_UserIsAdmin)
            {
                lobj_ItemToAdd = is_BoardMenuItem;
            }
            else if (ib_UserIsARB)
            {
                lobj_ItemToAdd = is_ARBMenuItem;
            }
            $(lobj_ItemToAdd).insertAfter(".ms-quickLaunch li:eq(1)");            
        }
    }, 300);
}

checkRights();

 

0

Have you tried this yet?

remove: SP.SOD.executeFunc('sp.js', function () ExecuteOrDelayUntilScriptLoaded(processmenu(), "sp.js"); $(document).ready(function () ...

replace with: _spBodyOnLoadFunctionNames.push("menuToHide")

7
  • Yes I tried that and the code never fired. It appears to be related to the minimal download strategy Commented Aug 14, 2017 at 1:19
  • 1
    The minimal download strategy only smooth the load time when you access a new page. I don't think that the cause. Is there any custom script running during page load? I am using SharePoint 2013, I just tried in oslo.html master, it works for me. <!--SPM:</SharePoint:ScriptBlock>--> <script> _spBodyOnLoadFunctionNames.push("menuToHide"); function menuToHide() { var menulist = document.getElementById("zz12_V4QuickLaunchMenu"); console.log(menulist); } </script></body> jquery-1.11.2.min.js is used in my environment.
    – Alan
    Commented Aug 14, 2017 at 23:45
  • If you don't mind, you are welcome to send me your master (.html), I'll see if I can replicate in my environment.
    – Alan
    Commented Aug 14, 2017 at 23:54
  • Thanks Alan. I think following the information in this thread related to MDS will work. I am still in the middle of testing it. sharepoint.stackexchange.com/questions/222658/… Commented Aug 15, 2017 at 1:57
  • thanks, let us know if you fix the problem, I am quite keen to know the cause of this.
    – Alan
    Commented Aug 17, 2017 at 22:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.