Hello Community,
I'm working in SharePoint 2013 and I'm building a dynamic multi-level menu system. Basically there are two components, a list where users add their menu items, and a page where using REST API and Dynamic CSS, the menu items are displayed.
Here is a representational sample of the REST API Code:
$(function () {
$.ajax({
url: "/sites/regulatory3/_api/web/lists/GetByTitle('Navigation')/items?$orderby=LVL2Sequence",
type: "GET",
headers: {"accept": "application/json;odata=verbose"
},
}).success(function (data) {
var listItemInfo = '';
listItemInfo += "<nav><ul id='nav'>"
//Level 1 LVL1Sequence 1
$.each(data.d.results, function (key, value) {
//alert("Sequence " + value.Sequence);
if(value.Level == 1){
if(value.Sequence == 1){
//listItemInfo += value.Title;
listItemInfo += "<li><a href='#'>" + value.Title + "</a><ul>";
}
}
});
//TopItemID 1 Level 2 LVL2Sequence All
$.each(data.d.results, function (key, value) {
if(value.Level == 2){
if(value.TopItemID == 1){
listItemInfo += "<li><a href='" + value.Link + "'>" + value.Title + "</a></li>";
}
}
});
//Level 1 LVL1Sequence 2
$.each(data.d.results, function (key, value) {
//alert("Sequence " + value.Sequence);
if(value.Level == 1){
if(value.Sequence == 2){
//listItemInfo += value.Title;
listItemInfo += "</ul></li><li><a href='#'>" + value.Title + "</a><ul>";
}
}
});
//TopItemID 2 Level 2 LVL2Sequence All
$.each(data.d.results, function (key, value) {
if(value.Level == 2){
if(value.TopItemID == 2){
listItemInfo += "<li><a href='" + value.Link + "'>" + value.Title + "</a></li>";
}
}
});
listItemInfo += "</ul></li></ul></nav>"
return $("#w").html(listItemInfo);;
alert("REST API");
});
failure(function (data) {
alert("Failure");
});
});Here is the Dynamic CSS code, this gives the menu an accordion effect:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script><!-- <script type="text/javascript" language="javascript" charset="utf-8" src="nav.js"></script> --> <!--[if lt IE 9]><script type="text/javascript" src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]--><script>
$(document).ready(function(){
$("#nav > li > a").on("click", function(e){
if($(this).parent().has("ul")) {
e.preventDefault();
}
if(!$(this).hasClass("open")) {
// hide any open menus and remove all other classes
$("#nav li ul").slideUp(350);
$("#nav li a").removeClass("open");
// open our new menu and add the open class
$(this).next("ul").slideDown(350);
$(this).addClass("open");
}
else if($(this).hasClass("open")) {
$(this).removeClass("open");
$(this).next("ul").slideUp(350);
}
});
});</script>Here is the CSS code, this adds the menu style:
<style>
#sideNavBox {DISPLAY: none}
#contentBox {MARGIN-LEFT: 5px}
ol, ul, li {
padding: 0;
}
menu, nav, section { display: block; }
ol, ul { list-style: none; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
strong { font-weight: bold; }
table { border-collapse: collapse; border-spacing: 0; }
h1 { font-family: 'Merienda', 'Trebuchet MS', Verdana, sans-serif; font-size: 1em; line-height: 1.7em; margin-bottom: 20px; font-weight: bold; letter-spacing: -0.03em; color: #675d90; text-shadow: 2px 2px 0px rgba(255,255,255,0.65); text-align: center; }
#w { display: block; width: 400px; margin: 0 auto; margin-left: 0px; padding-top: 5px; }
/* nav menu styles */
#nav {
display: block;
width: 150px;
margin: 0 auto;
margin-left: 0px;
-webkit-box-shadow: 3px 2px 3px rgba(0,0,0,0.7);
-moz-box-shadow: 3px 2px 3px rgba(0,0,0,0.7);
box-shadow: 3px 2px 3px rgba(0,0,0,0.7);
}
#nav li { }
#nav > li > a {
display: block;
padding: 16px 18px;
font-size: 0.7em;
font-weight: bold;
color: #d4d4d4;
text-decoration: none;
border-bottom: 1px solid #212121;
background-color: #343434;
background: -webkit-gradient(linear, left top, left bottom, from(#948c6f), to(#292929));
background: -webkit-linear-gradient(top, #595959, #292929);
background: -moz-linear-gradient(top, #595959, #292929);
background: -ms-linear-gradient(top, #595959, #292929);
background: -o-linear-gradient(top, #595959, #292929);
background: linear-gradient(top, #595959, #292929);
}
#nav > li > a:hover, #nav > li > a.open {
color: #e9e9e9;
border-bottom-color: #384f76;
background-color: #6985b5;
background: -webkit-gradient(linear, left top, left bottom, from(#6985b5), to(#456397));
background: -webkit-linear-gradient(top, #ff8c00, #456397);
background: -moz-linear-gradient(top, #ff8c00, #456397);
background: -ms-linear-gradient(top, #ff8c00, #456397);
background: -o-linear-gradient(top, #ff8c00, #456397);
background: linear-gradient(top, #ff8c00, #456397);
}
#nav li ul { display: none; background: #f09609; }
#nav li ul li a {
display: block;
background: none;
padding: 10px 0px;
padding-left: 10px;
font-size: 0.7em;
text-decoration: none;
font-weight: bold;
color: white;
border-bottom-style: solid;
border-bottom-color: orange;
text-shadow: 1px 1px 0px #000;
}
#nav li ul li a:hover {
background: -webkit-gradient(linear, left top, left bottom, from(#456397), to(#000000));
background: -webkit-linear-gradient(top, #456397, #000000);
background: -moz-linear-gradient(top, #456397, #000000);
background: -ms-linear-gradient(top, #456397, #000000);
background: -o-linear-gradient(top, #456397, #000000);
background: linear-gradient(top, #456397, #000000);
}
</style>And here is the HTML, the Dynamic HTML generated by the REST API code injects into this <div>:
<div id="w"></div>
So here is the problem I'm having. The REST API code works fine and it creates the Dynamic HTML, injecting it into the HTML <div> tag and the Dynamic CSS works fine, but they don't work well together. If I run the REST API code the menu items are created, but the menu isn't dynamic. If, after running the REST API code I changed the <div> tag id from "w" to anything else, for example "w1", the Dynamic CSS code works fine:
Some of the things I've tried include (but are not limited to):
Adding break; to various points in the REST API code
Adding return; to various points in the REST API code
Functions to change the id attribute of the <div> tag - these work but I just can't seem to put them in the right place in the code, no matter where I put them they run before the REST API code and so the REST API doesn't write anything because the id attribute is already changed:
function changeToW1(){
$('#w').attr('id', 'w1');
alert("Change W to W1");
}
function changeToW() {
$('#w1').attr('id', 'w');
alert("Change W1 to W");
}
Nothing works but it seems like somehow the REST API code just won't "let go" of the <div> tag and so the Dynamic CSS code won't attach to the <div> tag.
I know this is somewhat complex but if anyone thinks they can help please provide guidance and code samples, and I'll try your suggestions quickly.
Thanks!
Tom
Tom Molskow - Senior SharePoint Architect - Microsoft Community Contributor 2011 and 2012 Award - Linked-In - SharePoint Gypsy