In this second post, I will show how you can create your own markup for the global navigation. This could be a great option when you need to take advantage of HTML 5 tags and additional jQuery plugins that requires simpler markup than SharePoint gives you out of the box.
Alternative to create a complete new control via code, an easy way is to use a standard old good .NET repeater control, instead of the SharePoint:AspMenu control and let the repeater connect to a asp:SiteMapDataSource. To use a repeater control instead of the SharPoint:AspMenu is most likely something suitable for a public SharePoint site.

simple
The repeater gives you a possibility to simplify the markup and just render a minimum of UL and Lis where you can set you own names for IDs or classes.
In order to add a selected class for selected links in the navigation you’ll need to use code behind or java script to do this. The thing here is that JS this will be valid as long as the page is still open, as soon as the user goes to a new page the JS will be reset. To overcome this you can use a cookie or read the URL, parse it, and then add a selected class to the current navigation node or as in this solution just use jQuery with location.pathname to compare the selected link to what’s in the URL.

Ok, if you only need a plain navigation without any dropdown items, replace the old control with this stuff:

<SharePoint:AjaxDelta id="DeltaTopNavigation" BlockElement="true" CssClass="ms-displayInline ms-core-navigation" role="navigation" runat="server">
<SharePoint:DelegateControl runat="server" ControlId="TopNavigationDataSource" Id="topNavigationDelegate"></SharePoint:DelegateControl>
<asp:ContentPlaceHolder id="PlaceHolderTopNavBar" runat="server">
<nav class="SpNav">
<ul id="SpNavUL">
<asp:Repeater ID="GlobalNavMenuItems" runat="server" DataSourceID="topSiteMap">
<ItemTemplate>
<li>
<asp:HyperLink ID="SpNavLinks" runat="server" NavigateUrl='<%# Eval("Url")%>' Text='<%# Eval("Title") %>'></asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
<asp:SiteMapDataSource ShowStartingNode="False" SiteMapProvider="CombinedNavSiteMapProvider" id="topSiteMap" runat="server" StartingNodeUrl="sid:1002" />
</ul>
</nav>	 
</asp:ContentPlaceHolder>
</SharePoint:AjaxDelta>

And the CSS:

#SpNavUL, #SpNavUL ul {
margin:0;padding:0;list-style:none;
}
#SpNavUL{
margin: 0px auto;
border: 1px solid #222;
background-color: #111;
background-image: linear-gradient(#444, #111);
border-radius: 6px;
box-shadow: 0 1px 1px #777;
}
#SpNavUL:before,
#SpNavUL:after {
content: "";
display: table;
}
#SpNavUL:after {
clear: both;
}
#SpNavUL li {
float: left;
border-right: 1px solid #222;
box-shadow: 1px 0 0 #444;
position: relative;
}
#SpNavUL a {
float: left;
padding: 12px 30px;
color: #999;
text-transform: uppercase;
font: bold 12px Arial, Helvetica;
text-decoration: none;
}
#SpNavUL li:hover > a {
color: #fafafa;
}
.SpNavActive{
color:#04acec!important;
}

And the jQuery:

$(document).ready(function(){
$(function() {
$('#SpNavUL a[href^="/' + location.pathname.split("/")[1] + '"]').addClass('SpNavActive');
});    
});

If you need to display dropdown items in the repeater control you have to use a bit server side script in the repeater to get the child nodes. You need to enable code blocks via web config file to get this working and if you need to do this for a production environment, don’t forget to handle the changes for the web.config in a WSP. Note that you will not be able to modify the web.config file for a SharePoint Online site.

double

Download all the stuff here including how to do with a repeater that includes a drop down menu.

Stay in tune for the next post in this series about the global navigation in SharePoint 2013

Please drop a comment if you have any question or just ideas for the next posts!

/ Christian

Advertisements