Step 7: Create dynamic navigation menu
In this step you will use SCS Render API to replace static
navigation menu in the page layout files with the menu that is rendered
dynamically to display pages that you added to the ‘ModernBusiness’ site on
Step 5.
1. Find the HTML that renders navigation in the
Bootstrap theme:
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
…
</nav>
2. Replace it with the HTML snippet below. The <ul> tag has no content. You will dynamically generate HTML that renders list of menu items and add it to this tag using its id=”navbar-list”. Another HTML element that needs to be dynamically updated is the <a id=”navbar-brand”> tag in the “navbar-header” <div> tag.
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<!-- brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a id="navbar-brand" class="navbar-brand" href="index.html">Modern Business</a>
</div>
<!-- collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul id="navbar-list" class="nav navbar-nav navbar-right">
<!-- navigation menu goes in here -->
</ul>
</div>
</div>
</nav>
3. Add a new JavaScript file to the theme that will include code to render navigation dynamically (e.g. create ModernBusinessTheme (<user_name>)/assets/js/navigation.js) and then add the <script> tag at the bottom of all the page layouts to load this file:
<!-- SCS JS libraries -->
<script src="_scs_theme_root_/assets/js/navigation.js"></script>
<script data-main="/_sitescloud/renderer/renderer.js" src="/_sitescloud/renderer/require.js"></script>
4. To the navigation.js file you need to add JavaScript to generate HTML for the navigation menu that is similar to that in the original Bootstrap theme, but includes page links that are dynamically generated using SCS Render API.
5. Open navigation.js file in your favorite editor and add the following code:
// render navigation bar...
function renderNavbar() {
}
// must wait for the script to be ready...
if (document.addEventListener) {
document.addEventListener('scsrenderstart', renderNavbar, false);
} else if (document.attachEvent) {
document.documentElement.scsrenderstart = 0;
document.documentElement.attachEvent('onpropertychange', function(event) {
if (event && (event.propertyName == "scsrenderstart")) {
renderNavbar();
}
});
}
Note: The above code is required to make sure that the renderNavbar() function is called at the right time during SCS page lifecycle.6. Now add JavaScript that will generate the same HTML as in the Modern Business theme using SCS Render API to generate menu hierarchy dynamically:
// render navigation bar...
function renderNavbar() {
var id = SCS.navigationRoot;
var linkData, navBrand = $("#navbar-brand");
// add link to Home page...
if (navBrand) {
linkData = SCSRenderAPI.getPageLinkData(id) || {};
if (linkData.href) {
$(navBrand).attr("href", linkData.href);
}
}
// build navigation menu...
var navList = $("#navbar-list");
// add Home link...
$(navList).append(createNavItem(id));
// top level pages...
var curID, nodes = SCS.structureMap[id].children;
for (var n = 0; n < nodes.length; n++) {
curID = nodes[n];
// skip hidden node...
if (isNodeHidden(curID))
continue;
// add navigstion node...
if ((SCS.structureMap[curID].children.length > 0) && !allNodeChildrenAreHidden(curID)) {
// add navigation node with childern nodes...
navItem = document.createElement("li");
$(navItem).addClass("dropdown");
navLink = document.createElement("a");
$(navLink).addClass("dropdown-toggle");
$(navLink).attr("href", "#");
$(navLink).attr("data-toggle", "dropdown");
$(navLink).attr("data-hover", "dropdown");
$(navLink).attr("data-delay", "0");
$(navLink).attr("data-close-others", "false");
$(navLink).text(SCS.structureMap[curID].name);
// add downarroe top level to activate sub-menu...
var navLabel = document.createElement("b");
$(navLabel).addClass("caret");
$(navLink).append(navLabel);
$(navItem).append(navLink);
// sub-menu...
var navSubList = document.createElement("ul");
$(navSubList).addClass("dropdown-menu");
var subnodes = SCS.structureMap[curID].children;
for(var sub = 0; sub < subnodes.length; sub++) {
if (isNodeHidden(subnodes[sub]))
continue;
// add item in the sub-level navigation menu...
$(navSubList).append(createNavItem(subnodes[sub]));
}
$(navItem).append(navSubList);
} else {
// add top level node without children...
navItem = createNavItem(curID);
}
// add to the navigation menu...
$(navList).append(navItem);
}
}
// returns <li> tag for a navigation menu entry...
function createNavItem(id) {
var navItem = document.createElement("li");
if ( id ==SCS.navigationCurr )
$(navItem).addClass("active");
var navLink = document.createElement("a");
var linkData = SCSRenderAPI.getPageLinkData(id) || {};
if ( linkData.href ) {
$(navLink).attr("href", linkData.href);
}
if ( linkData.target ) {
$(navLink).attr("target", linkData.target);
}
$(navLink).text(SCS.structureMap[id].name);
$(navItem).append(navLink);
return navItem;
}
// returns true if given navigation node is hidden...
function isNodeHidden(id) {
var navNode, isHidden = false;
if (SCS.structureMap) {
navNode = SCS.structureMap[id];
if (navNode) {
isHidden = (true === navNode.hideInNavigation);
}
}
return isHidden;
}
// returns true if all children of given navigation node are hidden...
function allNodeChildrenAreHidden(id) {
var subnodes = SCS.structureMap[id].children,
allHidden = ( subnodes.length > 0 ) ? true: false;
for( var sub = 0; sub < subnodes.length; sub++ ) {
if( !isNodeHidden( subnodes[sub] ) ) {
allHidden = false;
break;
}
}
return allHidden;
}
7. Save navigation.js file.Note: The above code generates a two-level navigation menu. if you need to use menu that supports more levels, you should extend this code.
Checkpoint 4
In
the Site Builder, check that now you can use navigation bar on a page to
navigate pages in your site. Open site in the Edit mode and use Site Tree
palette to add new page – check that new page correctly appears in the
navigation.
At this point you can add new page to your SCS site and see new pages appearing in the navigation menu. In the Part 4 you will learn how to add Breadcrumbs and make pages editable in the Site Builder by adding SCS slots to page layouts in your new theme.
At this point you can add new page to your SCS site and see new pages appearing in the navigation menu. In the Part 4 you will learn how to add Breadcrumbs and make pages editable in the Site Builder by adding SCS slots to page layouts in your new theme.
No comments:
Post a Comment