var dummy; var undefined; window.currentMenu = null; document.onmousemove = function(evnt) { // debugging for portlet dragging, etc. //var elem = getTarget(evnt); //elem = findClassUp(elem, 'portletHandle'); //window.status = "X: " + getMouseX(evnt) + " Y: " + getMouseY(evnt) + " Elem: " + (elem!=null ? elem.id : "null"); quickaddDraggerOnMouseMove(evnt); portletDraggerOnMouseMove(evnt); ddmOnMouseMove(evnt); dropdownOnMouseMove(evnt); } window.clickCount = 0; document.onclick = function(evnt) { ++window.clickCount; ddmOnClick(evnt); } document.onmousedown = function(evnt) { quickaddDraggerOnMouseDown(evnt); portletDraggerOnMouseDown(evnt); dropdownOnMouseDown(evnt); } document.onmouseup = function(evnt) { quickaddDraggerOnMouseUp(); portletDraggerOnMouseUp(); dropdownOnMouseUp(evnt); if ( window.OrderedListOnMouseUp != null ) window.OrderedListOnMouseUp( evnt ); } document.onkeydown = function(evnt) { return dropdownOnKeyDown(evnt); } function getTarget(evnt) { return event.srcElement; } function findClassUp(node, clss) { while ((node != null) && (node.className != clss)) node = node.parentNode; return node; } function findPosX(obj) { var curleft = 0; if (document.getElementById || document.all) { while (obj.offsetParent) { curleft += obj.offsetLeft obj = obj.offsetParent; } } else if (document.layers) curleft += obj.x; return curleft; } function findPosY(obj) { var curtop = 0; if (document.getElementById || document.all) { while (obj.offsetParent) { curtop += obj.offsetTop obj = obj.offsetParent; } } else if (document.layers) curtop += obj.y; return curtop; } function getMouseX(evnt) { return event.clientX; } function getMouseY(evnt) { return event.clientY; } function moveToolTip(x, y) { var tooltip = getToolTip(); if ( parseInt(x) + parseInt(tooltip.offsetWidth) <= getDocumentWidth() ) tooltip.style.left = x-9; else tooltip.style.left = getDocumentWidth() - tooltip.offsetWidth; tooltip.style.top = y + document.body.scrollTop + 5; } function showToolTip(Title, Content) { if ( isValEmpty(Title) && isValEmpty(Content) ) return; var tooltipHTML =''+ ''+ '
'+ ''; if ( !isValEmpty(Title) ) tooltipHTML += ''; if ( !isValEmpty(Content) ) tooltipHTML += ''; tooltipHTML += '
'+Title+'
'+Content+'
'+ '
'; var tooltip = getToolTip(); tooltip.movetooltip = isValEmpty(tooltip.tooltipcontent) || tooltip.tooltipcontent != tooltipHTML; tooltip.tooltipcontent = tooltipHTML; if ( tooltip.hidetooltiptimer != null ) clearTimeout(tooltip.hidetooltiptimer); tooltip.showtooltiptimer = setTimeout("var tooltip = getToolTip(); if (tooltip.movetooltip) moveToolTip(lastX,lastY); tooltip.innerHTML=tooltip.tooltipcontent; tooltip.style.visibility = 'visible'", 500); } function hideToolTip() { var tooltip = getToolTip(); if ( tooltip.showtooltiptimer != null ) clearTimeout(tooltip.showtooltiptimer); tooltip.tooltipcontent = ''; tooltip.hidetooltiptimer = setTimeout("var tooltip = getToolTip(); tooltip.tooltipcontent = null; tooltip.style.visibility = 'hidden'", 1000); } function getToolTip() { var tooltip = document.getElementById('NLToolTip'); if ( tooltip == null ) { tooltip = document.createElement("DIV"); tooltip.id = 'NLToolTip'; tooltip.style.position='absolute'; tooltip.style.width='250px'; tooltip.style.top='0px'; tooltip.style.left='0px'; tooltip.style.zindex=4; tooltip.style.visibility='hidden'; document.body.appendChild(tooltip); } return tooltip; } window.menusAreOpen = false; window.rolloverDelay = 0; function makeMenu(name, values, level, parent) { if ( window.menuData == null ) window.menuData = new Array(); if ( window.menuLevel == null ) window.menuLevel = new Array(); if ( window.menuParent == null ) window.menuParent = new Array(); window.menuData[name] = values; window.menuLevel[name] = level; window.menuParent[name] = parent; } function ddmOnMouseMove(evnt) { if (window.currentMenu != null) { return window.currentMenu.handleMouseMove(evnt); } } function ddmOnClick(evnt) { var target = getTarget(evnt); var spn = findClassUp(target, 'ddmSpan'); if (spn == null) { var div = findClassUp(target, 'ddmDiv'); if(div == null) { clearAllMenusExcept("ALL_MENUS_PLEASE") } } } var tdCounter = 0; function NLMenu(name, values, level, parent) { this.tabName = name.substring(0, name.indexOf("_")); this.div = null; this.currentCell = null; this.isOpen = false; this.level = level; this.parent = parent; this.name = name; this.values = values; this.span = document.getElementById("spn_" + this.name); this.overrideX = 0; this.overrideY = 0; // function that allows you to do custom actions when the menu opens/closes this.onCloseAction = null; this.onOpenAction = null; } var menus = new Array(); var menuTimers = new Array(); var friendlyDelay = 0; function resetNavMenuTimer(tabname) { clearTimeout(menuTimers[tabname]); } function startTimer(tabname) { menuTimers[tabname] = setTimeout("clearAllMenus(-100, '"+tabname+"');",500); } function clearAllMenus(myLevel, tabname) { clearTimeout(friendlyDelay); for(i in menus) { if(menus[i].tabName == tabname) { if(menus[i].level > myLevel) menus[i].close(); } } } function clearAllMenusExcept(tabname) { for(i in menus) { if(menus[i].tabName != tabname) { var downarrow = document.getElementById(menus[i].tabName + "_nav_arrow"); if(downarrow != null) downarrow.src = "/images/nav/nav_arrow.gif"; menus[i].close(); } } } function getAndOpenMenu(child,thismenu,useTimer) { getMenu(child).open(thismenu,useTimer); } NLMenu.prototype.setXandYoverride = function(x,y) { this.overrideX = x; this.overrideY = y; } NLMenu.prototype.setCloseAction = function(action) { this.onCloseAction = new Function(action); } NLMenu.prototype.setOpenAction = function(action) { this.onOpenAction = new Function(action); } NLMenu.prototype.open = function(childOpener, useTimer) { if(this.isOpen == true) return; clearTimeout(friendlyDelay); if(this.onOpenAction != null) this.onOpenAction(); var isChild = false if(this.level>0) { isChild = true; clearAllMenus(this.level-1, this.tabName); } if(document.getElementById("div_" + this.name)) { return; } this.div = document.createElement("div"); this.div.className = 'ddmDiv'; this.div.id = "div_" + this.name; this.div.onmouseover = new Function("resetNavMenuTimer('"+this.tabName+"');"); if(useTimer) this.div.onmouseout = new Function("startTimer('"+this.tabName+"');"); var tab = document.createElement("table"); tab.className = 'ddmInnerTable'; this.div.appendChild(tab); var tbody = document.createElement("tbody"); tab.appendChild(tbody); tab.cellSpacing = 0; tab.cellPadding = 4; var allArrows = new Array(); var arrowCounter = 0; var i, tr, td, hr, msg, child, url, arrowFont, arrowText, sep, anchor; // keep track of whether or not there are ANY children in this menu so that we can position the arrows properly var bHasChild = false; for (i=0; i < this.values.length; i++) { tr = document.createElement("tr"); tbody.appendChild(tr); td = document.createElement("td"); tr.appendChild(td); td.id = "nl" + ++tdCounter; anchor = document.createElement("a"); anchor.className = 'ddmAnchor'; anchor.onclick = new Function("return false;"); msg = this.values[i][0]; url = this.values[i][1]; child = this.values[i][2]; if(child.length > 0) bHasChild = true; var isSeperator = msg == 'ddmSeperator'; if(isSeperator && !isIE) continue; if(child.length>0) { td.className = 'ddmTextHasChild'; var mouseoverScript = "clearTimeout(friendlyDelay); var timeout = "+(this.level==0? 250:0)+"; friendlyDelay = setTimeout(\"getAndOpenMenu('"+child+"','"+td.id+"',"+(useTimer?"true":"false")+")\",timeout)" td.onmouseover = new Function(mouseoverScript); } else { td.className = 'ddmText'; td.onmouseover = new Function("clearTimeout(friendlyDelay); clearAllMenus("+(this.level)+", '"+this.tabName+"');"); } if(url.length>0 && !isSeperator) { var url = this.values[i][1]; anchor.href = url; if( url.substring(0, url.indexOf(":")).toLowerCase() == 'javascript') url = url.substring(url.indexOf(":")+1); else url = "try { window.location = '" + url + "'; } catch (e) { }"; td.onclick = new Function("clearAllMenusExcept('clear all'); " + url); } var txt = document.createTextNode(msg); // items that have no URL AND have a child get arrows (currently we don't show arrows for items that are clickable - we // only show them for items that force you to go down a level in navigation) if( (url == null || url.length<1) && child.length>0 ) { tab.style.width = "165"; allArrows[arrowCounter] = document.createElement("div"); allArrows[arrowCounter].className = 'ddmArrow'; allArrows[arrowCounter].id = this.tabName+"_arrow_"+i; arrowText = document.createTextNode("4"); allArrows[arrowCounter].appendChild(arrowText); td.appendChild(allArrows[arrowCounter]); arrowCounter++; } if(isSeperator) { sep = document.createElement("tr"); tbody.appendChild(sep); sep.style.height = "1"; sep.className = 'ddmSeperator'; var sepTD = document.createElement("td"); sep.appendChild(sepTD); sep = document.createElement("tr"); tbody.appendChild(sep); sep.style.height = "1"; sep.className = 'ddmSeperatorEmpty'; sepTD = document.createElement("td"); sep.appendChild(sepTD); } else { td.appendChild(anchor); anchor.appendChild(txt); } } var addWidth = 0; var posObjectX = this.span; var posObjectY = this.span; // the div must be appended to the document before it is positioned since it has no height/width // attributes until it's in the document document.body.appendChild(this.div); if(isChild) { posObjectX = this.div; if(childOpener!=null) { posObjectY = document.getElementById(childOpener); } if(this.level > 0) { var currDD = getMenu(this.tabName+'_d1'); addWidth += currDD.div.offsetWidth + currDD.div.offsetLeft; } if(this.level >1 && this.parent != null) addWidth += getMenu(this.parent).div.offsetWidth; addWidth -= (this.level*4); } var divWidth = parseInt(tab.style.width); // if we have arrows, and this menu has at least one child, we set the // table's width to 4px larger to make room for the arrows if(arrowCounter>0 && bHasChild) tab.style.width = divWidth - 4; var x = findPosX(posObjectX); if(isChild) x = addWidth-1; else x = x-8; if (x + this.div.offsetWidth < getDocumentWidth()) { this.div.style.left = x + this.overrideX; } else { this.div.style.left = getDocumentWidth() - this.div.offsetWidth; } // sometimes nav menus are contained within divs that are scrollable. In this case we have to compensate // for the scroll position when we put the nav menus on the page var scrollDiv = findClassUp(this.span,'scrollarea'); var scrollOffset = 0; if(scrollDiv!=null) { scrollOffset = scrollDiv.scrollTop; } var y = findPosY(posObjectY); if (y + posObjectY.offsetHeight + this.div.offsetHeight > getDocumentHeight() + scrollOffset + document.body.scrollTop) { y = getDocumentHeight() - this.div.offsetHeight + 5 + scrollOffset + document.body.scrollTop; } else { y = y + posObjectY.offsetHeight; } if(isChild) { if(this.level==2) y -=24; else y -= 22; } // if there is a scroll offset we need to compensate y -= scrollOffset; this.div.style.top = y + 3 + this.overrideY; if(this.level == 0) window.menusAreOpen = true; this.div.style.zIndex = 2; var arrowTopAdjust = isIE ? 77 : 89; if(arrowCounter>0 && this.level==0) { for(j=0; j { allArrows[j].style.left = divWidth - 17; allArrows[j].style.top = findPosY(allArrows[j]) - arrowTopAdjust; } } this.isOpen = true; } NLMenu.prototype.close = function() { if (!this.isOpen) return; if(this.level==0) window.menusAreOpen = false; document.body.removeChild(this.div); this.currentCell = null; this.div = null; this.isOpen = false; if(this.onCloseAction != null) this.onCloseAction(); } NLMenu.prototype.setCurrentCellInMenu = function(cell) { var first=false; if (!this.isOpen) return; if (cell == null) { first = true; cell = this.div.firstChild.rows[0].cells[0]; } if (this.currentCell != null && this.currentCell.className!= 'ddmTextSeperator') { this.currentCell.className = 'ddmText'; } if (cell != null && cell.className!= 'ddmTextSeperator' && !first) { cell.className = 'ddmTextOver'; } this.currentCell = cell; } NLMenu.prototype.getIndex = function(str) { for (i=0; i < this.values.length; i += 2) { if (this.values[i] == str) return i/2; } return 0; } NLMenu.prototype.showHide = function(useTimer) { clearAllMenusExcept(this.tabName); this.becomeCurrent(); this.open(null, useTimer); } NLMenu.prototype.handleMouseMove = function(evnt) { if (!this.isOpen) return; var target = getTarget(evnt); while (target != null) { if ((target.className != null) && ( (target.className == 'ddmText') || (target.className == 'ddmTextHasChild') || (target.className == 'ddmTextSeperator' ))) { this.setCurrentCellInMenu(target); break; } target = target.parentNode; } } NLMenu.prototype.becomeCurrent = function() { if (window.currentMenu != this) { window.currentMenu = this; } } function getMenu(name) { var returnMe = menus[name]; if (returnMe == null) { returnMe = new NLMenu(name, window.menuData[name], window.menuLevel[name], window.menuParent[name]); menus[name] = returnMe; if(returnMe.level == 0) { var timer = 0; menuTimers[returnMe.tabName] = timer; } } return returnMe; } function menuDataExists(name) { if(window.menuData==null || window.menuData[name] == null || window.menuData[name].length<1) return false; else return true; } function showMenu(span_id, useTimer) { try { var spn = document.getElementById(span_id); if (spn != null) { var name = spn.id.substring(4, spn.id.length); if(!menuDataExists(name)) return false; return getMenu(name).showHide(useTimer); } } catch (e) { } } var currentDropdown = null; var dropdownCounter = 0; /** * This function should be called inline at the exact spot you want the dropdown to appear. It will write out the * html directly to the document. The document that you want the html to be writtin in can be passed via the 'renderDocument' * argument, or if this argument is null it uses the current document. */ function makeDropdown(name, width, values, defaultIndex, onChange, onFocus, minimumWidth, renderDocument, iFlags) { if(renderDocument == null) renderDocument = document; if (defaultIndex == null) defaultIndex = 0; var defaultValue = ""; var defaultText = ""; if (values.length > 0) { for (var i=0; i < values.length; i += 2) { values[i] = escapeHtml(values[i]); if (i == defaultIndex*2) { defaultText = values[i]; defaultValue = values[i+1]; } } } else { values = ["",""]; } var count = ++dropdownCounter; var nameC = name + count; if (onChange != null) onChange = "onchange=\""+onChange+"\""; else onChange = ""; var inptOnFocus = "onfocus='this.select()'"; if (onFocus != null) { onFocus = "onfocus=\""+onFocus+"\""; inptOnFocus = "onfocus='getElementById(\"hddn_"+nameC+"\").onfocus(); this.select();'"; } else { onFocus = ""; } if (defaultText == "") defaultText = " "; renderDocument.write(""); renderDocument.write(""); renderDocument.write(""); var dd = new NLDropdown(name, values, defaultIndex, count, renderDocument); if(window.dropdowns[nameC] == null) window.dropdowns[nameC] = dd; dd.setWidth(width, minimumWidth); dd.flags = iFlags; dd.disabled = dd.hasAttribute(32768); dd.typeAhead = dd.hasAttribute(65536); if(dd.hasAttribute(2048)) dd.setBackgroundColor('#FFFFE5'); if(dd.hasAttribute(32768)) dd.setDisabled(true); if(dd.hasAttribute(1073741824)) dd.setArrowImage(''); } function escapeHtml(str) { if (str == null) return null; if (str.length == 0) return ""; var escaperNode = document.createElement("a"); escaperNode.innerHTML = str + "\n"; var child = escaperNode.firstChild; if (child != null) { // get rid of trailing space that comes from "\n" above var result = child.data; if (result.charAt(result.length-1) == ' ') result = result.substr(0,result.length-1); return result; } else return ""; } function dropdownOnMouseDown(evnt) { var target = getTarget(evnt); if ( isNLMultiDropDown(target) ) { multidropdowns[target.ddname].handleMouseDown(evnt); } var inpt = findClassUp(target, 'dropdownInput'); if (inpt != null) { return getDropdown(inpt).handleMouseDown(evnt); } } function dropdownOnMouseUp(evnt) { var target = getTarget(evnt); if ( currentMultiDropdown != null && currentMultiDropdown.onMouseMoveIdx != -1 ) { currentMultiDropdown.onMouseMoveIdx = -1; currentMultiDropdown = null; } if ( currentDropdown != null ) { var inpt = findClassUp(target, 'dropdownInput'); if (inpt == null && currentDropdown.seenMouseMove) { var div = findClassUp(target, 'dropdownSelected'); if (div != null) currentDropdown.setAndClose(div.nlrow); currentDropdown.close(); currentDropdown = null; } } } var lastX, lastY; function dropdownOnMouseMove(evnt) { if (isIE) evnt = event; if (evnt.clientX == lastX && evnt.clientY == lastY) return; lastX = evnt.clientX; lastY = evnt.clientY; var target = getTarget(evnt); if ( currentMultiDropdown != null ) currentMultiDropdown.handleMouseMove(evnt); if ( currentDropdown != null ) currentDropdown.handleMouseMove(evnt); } function dropdownOnKeyDown(evnt) { var target = getTarget(evnt); var inpt = findClassUp(target, 'dropdownInput'); if ( isNLMultiDropDown(target) ) { return multidropdowns[target.ddname].handleKeydown(evnt); } else { return true; } } function getButtonId(evnt) { if(isIE) return event.button; else if(isNS) return evnt.button; else return null; } function getKeypress(evnt) { if (isIE) return event.keyCode; if (isNS) return evnt.which; } function dumpObj(obj) { for(var prop in obj) { var str = prop + ": " + obj[prop]; document.body.appendChild(document.createTextNode(str)); document.body.appendChild(document.createElement("BR")); } } NLDropdown.prototype.hasAttribute = function NLDropdown_hasAttribute(flag) { return (this.flags & flag) != 0; } function NLDropdown(name, values, defaultIndex, count, renderDocument) { if (name == null) throw "cannot create dropdown with null name"; if (values == null) throw "cannot create dropdown with null values"; this.name = name; this.nameC = name + count; this.textArray = new Array(values.length / 2); this.valueArray = new Array(values.length / 2); this.valueToIndexMap = new Array(); this.defaultIndex = defaultIndex; this.isOpen = false; this.divWidthHasBeenSet = false; this.disabled = false; this.div = null; this.currentCell = null; this.searchString = ""; this.typeAhead = false; this.cancelEventOnEnterKey = false; this.width = null; this.flags = 0; // we do this once at creation time to allow all of the fields to properly intialize this.inpt = renderDocument.getElementById("inpt_" + this.nameC); this.hddn = renderDocument.getElementById("hddn_" + this.nameC); this.indx = renderDocument.getElementById("indx_" + this.nameC); // we are always making the assumption that these fields exist within a span (created in NLSelect) this.span = this.inpt.parentNode; this.inpt.onmousedown = new Function("var dd=getDropdown(this); if (!dd.disabled) dd.setArrowImage('/images/forms/ddarrowPress.gif');"); this.inpt.onmouseup = new Function("getDropdown(this).setArrowImage('/images/forms/ddarrow.gif' );") // but the first time we open it up, we do it again because there are cases in dynamic content // where the fields move into a new document, and we want that document to have reference // to the fields after they move this.elementsAreInitialized = false; for (var i=0,j=0; i < values.length; i +=2, j++) { var txt = values[i]; var val = values[i+1]; this.textArray[j] = txt; this.valueArray[j] = val; this.valueToIndexMap[String(val)] = j; } this.setIndex(defaultIndex, true ); this.setText(this.textArray[this.getIndex()], true ); } /** * Initialize the new elements based on the current document reference. This is executed the first * time an NLDropdown is opened since it must reference objects in the current window. This is * necessary since NLDropdowns can be created in different windows than they are actually displayed * and used in. (mostly for dynamic content such as portlets and list machines) */ NLDropdown.prototype.initializeElements = function NLDropdown_initializeElements() { this.inpt = document.getElementById("inpt_" + this.nameC); this.hddn = document.getElementById("hddn_" + this.nameC); this.indx = document.getElementById("indx_" + this.nameC); // we are always making the assumption that these fields exist within a span (created in NLSelect) this.span = this.inpt.parentNode; this.elementsAreInitialized = true; } NLDropdown.prototype.setWidth = function NLDropdown_setWidth(width, minimumWidth) { if (minimumWidth != null) this.minimumWidth = minimumWidth; if (width != null) { this.width = width; this.setWidthDirect(width + 16); } else { if (this.div == null) this.buildDiv(); var div = this.div; var newWidth; document.body.insertBefore(div, document.body.firstChild); if (div.offsetHeight < 200) { newWidth = div.offsetWidth + 5 + 16; if (newWidth < 40) newWidth = 40; } else { newWidth = div.offsetWidth + 15 + 16; } document.body.removeChild(div); if (this.inpt.originalWidth != newWidth) { this.setWidthDirect(newWidth); this.inpt.originalWidth = null; if (this.inpt.afterWidthSet != null) this.inpt.afterWidthSet(); } } this.setText(null, true ); } NLDropdown.prototype.setWidthDirect = function NLDropdown_setWidthDirect(width) { if ((this.minimumWidth != null) && (width < this.minimumWidth)) width = this.minimumWidth; this.inpt.style.width = width; } NLDropdown.prototype.buildDiv = function NLDropdown_buildDiv() { var div = document.createElement("div"); this.div = div; div.className = 'dropdownDiv'; div.style.zIndex = 1000; this.divWidthHasBeenSet = false; var divArray = new Array(this.textArray.length); this.divArray = divArray; var i, div2; for (i=0; i < this.textArray.length; i++) { var msg = this.textArray[i]; if (msg == null || msg.length == 0) msg = " "; div2 = document.createElement("div"); divArray[i] = div2; div2.innerHTML = msg; div2.id = "nl" + ++tdCounter; div2.nlrow = i; div2.className = 'dropdownNotSelected'; div.appendChild(div2); } div.onkeydown=new Function("getDropdownFromNameC('"+this.nameC+"').handleKeydown()"); div.onkeypress=new Function("getDropdownFromNameC('"+this.nameC+"').handleKeypress()"); } NLDropdown.prototype.sizeDiv = function NLDropdown_sizeDiv() { var div = this.div; if(!this.divWidthHasBeenSet) { var divWidth = div.offsetWidth; var inptWidth = this.inpt.offsetWidth; div.style.overflow = 'hidden'; if (divWidth < inptWidth) { div.style.width = inptWidth; } else { div.style.width = divWidth + 4; } } // Calculate how much viewing area there actually is above and below the input field (NLDropdown). // Based on this we decide how large to make the div, and then later we position it in that spot var inputYPos = findPosY(this.inpt); var iDistanceFromDDtoTop = inputYPos - document.body.scrollTop; var iDistanceFromDDtoBottom = getDocumentHeight() - ( (inputYPos - document.body.scrollTop) + this.inpt.offsetHeight) ; var iMaxDistance = Math.max(iDistanceFromDDtoTop,iDistanceFromDDtoBottom); if (div.offsetHeight < Math.min(200,iMaxDistance)) { if (isIE) { } else if (isNS) { div.style.height = div.offsetHeight; if(!this.divWidthHasBeenSet) div.style.width = this.inpt.offsetWidth - 6; } } else { var newHeight = Math.min(iMaxDistance,200); div.style.height = newHeight - 2; div.style.overflow = 'auto'; if(!this.divWidthHasBeenSet) { if (isIE) { div.style.width = div.offsetWidth + 25; } else if (isNS) { div.style.width = div.offsetWidth - 12; } } } this.divWidthHasBeenSet = true; } NLDropdown.prototype.open = function NLDropdown_open() { // the first time we open up a dropdown, we have to set up some basics if(!this.elementsAreInitialized) this.initializeElements(); if (this.disabled || this.textArray.length == 0) return; if (this.div == null) this.buildDiv(); document.body.insertBefore(this.div, document.body.firstChild); this.sizeDiv(); // extreme editable fields must exist within relatively positioned SPANs so we need // a slightly different positioning algorithm if(this.hasAttribute(4096)) this.positionRelativeDiv(); else this.positionDiv(); this.isOpen = true; this.seenMouseMove = false; this.setCurrentCellInMenu(null); if (isIE && this.currentCell != null) this.div.scrollTop = this.currentCell.offsetTop; } NLDropdown.prototype.positionRelativeDiv = function NLDropdown_positionRelativeDiv() { this.span.style.zIndex = 1; this.span.insertBefore(this.div,this.span.firstChild); var x = findPosX(this.span); var y = findPosY(this.span); // we never have to shift the div on the x-axis in extreme lists because the input element is contained within the span in the cell this.div.style.left = 0; if ((y + this.inpt.offsetHeight + this.div.offsetHeight)-document.body.scrollTop > getDocumentHeight()) this.div.style.top = 3 - this.div.offsetHeight; else this.div.style.top = this.inpt.offsetHeight - 1; } NLDropdown.prototype.positionDiv = function NLDropdown_positionDiv() { var x = findPosX(this.inpt); if (x + this.div.offsetWidth <= getDocumentWidth()) this.div.style.left = x; else this.div.style.left = getDocumentWidth() - this.div.offsetWidth; var y = findPosY(this.inpt); if (y + this.inpt.offsetHeight + this.div.offsetHeight > getDocumentHeight()) { this.div.style.top = Math.max(y - this.div.offsetHeight,0); } else { if (isIE) this.div.style.top = y + this.inpt.offsetHeight - 1; else if (isNS) this.div.style.top = y + this.inpt.offsetHeight; } } NLDropdown.prototype.close = function NLDropdown_close() { if (!this.isOpen) return; this.setFocus(); if (this.indexOnDeck != null) { this.setIndex(this.indexOnDeck); this.indexOnDeck = null; } if (this.currentCell != null) { this.currentCell.className = 'dropdownNotSelected'; this.currentCell = null; } this.span.style.zIndex = null; this.div.parentNode.removeChild(this.div); this.isOpen = false; } NLDropdown.prototype.setFocus = function NLDropdown_setFocus() { try { this.inpt.focus(); this.inpt.select(); } catch (e) { } } NLDropdown.prototype.setText = function NLDropdown_setText(newVal, dontFocus, width) { if (newVal == null) newVal = this.getText(); this.inpt.title = newVal; if (newVal == null || newVal == "") newVal = " "; if (width == null) width = this.inpt.offsetWidth; width -= 17; newVal = elideTxt(newVal, width); this.inpt.setAttribute("value", newVal); if (!dontFocus || this == currentDropdown) { try { this.inpt.focus(); if (!this.isOpen) this.inpt.select(); } catch (e) { } } } NLDropdown.prototype.getText = function NLDropdown_getText(index) { if (index == null) index = this.getIndex(); if ((index == null) || (index < 0) || (index > this.textArray.length)) return ""; return this.textArray[index]; } NLDropdown.prototype.getValue = function() { var returnMe = this.hddn.value; return returnMe; } NLDropdown.prototype.setAndClose = function NLDropdown_setAndClose(idx) { this.close(); this.setIndex(idx); } function getNext(n) { var returnMe = n.firstChild; if (returnMe == null) { returnMe = n.nextSibling; if ((returnMe == null) && (returnMe.parentNode != null)) returnMe = n.parentNode.nextSibling; } return returnMe; } NLDropdown.prototype.setCurrentCellInMenu = function NLDropdown_setCurrentCellInMenu(cell) { if (!this.isOpen) return; var initial = cell; if (cell == null) { var rowNum = this.getIndex(); if (rowNum < 0 || rowNum > this.divArray.length || rowNum === undefined) { rowNum = 0; } cell = this.divArray[rowNum]; } if (this.currentCell != null) this.currentCell.className ='dropdownNotSelected'; if (cell != null) cell.className = 'dropdownSelected'; this.currentCell = cell; } NLDropdown.prototype.getIndex = function NLDropdown_getIndex() { return Number(this.indx.value); } NLDropdown.prototype.setIndex = function NLDropdown_setIndex(newIdx, noFocusOrOnChange) { if (newIdx == null) return; newIdx = Number(newIdx); if (newIdx < 0 || newIdx >= this.valueArray.length) return; var old = this.getIndex(); if (old == newIdx) return; this.indx.setAttribute("value", newIdx); this.hddn.setAttribute("value", this.valueArray[newIdx]); this.setText(this.textArray[newIdx], noFocusOrOnChange); if ((!noFocusOrOnChange) && (this.hddn.onchange != null)) { var isvalid = this.hddn.onchange(); if ( isvalid == false ) { this.indx.setAttribute("value", old); this.hddn.setAttribute("value", this.valueArray[old]); this.setText(this.textArray[old], noFocusOrOnChange); return; } } } NLDropdown.prototype.setValue = function NLDropdown_setValue(val, noFocusOrOnChange) { var mappedIndex = this.getIndexForValue(val); if (mappedIndex == null) return; this.setIndex(mappedIndex, noFocusOrOnChange); } NLDropdown.prototype.getValueAtIndex = function NLDropdown_getValueAtIndex(idx) { return this.valueArray[idx]; } NLDropdown.prototype.getTextAtIndex = function NLDropdown_getTextAtIndex(idx) { return this.textArray[idx]; } NLDropdown.prototype.respondToArrow = function NLDropdown_respondToArrow(offset) { var i; if (this.currentCell == null) { i = this.getIndex(); } else { i = this.currentCell.nlrow; } i += offset; if (i < 0) i = 0; if (i >= this.valueArray.length) i = this.valueArray.length - 1; if (this.isOpen) { var txt = this.textArray[i]; this.setText(txt); this.setCurrentCellInMenu(this.divArray[i]); if (isIE) { var scrollTop = this.currentCell.parentNode.scrollTop; var lineTop = this.currentCell.offsetTop; var scrollHeight = this.currentCell.parentNode.offsetHeight; var lineHeight = this.currentCell.offsetHeight; if (scrollTop > lineTop) this.currentCell.scrollIntoView(true); else if (scrollTop + scrollHeight < lineTop + lineHeight) this.currentCell.scrollIntoView(false); } this.indexOnDeck = i; } else { var value = this.valueArray[i]; if ((value == -1) && (offset > 0)) { if (i+1 < this.valueArray.length) // go on to the next option only if there's a next option to go on to this.respondToArrow(offset + 1); } else { this.setIndex(i); } } } NLDropdown.prototype.gotoNext = function NLDropdown_gotoNext(key) { if (this.searchStringTimeout != null) { clearTimeout(this.searchStringTimeout); this.searchStringTimeout = null; } var startIndex = this.getIndex(); if (this.currentCell != null) startIndex = this.currentCell.nlrow; var ctr = startIndex; var i; var len = this.textArray.length; this.searchString += String.fromCharCode(key).toUpperCase(); if (this.searchString.length == 1) ++ctr; var matched = false; for (var tries = 0; tries < len; tries++) { i = ctr % len; var match = this.textArray[i].substr(0, this.searchString.length).toUpperCase(); if (match == this.searchString) { matched = true; break; } ++ctr; } if (matched) { if (this.isOpen) { this.setText(this.textArray[i]); this.setCurrentCellInMenu(this.divArray[i]); this.div.scrollTop = this.currentCell.offsetTop; this.indexOnDeck = i; } else { this.setIndex(i); } } if (this.typeAhead == true) this.searchStringTimeout = setTimeout("clearSearchString('"+this.nameC+"')", 2000); else this.searchString = ""; } function clearSearchString(namec) { getDropdownFromNameC(namec).searchString = ""; } NLDropdown.prototype.getTextForValue = function NLDropdown_getTextForValue(value) { var idx = this.getIndexForValue(value); if (idx != null) return this.textArray[idx]; else return ""; } NLDropdown.prototype.getIndexForText = function NLDropdown_getIndexForText(text) { for(var i=0; i= maxWidth) return ellipsis; var len = txt.length; for (var i=0; i < len; i++) { var mid = txt.length/2; txt = txt.substr(0, mid) + txt.substr(mid+1); var txtWidth = getTextWidth(txt); if (txtWidth + ellipsisWidth < maxWidth) break; } return txt.substr(0, mid) + ellipsis + txt.substr(mid); } var multidropdowns = new Array(); var currentMultiDropdown = null; function NLMultiDropdown(name, values, defaultValues,height,renderDocument) { if (name == null) throw "cannot create multi-select dropdown with null name"; if (values == null) throw "cannot create multi-select dropdown with null values"; this.renderDocument = renderDocument; this.name = name; this.textArray = new Array(values.length / 2); this.valueArray = new Array(values.length / 2); this.valueToIndexMap = new Array(); this.defaultValues = defaultValues; this.selectedVals = isValEmpty(this.defaultValues) ? new Array() : this.defaultValues.split(String.fromCharCode(5)); this.numRows=height; this.disabled = false; this.span = null; this.table = null; this.width = null; this.hiddenField = renderDocument.getElementById("hddn_" + this.name); this.parentSpan = this.getParentSpan(); this.focusField = renderDocument.getElementById(this.name+"_focus"); this.focusField.onfocus = new Function("getMultiDropdown(\""+this.name+"\").setFocus();"); if ( isNS ) this.parentSpan.onmousedown = new Function("return false;"); else this.parentSpan.onselectstart = new Function("return false;"); this.currentIdx = -1; this.previousIdx = -1; this.onMouseMoveIdx = -1; for (var i=0,j=0; i < values.length; i +=2, j++) { var txt = values[i]; var val = values[i+1]; this.textArray[j] = txt; this.valueArray[j] = val; this.valueToIndexMap[String(val)] = j; } this.setWidth(); this.defaultBorderColor = this.table.style.borderColor; } function makeMultiDropdown(name, height, values, defaultvals, onChange, renderDocument) { if (renderDocument == null) renderDocument = document; if (values.length > 0) { for (var i=0; i < values.length; i += 2) values[i] = escapeHtml(values[i]); } else values = ["",""]; if (onChange != null) onChange = "onchange=\""+onChange+"\""; renderDocument.write(""); renderDocument.write(""); var dd = new NLMultiDropdown(name, values, defaultvals, height, renderDocument); // we never want to add the object twice if(window.multidropdowns[name] == null) window.multidropdowns[name] = dd; return dd; } NLMultiDropdown.prototype.getParentSpan = function NLMultiDropdown_getParentSpan() { var span = this.renderDocument.getElementById(this.name+"_fs"); if ( span == null ) { var spans = this.renderDocument.getElementsByTagName('SPAN'); for ( i = 0; i < spans.length; i++ ) { if ( spans[i].id != null && spans[i].id.split("_").length > 1 ) { tokens = spans[i].id.split("_"); if ( tokens[tokens.length-1] == "fs" && tokens[tokens.length-2] == this.name ) { span = spans[i]; break; } } } } return span; } NLMultiDropdown.prototype.buildSpan = function NLMultiDropdown_buildSpan() { this.span = this.renderDocument.createElement("span"); this.parentSpan.insertBefore(this.span,this.hiddenField); this.span.style.position='relative'; this.span.className = 'dropdownDiv'; this.span.style.height=parseInt(this.numRows)*15; this.span.style.overflow = 'auto'; this.span.isddmultiselect = true; this.span.ddname=this.name; this.table = this.renderDocument.createElement("table"); this.span.appendChild(this.table); this.table.cellSpacing = 0; this.table.cellPadding = 0; this.table.isddmultiselect = true; this.table.style.borderCollapse = 'collapse'; this.table.ddname=this.name; var tbody = this.renderDocument.createElement("tbody"); this.table.appendChild(tbody); for (var i=0; i < this.textArray.length; i++) { var tr = this.renderDocument.createElement("tr"); tbody.appendChild(tr); var td = this.renderDocument.createElement("td"); tr.appendChild(td); td.className = this.contains(i) ? 'dropdownSelected' : 'dropdownNotSelected'; td.style.whiteSpace = "nowrap"; td.style.borderWidth='0px'; td.style.borderStyle='solid'; td.style.borderColor='#FFFFFF'; td.nlrow=i; td.isddmultiselect = true; td.ddname=this.name; var msg = this.textArray[i]; if ( isValEmpty(msg) ) msg = " "; td.innerHTML = msg; td.onkeypress = new Function("getMultiDropdown(\""+this.name+"\").handleKeypress();"); } } NLMultiDropdown.prototype.setFocus = function NLMultiDropdown_setFocus() { try { this.table.focus(); if ( this.selectedVals.length == 0 ) this.highLightBorder(0); } catch (e) { } } NLMultiDropdown.prototype.setWidth = function NLMultiDropdown_setWidth(width) { if ( this.span == null ) this.buildSpan(); var newWidth = this.table.offsetWidth + 5 + 16; if (newWidth < 40) newWidth = 40; this.table.style.width = newWidth; this.parentSpan.style.width = newWidth; this.width = newWidth; } NLMultiDropdown.prototype.becomeCurrent = function NLMultiDropdown_becomeCurrent() { if (currentMultiDropdown != this) currentMultiDropdown = this; } NLMultiDropdown.prototype.resetDropDown = function NLMultiDropdown_resetDropDown() { this.removeAll(); this.previousIdx = -1; this.currentIdx = -1; this.selectedVals = isValEmpty(this.defaultValues) ? new Array() : this.defaultValues.split(String.fromCharCode(5)); var numOptions = this.selectedVals.length; var idx = 0; while ( idx < numOptions ) this.add(this.valueToIndexMap[this.selectedVals[idx++]], true); if ( this.width == null ) this.setWidth(); this.setHiddenField(); } NLMultiDropdown.prototype.getTextForValue = function NLMultiDropdown_getTextForValue(value) { var idx = this.getIndexForValue(value); if (idx != null) return this.textArray[idx]; else return ""; } NLMultiDropdown.prototype.getIndexForValue = function NLMultiDropdown_getIndexForValue(value) { return this.valueToIndexMap[String(value)]; } NLMultiDropdown.prototype.setValue = function NLMultiDropdown_setValue(value) { this.setIndex(valueToIndexMap[value]); } NLMultiDropdown.prototype.setIndex = function NLMultiDropdown_setIndex(idx) { if (this.disabled) return; if ( event.shiftKey ) this.handleShiftKey(Math.min(this.currentIdx,idx),Math.max(this.currentIdx,idx)); else if ( event.ctrlKey ) { if ( this.contains(idx) ) this.remove(idx, true); else this.add(idx, true); } else { this.removeAll(); this.add(idx, true); } this.highLightBorder(idx); this.previousIdx = idx; this.setHiddenField(true); } NLMultiDropdown.prototype.setValues = function NLMultiDropdown_setValues(vals) { this.removeAll(); this.previousIdx = -1; var valueArray = vals.split(String.fromCharCode(5)); var i = 0; for ( i = 0; i < valueArray.length; i++ ) this.add(this.getIndexForValue(valueArray[i]),true); this.setHiddenField(true); } NLMultiDropdown.prototype.highLightBorder = function NLMultiDropdown_highLightBorder(idx) { if ( this.previousIdx != -1 ) { this.getCell(this.previousIdx).style.borderStyle='solid'; this.getCell(this.previousIdx).style.borderColor='#FFFFFF'; } this.getCell(idx).style.borderStyle='dotted'; this.getCell(idx).style.borderColor=this.defaultBorderColor; } NLMultiDropdown.prototype.handleScrolling = function NLMultiDropdown_handleScrolling(idx) { if ( isIE ) { var windowTop = this.span.scrollTop; var windowBottom = this.span.scrollTop + this.getCell(idx).offsetHeight * Math.max(1,this.numRows-1); if ( this.getCell(idx).offsetTop > (windowBottom+this.getCell(idx).offsetHeight) || this.getCell(idx).offsetTop < (windowTop-this.getCell(idx).offsetHeight) ) this.span.scrollTop = this.getCell(idx).offsetTop; else if ( this.getCell(idx).offsetTop > windowBottom ) this.span.scrollTop += this.getCell(idx).offsetHeight; else if ( this.getCell(idx).offsetTop < windowTop ) this.span.scrollTop -= this.getCell(idx).offsetHeight; } } NLMultiDropdown.prototype.getSelectedValues = function NLMultiDropdown_getSelectedValues() { return this.selectedVals.join(String.fromCharCode(5)); } NLMultiDropdown.prototype.getSelectedText = function NLMultiDropdown_getSelectedText(delim) { var val = ''; if ( isValEmpty(delim) ) delim = ','; if ( this.selectedVals.length > 0 ) { for ( var i=0; i < this.selectedVals.length; i++) val += (i == 0 ? '' : delim) + this.getText(this.valueToIndexMap[this.selectedVals[i]]); } return val; } NLMultiDropdown.prototype.getSelectedTextFromValues = function NLMultiDropdown_getSelectedTextFromValues(values,delim) { var val = ''; if ( isValEmpty(delim) ) delim = ','; if ( !isValEmpty(values) ) { var tokens = values.split(String.fromCharCode(5)); for ( var i=0; i < tokens.length; i++) val += (i == 0 ? '' : delim) + this.getText(this.valueToIndexMap[tokens[i]]); } return val; } NLMultiDropdown.prototype.setHiddenField = function NLMultiDropdown_setHiddenField(invokeOnChange) { this.hiddenField.value = this.getSelectedValues(); if ( invokeOnChange ) this.hiddenField.onchange(); } NLMultiDropdown.prototype.removeAll = function NLMultiDropdown_removeAll() { var vals = this.selectedVals; for ( var i=0; i < vals.length; i++ ) { var idx = this.valueToIndexMap[vals[i]]; this.remove(idx, true); this.getCell(idx).style.borderStyle='solid'; this.getCell(idx).style.borderColor='#FFFFFF'; } } NLMultiDropdown.prototype.add = function NLMultiDropdown_add(idx,updateCell) { if (idx == null) return; this.currentIdx = idx; arrayAdd(this.selectedVals, this.getValue(idx)); if ( updateCell ) this.getCell(idx).className= 'dropdownSelected'; } NLMultiDropdown.prototype.remove = function NLMultiDropdown_remove(idx, updateCell) { if (idx == null) return; this.selectedVals = arrayRemove(this.selectedVals, this.getValue(idx)); if ( updateCell ) this.getCell(idx).className= 'dropdownNotSelected'; } NLMultiDropdown.prototype.contains = function NLMultiDropdown_contains(idx) { return arrayContains(this.selectedVals,this.valueArray[idx]); } NLMultiDropdown.prototype.getCell = function NLMultiDropdown_getCell(idx) { return this.table.rows[idx].cells[0]; } NLMultiDropdown.prototype.getValue = function NLMultiDropdown_getValue(idx) { return this.valueArray[idx]; } NLMultiDropdown.prototype.getText = function NLMultiDropdown_getText(idx) { return this.textArray[idx]; } NLMultiDropdown.prototype.setBackgroundColor = function NLMultiDropdown_setBackgroundColor(clr) { this.defaultBorderColor = clr; this.table.style.backgroundColor = clr; this.span.style.backgroundColor = clr; } NLMultiDropdown.prototype.handleShiftKey = function NLMultiDropdown_handleShiftKey(from_idx, to_idx) { if ( from_idx > to_idx || from_idx < 0 || to_idx >= this.valueArray.length ) return; else { var i = 0; while ( i < this.valueArray.length ) { if ( i >= from_idx && i <= to_idx ) this.add(i, true) else this.remove(i, true); i++; } } } NLMultiDropdown.prototype.handleMoveSelection = function NLMultiDropdown_handleMoveSelection(offset) { var numValues = this.valueArray.length; var idx = this.currentIdx; idx += offset; idx = Math.min(idx,numValues-1); idx = Math.max(idx, 0); if ( event.shiftKey ) this.handleShiftKey(Math.min(this.previousIdx,idx),Math.max(this.previousIdx,idx)); else this.removeAll(); this.add(idx, true); this.highLightBorder(idx); if ( !event.shiftKey ) this.previousIdx = idx; this.handleScrolling(idx); this.setHiddenField(true); } NLMultiDropdown.prototype.handleTypeAhead = function NLMultiDropdown_handleTypeAhead(key) { var ctr = Math.max(this.currentIdx, 0)+1; var i; var len = this.textArray.length; var searchString = String.fromCharCode(key).toUpperCase(); var matched = false; for (var tries = 0; tries < len; tries++) { i = ctr % len; var match = this.textArray[i].substr(0, searchString.length).toUpperCase(); if (match == searchString) { matched = true; break; } ++ctr; } if (matched) { this.removeAll(); this.add(i, true); this.highLightBorder(i); this.previousIdx = i; this.handleScrolling(i); this.setHiddenField(true); } } NLMultiDropdown.prototype.handleMouseMove = function NLMultiDropdown_handleMouseMove(evnt) { if ( this.disabled ) return; if ( this.onMouseMoveIdx == -1 ) return; var target = getTarget(evnt); while (target != null) { if (target.className != null && !isNaN(target.nlrow) && target.nlrow != 'undefined' ) { var idx = target.nlrow; var doRemoveOption = this.onMouseMoveIdx != this.previousIdx && this.contains(this.onMouseMoveIdx) && Math.abs(this.previousIdx-this.onMouseMoveIdx) > Math.abs(this.previousIdx-idx); if ( doRemoveOption ) this.remove(this.onMouseMoveIdx, true); else { var from_idx = Math.min(this.previousIdx, idx); var to_idx = Math.max(this.previousIdx, idx); for ( var i = from_idx; i <= to_idx; i++ ) { if ( !this.contains(i) ) this.add(i, true); } } this.handleScrolling(idx); this.onMouseMoveIdx = idx; break; } target = target.parentNode; } this.setHiddenField(true); } NLMultiDropdown.prototype.handleMouseDown = function NLMultiDropdown_handleMouseDown(evnt) { if (this.disabled) return; this.becomeCurrent(); var target = getTarget(evnt); if ( target != null && !isNaN(target.nlrow) && target.nlrow != 'undefined' ) { this.onMouseMoveIdx = target.nlrow; this.setIndex(target.nlrow) this.handleScrolling(target.nlrow); } } NLMultiDropdown.prototype.handleKeydown = function NLMultiDropdown_handleKeydown(evnt) { if (this.disabled) return; this.becomeCurrent(); var bReturnMe = false; var keycode = getKeypress(evnt); switch (keycode) { case 33: this.handleMoveSelection(-this.numRows); break; case 34: this.handleMoveSelection(+this.numRows); break; case 35: this.handleMoveSelection(this.valueArray.length-this.currentIdx); break; case 36: this.handleMoveSelection(-this.currentIdx); break; case 38: this.handleMoveSelection(-1); break; case 40: this.handleMoveSelection(+1); break; default: bReturnMe = true; break; } return bReturnMe; } NLMultiDropdown.prototype.handleKeypress = function NLMultiDropdown_handleKeypress(evnt) { if (this.disabled) return true; this.becomeCurrent(); var key = getKeypress(evnt); this.handleTypeAhead(key); } NLMultiDropdown.prototype.setDisabled = function NLMultiDropdown_setDisabled(val) { this.disabled = val; this.hiddenField.disabled = val; if ( !this.disabled && this.span == null && this.width == null ) { this.setWidth(); this.setBackgroundColor(this.defaultBorderColor); } } NLMultiDropdown.prototype.setHidden = function NLMultiDropdown_setHidden(val) { if ( this.span != null ) this.span.style.display = val ? "none" : ""; } NLMultiDropdown.prototype.addOption = function NLMultiDropdown_addOption(text, val, selected) { if ( val == null ) throw "cannot create an option with null value"; if ( text == null ) throw "cannot create an option with null text"; text = String(text); val = String(val); this.textArray[this.textArray.length] = text; this.valueArray[this.valueArray.length] = val; this.valueToIndexMap[val] = this.valueArray.length-1; if ( selected ) this.add(this.valueArray.length-1, false); if ( this.span != null ) this.parentSpan.removeChild(this.span); this.span = null; if ( !this.disabled ) { this.width = null; this.setWidth(); this.setBackgroundColor(this.defaultBorderColor); } this.setHiddenField(); this.handleScrolling(this.valueArray.length-1); } NLMultiDropdown.prototype.deleteAllOptions = function NLMultiDropdown_deleteAllOptions() { this.valueArray.length = 0; this.textArray.length = 0; this.valueToIndexMap = new Array(); this.previousIdx = -1; this.currentIdx = -1; this.selectedVals = new Array(); this.parentSpan.removeChild(this.span); this.span = null; this.width = null; this.setWidth(); this.setBackgroundColor(this.defaultBorderColor); this.setHiddenField(); } NLMultiDropdown.prototype.deleteOneOption = function NLMultiDropdown_deleteOneOption(val) { val = String(val); var i = this.valueToIndexMap[val]; if (i == null) return; this.valueArray.splice(i,1); this.textArray.splice(i,1); delete this.valueToIndexMap[val]; this.selectedVals = arrayRemove(this.selectedVals, val); this.parentSpan.removeChild(this.span); this.span = null; this.width = null; this.setWidth(); this.setBackgroundColor(this.defaultBorderColor); this.setHiddenField(); } function getMultiDropdown(name, win) { if (win == null) win = window; var returnMe = win.multidropdowns[name]; if ((returnMe == null) && (win.parent != null) && (win.parent.multidropdowns != null)) returnMe = win.parent.multidropdowns[name]; return returnMe; } function arrayContains(array, val) { for ( var i = 0; i < array.length; i++ ) { if ( val == array[i] ) return true; } return false; } function arrayAdd(array, val) { if ( !arrayContains(array, val) ) array.push(val); } function arrayRemove(array, val) { var newarray = new Array(); for ( var i = 0; i < array.length; i++ ) { if ( val != array[i] ) newarray.push(array[i]); } return newarray; } function resetNLDropDowns(frm) { if ( window.dropdowns != null ) { for ( i in window.dropdowns ) { var dd = window.dropdowns[String(i)]; if ( frm == null || dd.hddn.form == frm ) dd.resetDropDown(); } } if ( window.multidropdowns != null ) { for ( i in window.multidropdowns ) { var dd = window.multidropdowns[String(i)]; if ( frm == null || dd.hiddenField.form == frm ) dd.resetDropDown(); } } } var _popup_help = ''; var _mult_popup_help = ''; var dragger = null; var mouseX=0, mouseY=0; var currentPortlet = null; var bar = null; function NLPortletDragger() { this.trToBeMoved = null; this.divContainer = null; this.width = null; this.originalColumn = null; this.originalNext = null; this.originalContainer = null; this.widthPlaceHolder = null; this.portletID = null; } NLPortletDragger.prototype.putDownPortlet = function NLPortletDragger_putDownPortlet() { if (bar && bar.parentNode) bar.parentNode.removeChild(bar); var moveTo = currentPortlet; this.divContainer.parentNode.removeChild(this.divContainer); if (moveTo != null) { // Figure out which column of the main table we are trying to put this portlet in (0 based) var newColumn = moveTo.parentNode.parentNode.parentNode.cellIndex + 1; moveTo.parentNode.insertBefore(this.trToBeMoved, moveTo); updateLayoutInDatabase(this.portletID, moveTo.portletID, newColumn, this.originalColumn); } else { // this object has not moved, so put it back where it was without making any database changes this.originalContainer.insertBefore(this.trToBeMoved, this.originalNext); } // remove the width placeholder (tr) this.originalContainer.removeChild(this.widthPlaceHolder); // we're done, so set the currentPortlet to null currentPortlet = null; } NLPortletDragger.prototype.putDownRow = function NLPortletDragger_putDownRow() { if (bar && bar.parentNode) bar.parentNode.removeChild(bar); var moveTo = currentPortlet; if ( this.divContainer != null ) { this.divContainer.parentNode.removeChild(this.divContainer); this.originalContainer.insertBefore(this.trToBeMoved, this.originalNext); } if (moveTo != null && OrderedListMoveLineTo) OrderedListMoveLineTo(moveTo.machineName, moveTo.rowIndex); // we're done, so set the currentPortlet to null if ( currentPortlet != null && OrderedListMarkRowNavigation ) OrderedListMarkRowNavigation(currentPortlet, false); currentPortlet = null; } function movePortlet(origElement, evnt) { // I wrapped this entire method in a try/catch just to be safe. // If anything goes wrong here, we'll just do nothing to the layout try { // this handles cases where there are href links inside the TR that carries the onmousedown handler // for the portlet dragger. This will fire the href, and leave the portlet where it is var clickedElem = getTarget(evnt); if(clickedElem.parentNode.nodeName == "A") return true; // look for the closest element with the portlet handle class. This should be our parent TR var element = findClassUp(origElement, 'portletHandle'); dragger = new NLPortletDragger(); dragger.portletID = getPortletId(origElement.id); // grab the TR that contains the portlet and get the other objects we need to position it properly dragger.trToBeMoved = element; dragger.originalColumn = element.parentNode.parentNode.parentNode.cellIndex + 1; dragger.originalContainer = element.parentNode; dragger.originalNext = element.nextSibling; dragger.width = element.offsetWidth; // create the temporary div that we will drag around with the portlet in it dragger.divContainer = document.createElement("div"); dragger.divContainer.style.position = "absolute"; dragger.divContainer.style.width = dragger.width; dragger.divContainer.style.background = document.body.bgColor; dragger.divContainer.style.padding = "4px"; dragger.divContainer.style.borderWidth = 1; dragger.divContainer.style.borderColor = "#999999"; // we're just giving it a gray border for now. dragger.divContainer.style.borderStyle = "solid"; // insert a temp TR so that the width doesn't jump around on us // currently this is stretch.gif, but it could just as easily be a block level element dragger.widthPlaceHolder = document.createElement("tr"); var td = document.createElement("td"); var img = document.createElement("img"); td.appendChild(img); dragger.widthPlaceHolder.appendChild(td); img.src = "/images/nav/stretch.gif"; img.width = dragger.width; img.height = "0"; // add it to the end so that you don't see the 1 px jump dragger.originalContainer.appendChild(dragger.widthPlaceHolder); dragger.originalContainer.removeChild(element); // shrink the portlet. cute, but it only works on ie 5.5 and later //dragger.divContainer.style.zoom = 0.5; //dragger.width = 0.5 * dragger.width; var eTable = document.createElement("table"); eTable.style.borderWidth = 0; eTable.width = "100%"; var tBody = document.createElement("tbody"); eTable.appendChild(tBody); tBody.appendChild(element); dragger.divContainer.appendChild(eTable); document.body.appendChild(dragger.divContainer); // calculate the position of the floating portlet div that will follow the mouse positionFloatingPortlet(dragger.divContainer, 4); } catch (e) { } } function portletDraggerOnMouseMove(evnt) { // update the mouse position updateMousePosition(evnt); if (dragger) { // if there are scroll bars and we try to drag the portlet above or below // the current viewable area, we'll pop the scroll bars to the top or bottom // depending on which way they are dragging if( (document.body.scrollHeight > getDocumentHeight()) && (getDocumentHeight()-mouseY) < 10 ) document.body.scrollTop = document.body.scrollHeight - getDocumentHeight(); else if (mouseY < 15 && document.body.scrollTop > 0) document.body.scrollTop = 0; positionFloatingPortlet(dragger.divContainer, 4); // keep track of where we are portlet-wise var elem = getTarget(evnt); elem = findClassUp(elem, 'portletHandle'); if ((elem != null) && (elem != currentPortlet) && elem != dragger.trToBeMoved) { currentPortlet = elem; if (bar != null && bar.parentNode != null) bar.parentNode.removeChild(bar); bar = getPositionUpdateBar(); currentPortlet.portletID = getPortletId(currentPortlet.id); // showing the bar will crash ie5.0 windows about 20% of the time // if this turns into an issue with customers, we can just create a div to float over // the spot rather than inserting the hr into the table currentPortlet.parentNode.insertBefore(bar, currentPortlet); } } } function updateMousePosition(evnt) { // update the mouse position mouseX = getMouseX(evnt); mouseY = getMouseY(evnt); } function getPositionUpdateBar( adjacentrow ) { var tr = document.createElement("tr"); var td = document.createElement("td"); tr.appendChild(td); var hr = document.createElement("hr"); hr.style.width='100%'; hr.className = 'portletDragDropBar'; td.appendChild(hr); if ( adjacentrow && adjacentrow.cells.length > 0 ) { td.colSpan = adjacentrow.cells.length; hr.style.width='95%'; } return tr; } function positionFloatingPortlet(dragger, iDistanceY) { // set up some constants to make these easy to experiment with and change // margins specify the number of pixels between the edge of the page and the portlet div (prevents the div from leaving the page) var leftMargin = 8; var rightMargin = 10; var YdistanceFromMouseToDiv = iDistanceY; var clientWidth = getDocumentWidth(); // div would extend off the left screen, so we put it along the left margin if(mouseX < 15) dragger.style.left = leftMargin; // div would extend off the right of the screen, so put it along the right margin else if( (mouseX + dragger.offsetWidth) > (clientWidth - rightMargin) ) dragger.style.left = (clientWidth - rightMargin) - dragger.offsetWidth; // we have room, so keep it aligned with the mouse pointer else dragger.style.left = mouseX - 10; // the div must be slightly below the mouse so that we can keep track of which portlet the mouse is over // it's very important to include scrollTop property here... // And, we only change the y position if we are actually within the browser window if( mouseY < getDocumentHeight()) { if( (mouseY + dragger.offsetHeight) < getDocumentHeight()) dragger.style.top = mouseY + document.body.scrollTop + YdistanceFromMouseToDiv; else dragger.style.top = (mouseY + document.body.scrollTop + YdistanceFromMouseToDiv) - dragger.offsetHeight - 15 ; } } function portletDraggerOnMouseDown(evnt) { if(dragger || getButtonId(evnt) > 1) return; var target = getTarget(evnt); var element = findClassUp(target, 'portletDragDropIcon'); if (element != null && element.id != null) { movePortlet(element, evnt); } } function portletDraggerOnMouseUp() { if (dragger) { dragger.putDownPortlet(); dragger = null; return false; // if the user dropped the portlet on a link, don't navigate away } } function getPortletId(elementID) { if(elementID == null) return -1; else return elementID.substring(elementID.lastIndexOf("_")+1,elementID.length); } function updateLayoutInDatabase(moving, pushedDown, newColumn, oldColumn) { var sUrl = "/app/center/portletlayout.nl?movedid=" + moving + "&replacedid=" + pushedDown + "§ionid=-29&newcolumn=" + newColumn + "&oldcolumn=" + oldColumn; sendRequestToFrame(sUrl, "server_commands"); } function hidePortlet(iSection, iPortlet, elementId) { var element = document.getElementById(elementId); // now get the main TR that this portlet occupies in the table, and remove it element = findClassUp(element, 'portletHandle'); if(element != null) { element.parentNode.removeChild(element); var sUrl = "/app/center/hideportlet.nl?portletid="+iPortlet+"§ionid="+iSection+"&dynamic=T"; sendRequestToFrame(sUrl, "server_commands"); } } function refreshPortlet(sElementId, sStickyTag, noreload, sSectionId, iPortletId, iNewSearchId) { var serverUrl = "/app/center/setup/portletrefresher.nl?elemid="+sElementId+"&sticky="+sStickyTag; if(noreload != null) serverUrl += "&noreload=" + (noreload ? "T" : "F") ; if(sSectionId != null) serverUrl += "&sc=" + sSectionId; if(iPortletId != null) serverUrl += "&portletid=" + iPortletId; if(iNewSearchId != null) serverUrl += "&searchid=" + iNewSearchId; sendRequestToFrame(serverUrl,"server_commands"); } function sendRequestToFrame(url, frame) { try { document.frames[frame].document.location.replace(url); } catch (e) { } } var quickAddDragger = null; function quickaddDraggerOnMouseDown(evnt) { if(quickAddDragger || getButtonId(evnt) > 1) return; var target = getTarget(evnt); var element = findClassUp(target, 'quickaddDragDropIcon'); if (element != null && element.id != null) { quickAddDragger = findClassUp(element, "quickadddragger"); } } function quickaddDraggerOnMouseMove(evnt) { if(quickAddDragger != null) { positionFloatingPortlet(quickAddDragger, 0); } } function quickaddDraggerOnMouseUp() { quickAddDragger = null; return false; } /** * When you dynamically update a portlet, it's nice to see some visual evidence that the update * is actually happening. We change the "Update" link to "Updating..." and the 3 dots are animated * suggesting the action is in progress. */ function setPortletToUpdating(sElementId) { var spanId = "rfsh_" + sElementId; var span = document.getElementById(spanId); if(span != null) { var arrowImg = span.parentNode.previousSibling.firstChild; if(arrowImg != null && arrowImg.nodeName == "IMG") arrowImg.src = "/images/nav/dingbats/misc_arrow_gray.gif"; span.removeChild(span.firstChild); var fontTag = document.createElement("font"); fontTag.color = "#999999"; var text = document.createTextNode("Updating"); fontTag.appendChild(text); span.appendChild(fontTag); var img = document.createElement("img"); img.src = "/images/setup/updating.gif"; img.border = 0; span.appendChild(img); } } function statusMessage(ms,s) { if(ms == null) ms = 2000; window.status = s; setTimeout("clearStatusBar()", ms); } function clearStatusBar() { window.status = ""; }