//** All Levels Navigational Menu- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//** Script Download/ instructions page: http://www.dynamicdrive.com/dynamicindex1/ddlevelsmenuadmin/
//** Usage Terms: http://www.dynamicdrive.com/notice.htm
//** July 7th, 08'- Creation Date
//** July 16th, 08'- Updated to v 1.3:
//1) Adds "Side Bar" orientation option.
//2) Drop Down Menus now auto adjust their positioning if too close to either right or bottom window edges.
//3) Enhanced IFRAME shim "coverage" on the page.
//** July 19th, 08'- Updated to v 1.31: Drop down menu now positions at top of window edge if there's neither room downwards or upwards to settle.
//** Aug 13th, 08'- v1.32: Moved "rel" attribute from menu's <li> elements to inner <a>, for validation reasons
//** Sept 10th, 08'- Updated to v 1.4:
//1) Added optional "sliding" animation when sub menus are revealed.
//2) Arrow images now dynamically positioned, instead of relying on CSS's "right" property
var ddlevelsmenuadmin = {
downarrowpointer_adminmenu: ["ddlevelsfiles/arrow-down.gif", 11,7], //path to "down arrow" image that gets added to main menu items (last 2 parameters should be width/height of img)
rightarrowpointer_admin: ["ddlevelsfiles/arrow-right.gif", 12,12], //path to "right arrow" image that gets added to LI elements within drop down menu containing additional menus
hideinterval: 0, //delay in milliseconds before sub menu(s) disappears onmouseout.
revealanimate: false, //enable sliding animation when revealing sub menus? (true/false)
httpsiframesrc: "blank.htm", //If menu is run on a secure (https) page, the IFRAME shim feature used by the script should point to an *blank* page *within* the secure area to prevent an IE security prompt. Specify full URL to that page on your server (leave as is if not applicable).
///No need to edit beyond here////////////////////
topmenuids: [], //array containing ids of all the primary menus on the page
topitems: {}, //object array containing all top menu item links
subuls: {}, //object array containing all ULs
topitemsindex: -1,
ulindex: -1,
hidetimers: {}, //object array timer
shimadded: false,
isff3orabove: /Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent) && RegExp.$1>=3, //detect FF3 or above
getoffset:function(what, offsettype){
var offset = 0;
p = what.offsetParent;
while (p && p != this.standardbody) {
offset += offsettype == "offsetTop" ? p.offsetTop : p.offsetLeft;
p = p.offsetParent;
}
return (what.offsetParent)? what[offsettype] + this.getoffset(what.offsetParent, offsettype) : what[offsettype]
},
getoffsetof:function(el){
el._offsets={left:this.getoffset(el, "offsetLeft"), top:this.getoffset(el, "offsetTop")}
},
getwindowsize:function(){
this.docwidth=window.innerWidth? window.innerWidth-10 : this.standardbody.clientWidth-10
this.docheight=window.innerHeight? window.innerHeight-15 : this.standardbody.clientHeight-18
},
gettopitemsdimensions:function(){
for (var m=0; m<this.topmenuids.length; m++){
var topmenuid=this.topmenuids[m]
for (var i=0; i<this.topitems[topmenuid].length; i++){
var header=this.topitems[topmenuid][i]
var submenu = document.getElementById(header.getAttribute('rel'));
if (submenu) {
header._dimensions={w:header.offsetWidth, h:header.offsetHeight, submenuw:submenu.offsetWidth, submenuh:submenu.offsetHeight}
}
}
}
},
isContained:function(m, e){
var e=window.event || e
var c=e.relatedTarget || ((e.type=="mouseover")? e.fromElement : e.toElement)
while (c && c!=m)try {c=c.parentNode} catch(e){c=m}
if (c==m)
return true
else
return false
},
addpointer:function(target, imgclass, imginfo){
var pointer=document.createElement("img")
pointer.src=imginfo[0]
pointer.style.width=imginfo[1]+"px"
pointer.style.height=imginfo[2]+"px"
pointer.style.left=target.offsetWidth-imginfo[2]-2+"px"
pointer.className=imgclass
target.appendChild(pointer)
},
css:function(el, targetclass, action){
var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
if (action=="check")
return needle.test(el.className)
else if (action=="remove")
el.className=el.className.replace(needle, "")
else if (action=="add" && !needle.test(el.className))
el.className+=" "+targetclass
},
addshimmy:function(target){
var shim=(!window.opera)? document.createElement("iframe") : document.createElement("div") //Opera 9.24 doesnt seem to support transparent IFRAMEs
shim.className="ddiframeshim_admin"
shim.setAttribute("src", location.protocol=="https:"? this.httpsiframesrc : "about:blank")
shim.setAttribute("frameborder", "0")
target.appendChild(shim)
shim.style.position = "absolute";
shim.style.left = "-5000px";
shim.style.top = "-5000px";
shim.style.display = "none";
try{
shim.style.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
}
catch(e){}
return shim
},
positionshim:function(header, submenu, dir, scrollX, scrollY){
if (header._istoplevel){
var scrollY=window.pageYOffset? window.pageYOffset : this.standardbody.scrollTop
var topgap=header._offsets.top-scrollY
var bottomgap=scrollY+this.docheight-header._offsets.top-header._dimensions.h
if (topgap>0){
this.shimmy.topshim.style.left=scrollX+"px"
this.shimmy.topshim.style.top=scrollY+"px"
this.shimmy.topshim.style.width="99%"
this.shimmy.topshim.style.height=topgap+"px" //distance from top window edge to top of menu item
}
if (bottomgap>0){
this.shimmy.bottomshim.style.left=scrollX+"px"
this.shimmy.bottomshim.style.top=header._offsets.top + header._dimensions.h +"px"
this.shimmy.bottomshim.style.width="99%"
this.shimmy.bottomshim.style.height=bottomgap+"px" //distance from bottom of menu item to bottom window edge
}
}
},
hideshim:function(){
this.shimmy.topshim.style.width=this.shimmy.bottomshim.style.width=0
this.shimmy.topshim.style.height=this.shimmy.bottomshim.style.height=0
},
prepareShowMenu: function(e, header, dir) {
if (!ddlevelsmenuadmin.isContained(header, e)) {
if (typeof ddlevelsmenuadmin.hidetimers[header._master][parseInt(header._pos)]!="undefined")
clearTimeout(ddlevelsmenuadmin.hidetimers[header._master][parseInt(header._pos)])
if (header._istoplevel)
ddlevelsmenuadmin.css(header, "selected", "add")
var submenu=ddlevelsmenuadmin.subuls[header._master][parseInt(header._pos)]
ddlevelsmenuadmin.getoffsetof(header)
var scrollX=window.pageXOffset? window.pageXOffset : ddlevelsmenuadmin.standardbody.scrollLeft
var scrollY=window.pageYOffset? window.pageYOffset : ddlevelsmenuadmin.standardbody.scrollTop
p = submenu.parentNode;
scr = 0;
while (p && p.nodeName.toLowerCase() != "body") {
scr += p.scrollTop;
p = p.parentNode;
}
p = submenu.offsetParent;
var off = 0;
while (p && p.nodeName.toLowerCase() != "body") {
off += p.offsetTop;
p = p.offsetParent;
}
var submenurightedge=header._offsets.left + header._dimensions.submenuw + (header._istoplevel && dir=="topbar"? 0 : header._dimensions.w)
var submenubottomedge=header._offsets.top + header._dimensions.submenuh
//Sub menu starting left position
var menuleft=(header._istoplevel? header._offsets.left + (dir=="sidebar"? header._dimensions.w : 0) : header._dimensions.w)
if (submenurightedge-scrollX>ddlevelsmenuadmin.docwidth){
menuleft+= -header._dimensions.submenuw + (header._istoplevel && dir=="topbar" ? header._dimensions.w : -header._dimensions.w)
}
//Sub menu starting top position
var menutop=(header._istoplevel? header._offsets.top + (dir=="sidebar"? 0 : header._dimensions.h) : header.offsetTop)
//if (document.all)
menutop -= off;
try {
if (parent.top.JAVASCRIPTS) {
menutop--;
menuleft--;
}
} catch (e) {}
//if (!document.all) menutop -= scr;
submenu.style.left = menuleft + "px"
if (submenubottomedge-scrollY>ddlevelsmenuadmin.docheight){ //no room downwards?
if (header._dimensions.submenuh<header._offsets.top+(dir=="sidebar"? header._dimensions.h : 0)-scrollY){ //move up?
menutop+= - header._dimensions.submenuh + (header._istoplevel && dir=="topbar"? -header._dimensions.h : header._dimensions.h)
}
else{ //top of window edge
menutop+= -(header._offsets.top-scrollY) + (header._istoplevel && dir=="topbar"? -header._dimensions.h : 0)
}
}
submenu.style.top=menutop+"px"
//submenu.style.top="80px"
if (ddlevelsmenuadmin.revealanimate==false || ddlevelsmenuadmin.isff3orabove){ //apply shim immediately only if animation is turned off, or if on, in non FF2.x browsers
ddlevelsmenuadmin.positionshim(header, submenu, dir, scrollX, scrollY)
}
else{
submenu.ff2scrollInfo={x:scrollX, y:scrollY}
}
ddlevelsmenuadmin.showmenu(header, submenu, dir)
if (typeof TurnkeysConfig != "undefined") {
TurnkeysConfig.getDefaultConfig().isDDMenuShow = true;
}
}
},
buildmenu:function(mainmenuid, header, submenu, submenupos, istoplevel, dir){
header._master=mainmenuid //Indicate which top menu this header is associated with
header._pos=submenupos //Indicate pos of sub menu this header is associated with
header._istoplevel=istoplevel
if (istoplevel){
this.addEvent(header, function(header, dir) {
var header = header;
var dir = dir;
return function(e) {
var menuitem = ddlevelsmenuadmin.subuls[this._master][parseInt(this._pos)];
if (menuitem.style.visibility != 'hidden') {
ddlevelsmenuadmin.hidemenu(menuitem);
} else {
ddlevelsmenuadmin.prepareShowMenu(e, header, dir);
}
}
}(header, dir), "click")
}
this.subuls[mainmenuid][submenupos]=submenu
header._dimensions={w:header.offsetWidth, h:header.offsetHeight, submenuw:submenu.offsetWidth, submenuh:submenu.offsetHeight}
this.getoffsetof(header)
submenu.style.left=0
submenu.style.top=0
submenu.style.visibility="hidden"
this.addEvent(header, function(header, dir) { //mouseover event
var header = header;
var dir = dir;
return function(e) {
ddlevelsmenuadmin.prepareShowMenu(e, header, dir);
}
}(header, dir), "mouseover")
this.addEvent(header, function(e){ //mouseout event
if (this._istoplevel){
var submenu=ddlevelsmenuadmin.subuls[this._master][parseInt(this._pos)]
if (!ddlevelsmenuadmin.isContained(this, e) && !ddlevelsmenuadmin.isContained(submenu, e)) //hide drop down ul if mouse moves out of menu bar item but not into drop down ul itself
ddlevelsmenuadmin.hidemenu(submenu)
} else if (!this._istoplevel && !ddlevelsmenuadmin.isContained(this, e)){
var headerlist=this
ddlevelsmenuadmin.hidetimers[this._master][parseInt(this._pos)]=setTimeout(function(){
var submenu=ddlevelsmenuadmin.subuls[headerlist._master][parseInt(headerlist._pos)]
ddlevelsmenuadmin.hidemenu(submenu)
}, ddlevelsmenuadmin.hideinterval)
}
}, "mouseout")
},
hideAll: function() {
for (var i in this.topitems) {
for (var j=0; j<this.topitems[i].length; j++) {
var dropul = document.getElementById(this.topitems[i][j].getAttribute('rel'))
if (dropul) this.hidemenu(dropul);
}
}
},
showmenu:function(header, submenu, dir){
if (this.revealanimate){
submenu._curanimatepoint=0
var endpoint=(header._istoplevel && dir=="topbar")? submenu.offsetHeight : submenu.offsetWidth
submenu.style.width=submenu.style.height=0
submenu.style.overflow="hidden"
clearTimeout(submenu._animatetimer)
submenu._animatetimer=setInterval(function(){ddlevelsmenuadmin.revealmenu(header, submenu, endpoint, dir)}, 10)
}
submenu.style.zIndex = 200000;
//submenu.style.border = "solid black 1px"
submenu.style.visibility="visible"
try {
if (parent.top.Ext) parent.top.Ext.setElementsVisibility('object', '.extHideObject', false);
} catch (e) {}
},
revealmenu:function(header, submenu, endpoint, dir){
if (submenu._curanimatepoint<endpoint){
if (submenu._curanimatepoint==0) //reset either width or height of sub menu to "auto" when animation begins
submenu.style[header._istoplevel && dir=="topbar"? "width" : "height"]="auto"
submenu._curanimatepoint= submenu._curanimatepoint + 5 + (submenu._curanimatepoint/10)
submenu.style[header._istoplevel && dir=="topbar"? "height" : "width"]=submenu._curanimatepoint+"px"
}
else{
if (submenu.ff2scrollInfo) //if this is FF2 or below (meaning shim hasn't been applied yet
this.positionshim(header, submenu, dir, submenu.ff2scrollInfo.x, submenu.ff2scrollInfo.y)
submenu.style[header._istoplevel && dir=="topbar"? "height" : "width"]="auto"
submenu.style.overflow="visible"
clearInterval(submenu._animatetimer)

}
},
hidemenu:function(submenu){
if (typeof submenu._pos!="undefined"){ //if submenu is outermost UL drop down menu
this.css(this.topitems[submenu._master][parseInt(submenu._pos)], "selected", "remove")
this.hideshim()
}
clearTimeout(submenu._animatetimer)
submenu.style.left=0
submenu.style.top="-1000px"
submenu.style.visibility="hidden"
if (typeof TurnkeysConfig != "undefined") {
TurnkeysConfig.getDefaultConfig().isDDMenuShow = false;
}
try {
if (parent.top.Ext) parent.top.Ext.setElementsVisibility('object', '.extHideObject', true);
} catch (e) {}
},
addEvent:function(target, functionref, tasktype) {
if (target.addEventListener)
target.addEventListener(tasktype, functionref, false);
else if (target.attachEvent)
target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)});
},
init:function(mainmenuid, dir){
this.standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body
this.topitemsindex=-1
this.ulindex=-1
this.topmenuids.push(mainmenuid)
this.topitems[mainmenuid]=[] //declare array on object
this.subuls[mainmenuid]=[] //declare array on object
this.hidetimers[mainmenuid]=[] //declare array on object
if (!this.shimadded){
this.shimmy={}
this.shimmy.topshim=this.addshimmy(document.body) //create top iframe shim obj
this.shimmy.bottomshim=this.addshimmy(document.body) //create bottom iframe shim obj
this.shimadded=true
}
var menubar=document.getElementById(mainmenuid)
var alllinks=menubar.getElementsByTagName("a")
this.getwindowsize()
for (var i=0; i<alllinks.length; i++){
if (alllinks[i].getAttribute('rel')){
this.topitemsindex++
this.ulindex++
var menuitem=alllinks[i]
this.topitems[mainmenuid][this.topitemsindex]=menuitem //store ref to main menu links
var dropul=document.getElementById(menuitem.getAttribute('rel'))
if (dropul) {
dropul.style.zIndex=200000 //give drop down menus a high z-index
dropul._master=mainmenuid //Indicate which main menu this main UL is associated with
dropul._pos=this.topitemsindex //Indicate which main menu item this main UL is associated with
//this.addEvent(dropul, function(){ddlevelsmenuadmin.hidemenu(this)}, "click")
var arrowpointer=(dir=="sidebar")? "rightarrowpointer_admin" : "downarrowpointer_adminmenu"
//this.addpointer(menuitem, arrowpointer, this[arrowpointer])
this.buildmenu(mainmenuid, menuitem, dropul, this.ulindex, true, dir) //build top level menu
//dropul.onmouseover=function(){
//do nothing
//}
this.addEvent(dropul, function(e){ //hide menu if mouse moves out of main UL element into open space
if (!ddlevelsmenuadmin.isContained(this, e) && !ddlevelsmenuadmin.isContained(ddlevelsmenuadmin.topitems[this._master][parseInt(this._pos)], e)){
var dropul=this
ddlevelsmenuadmin.hidetimers[this._master][parseInt(this._pos)]=setTimeout(function(){
ddlevelsmenuadmin.hidemenu(dropul)
}, ddlevelsmenuadmin.hideinterval)
}
}, "mouseout")
var subuls=dropul.getElementsByTagName("ul")
for (var c=0; c<subuls.length; c++){
this.ulindex++
var parentli=subuls[c].parentNode
//this.addpointer(parentli.getElementsByTagName("a")[0], "rightarrowpointer_admin", this.rightarrowpointer_admin)
this.buildmenu(mainmenuid, parentli, subuls[c], this.ulindex, false, dir) //build sub level menus
}
}
}
} //end for loop
this.addEvent(window, function(){ddlevelsmenuadmin.getwindowsize(); ddlevelsmenuadmin.gettopitemsdimensions()}, "resize")
},
setup:function(mainmenuid, dir){
this.addEvent(window, function(){ddlevelsmenuadmin.init(mainmenuid, dir)}, "load")
}
}
var ddlevelsmenu = ddlevelsmenuadmin;
