Toolbar System Codebase
Markup
<html>
<head>
<link rel="stylesheet" type="text/css" href="/content/styles/menusyst.css" />
</head>
<body class="body-example">
<div id="menu-content-wrapper"></div>
<script type="text/javascript" src="/content/scripts/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/content/scripts/menusyst.js"></script>
<script type="text/javascript" src="/content/scripts/menusyst-h.js"></script>
</body>
</html>
Javascript/JQuery
/* ----------------------------
/content/scripts/menusyst.js
---------------------------- */
var menusystObject = new function () {
function createSubMenus(obj, markup) {
var markup = "",
menuitem = obj.item;
if (menuitem && menuitem.length) {
for (var i = 0; i < obj.item.length; i++) {
menuitem = obj.item[i];
if (menuitem.item) {
markup +=
'<div class="menu-parent"><a href="' + menuitem.url +
'" name="menusyst-' + menuitem.id + '" title="' + menuitem.title + '">' +
menuitem.menutext + '</a><div class="menu-dropdown" id="menusyst-' + menuitem.id + '">' +
createSubMenus(menuitem, markup) +
'</div></div>';
} else {
markup +=
'<div><a href="' + menuitem.url +
'" title="' + menuitem.title + '">' + menuitem.menutext + '</a></div>';
}
}
} else if (menuitem) {
markup +=
'<div><a href="' + menuitem.url +
'" title="' + menuitem.title + '">' + menuitem.menutext + '</a></div>';
}
return markup;
}
function createRootMenus(obj, menutype) {
var markup = "",
menuitem = obj.item;
if (menuitem) {
markup +=
'<div class="menu-content" id="menusyst"><div class="menu-toolbar ' +
(menutype === 0 ? "menu-horizontal" : "menu-vertical") + '" id="menusyst-toolbar">';
for (var i = 0; i < obj.item.length; i++) {
menuitem = obj.item[i];
if (menuitem.item) {
markup +=
'<div class="menu-parent"><a href="' + menuitem.url +
'" name="menusyst-' + menuitem.id + '" title="' + menuitem.title + '">' +
menuitem.menutext + '</a><div class="menu-dropdown" id="menusyst-' + menuitem.id + '">' +
createSubMenus(menuitem, markup) +
'</div></div>';
} else {
markup +=
'<div><a href="' + menuitem.url + '" title="' + menuitem.title + '">' +
menuitem.menutext + '</a></div>';
}
}
markup += '</div></div">';
}
return markup;
};
function parseMenusystMarkup(obj, wrapper, menutype) {
var $menuLinks = null,
$menuToolbar = null,
$menuWrapper = $("#" + wrapper).first(),
menuMarkup = createRootMenus(obj, (menutype === 1 ? 1 : 0));
// insert, parse the menusyst markup
if (menuMarkup.length) {
$menuWrapper.html(menuMarkup),
$menuToolbar = $menuWrapper.find("#menusyst-toolbar").first(),
$menuLinks = $menuWrapper.find("a");
// apply menusyst link object properties
$menuLinks.each(function () {
var $this = $(this),
$childMenu = $("#" + $this.attr("name")).first(),
$childMenuLinks = $childMenu.children("div").children("a"),
hasParentMenu = ($this.data("hasParentMenu") ? true : false);
$childMenuLinks.each(function () {
$(this).data("hasParentMenu", true);
});
$this.data("hasParentMenu", hasParentMenu);
$this.data("childMenu", $childMenu);
$this.on("mouseover", menuLinkMouseover);
});
// apply menusyst object properties
menusyst = $menuWrapper.find("#menusyst")[0];
menusyst.menutype = $menuToolbar.hasClass("menu-horizontal") ? "horizontal" : "vertical";
}
}
function menuSystMouseout() {
$(menusyst).off("mouseout");
menusyst.tmr2 = setTimeout(function () {
hideSiblingChildMenus();
}, 400);
}
function hideSiblingChildMenus($el) {
var $parentLinks = ($el ? $el.parent().parent() : $(menusyst)).find(".menu-parent > a");
$parentLinks.each(function () {
$(this).data("childMenu").css("display", "none");
});
}
function positionElement($el, top, left) {
$el
.css("top", top + "px")
.css("left", left + "px")
.css("display", "block");
}
function menuLinkMouseover(e) {
var $this = $(this),
$childMenu = $this.data("childMenu");
// kill timers and reset mouseout
menusyst.tmr1 = clearTimeout(menusyst.tmr1);
menusyst.tmr2 = clearTimeout(menusyst.tmr2);
$(menusyst).on("mouseout", menuSystMouseout);
// show, hide and position menus
if (typeof $childMenu !== 'undefined') {
var $parent = $this.parent(),
$position = $parent.position(),
isDroplist = !($this.data("hasParentMenu") || menusyst.menutype === "vertical"),
left = $position.left + $parent.width(),
top = $position.top;
// position horizontal-toolbar menus
if (isDroplist) {
top = $position.top + $parent.height();
left = $position.left;
}
hideSiblingChildMenus($this);
positionElement($childMenu, top, left);
} else {
hideSiblingChildMenus($this);
};
e.CancelBubble = true;
e.stopPropagation();
}
this.load = function (url, wrapper, menutype) {
$.ajax({
type: "GET",
url: url,
dataType: "json"
}).done(function (data) {
parseMenusystMarkup(data, wrapper, menutype);
});
}
};
$(function () {
// horizontal toolbar
menusystObject.load("/content/resources/menusyst.json", "menu-content-wrapper", 0);
// vertical, slide-out toolbar
// menusystObject.load("/content/resources/menusyst.json", "menu-content-wrapper", 1);
});
JSON
{
"item": [
{
"id": "welcome",
"url": "/welcome",
"title": "ayespee.net: Home",
"menutext": "Home"
},
{
"id": "web-development",
"url": "/web-development",
"title": "ayespee.net: Web Development",
"menutext": "Development",
"item": [
{
"id": "slideshow-module",
"url": "/slideshow-module",
"title": "Web Development: Slideshow",
"menutext": "Slideshow",
"item": [
{
"id": "slideshow-example",
"url": "/slideshow-example",
"title": "Slideshow: Slideshow Example",
"menutext": "Slideshow Example"
},
{
"id": "slideshow-code",
"url": "/slideshow-code",
"title": "Slideshow: Slideshow Code",
"menutext": "Slideshow Code"
}
]
},
{
"id": "drop-menus",
"url": "/drop-menus",
"title": "Web Development: Dropmenus",
"menutext": "Dropmenus",
"item": [
{
"id": "slideout-menu",
"url": "/slide-out-menu",
"title": "Dropmenus: Drop-Menu Example",
"menutext": "Drop-Menu Example"
},
{
"id": "drop-menu-code",
"url": "/drop-menu-code",
"title": "Dropmenus: Drop-Menu Code",
"menutext": "Drop-Menu Code"
}
]
},
{
"id": "css-image-sprites",
"url": "/css-image-sprites",
"title": "Web Development: CSS Image Sprites",
"menutext": "CSS Image Sprites",
"item": [
{
"id": "css-image-sprites-code",
"url": "/image-sprites-code",
"title": "Image Sprites Code",
"menutext": "Image Sprites Code"
}
]
}
]
},
{
"id": "design-and-artwork",
"url": "/design-and-artwork",
"title": "ayespee.net: Design",
"menutext": "Design",
"item": [
{
"id": "web-design-portfolio",
"url": "/web-design-portfolio",
"title": "Design: Web Design Portfolio",
"menutext": "Web Design Portfolio"
},
{
"id": "artwork-portfolio",
"url": "/artwork-portfolio",
"title": "Design: Artwork Portfolio",
"menutext": "Artwork Portfolio",
"item": [
{
"id": "sleeper-mixed-media",
"url": "/sleeper-mixed-media",
"title": "Artwork Portfolio: Sleeper (mixed-media)",
"menutext": "Sleeper (mixed-media)"
},
{
"id": "melissa-collage",
"url": "/melissa-collage",
"title": "Artwork Portfolio: Melissa (collage)",
"menutext": "Melissa (collage)"
},
{
"id": "arlene-drawing",
"url": "/arlene-drawing",
"title": "Artwork Portfolio: Arlene (drawing)",
"menutext": "Arlene (drawing)"
},
{
"id": "lovers-painting",
"url": "/lovers-painting",
"title": "Artwork Portfolio: Lovers (painting)",
"menutext": "Lovers (painting)"
},
{
"id": "old-boat-painting",
"url": "/old-boat-painting",
"title": "Artwork Portfolio: Old Boat (painting)",
"menutext": "Old Boat (painting)"
},
{
"id": "pike-place-paintin",
"url": "/pike-place-painting",
"title": "Artwork Portfolio: Pike Place (painting)",
"menutext": "Pike Place (painting)"
}
]
}
]
},
{
"id": "sitemap",
"url": "/sitemap",
"title": "ayespee.net: Sitemap",
"menutext": "Sitemap"
}
]
}
CSS
/* ----------------------------
/content/styles/menusyst.css
---------------------------- */
.body-example {
margin: 0;
}
.body-example .menu-content {
font: bold .76em verdana !important;
}
.body-example #menu-content-wrapper {
display: block !important;
}
#menu-content-wrapper {
display: inline-block;
}
.menu-content {
box-sizing: border-box;
}
.menu-content a {
display: block;
color: #114477;
white-space: nowrap;
text-decoration: none;
padding: 5px 15px 5px 7px;
border-top: 1px solid #000;
border-left: 1px solid #000;
}
.menu-content a:hover {
color: #114477;
}
.menu-toolbar {
display: inline-block;
border-bottom: 1px solid #000;
border-right: 1px solid #000;
}
.menu-toolbar.menu-vertical > div {
min-width: 200px;
}
.menu-toolbar a {
background-color: #fffcf0;
}
.menu-toolbar a:hover {
background-color: #dcdcdc;
}
.menu-toolbar .menu-parent > a {
background: url("/content/images/rightarrow.gif") no-repeat;
background-position: center right;
background-color: #fffcf0;
padding-right: 35px;
}
.menu-toolbar .menu-parent > a:hover {
background-color: #dcdcdc;
}
.menu-parent .menu-dropdown {
display: none;
animation: dropdownFadeIn ease 1200ms;
}
.menu-dropdown {
position: absolute;
left: -1000px;
border-bottom: 1px solid #000;
border-right: 1px solid #000;
}
.menu-dropdown a {
border-top: 1px solid #000;
border-left: 1px solid #000;
}
@keyframes dropdownFadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* for horizontal only */
.menu-toolbar.menu-horizontal {
display: block;
background-color: #000;
border-bottom-width: 0;
border-right-width: 0;
}
.menu-toolbar.menu-horizontal > div {
display: inline-block;
min-width: inherit;
padding: 0 2.5em 0 0;
}
.menu-toolbar.menu-horizontal > div > a,
.menu-toolbar.menu-horizontal > div.menu-parent > a {
color: #fff;
background: none;
background-color: none;
border: 0;
}
.menu-toolbar.menu-horizontal > div > a:hover,
.menu-toolbar.menu-horizontal > div.menu-parent > a:hover {
color: #fff;
}
.content {
margin-top: 26px;
}