Top Naviation Menu is not loaded when script runs - SharePoint Foundation 2013 Oslo Master Page
-
30-12-2020 - |
Question
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?
Solution
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();
OTHER TIPS
Have you tried this yet?
remove: SP.SOD.executeFunc('sp.js', function () ExecuteOrDelayUntilScriptLoaded(processmenu(), "sp.js"); $(document).ready(function () ...
replace with: _spBodyOnLoadFunctionNames.push("menuToHide")