//////////////////////////////////////////////////////////////////////////////// ///// /// Picklist.js -- (C) 1999,2003 by Ralph L. Brown (akakEk) ///// /// ///// /// This script, with copyright notice intact, may be freely ///// /// ///// /// distributed and used for any legal and legitimate ///// /// ///// /// purpose(s) except for the distribution of unsolicited ///// /// ///// /// email (spam) and the publication of pornographic content. ///// /// //////////////////////////////////////////////////////////////////////////////// var UNDEFINED; // do not assign! function getX(obj) { return( obj.offsetParent==null ? obj.offsetLeft : obj.offsetLeft+getX(obj.offsetParent) ); } function getY(obj) { return( obj.offsetParent==null ? obj.offsetTop : obj.offsetTop+getY(obj.offsetParent) ); } function isvalidchar(achar,validstr) { if ( !validstr ) validstr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 `~!@#$%^&*()_-+={}[]|:;'<>,./?\\\""; return( validstr.toUpperCase().indexOf(achar.toString().toUpperCase(),0) >= 0 ); } function getQualifiedName(formElement) { var i, j, fs = document.forms; _end: for (i = 0; i < fs.length; i++) { var f = fs[i].elements; for (j = 0; j < f.length; j++) { if (f[j] == formElement) { break _end; } } } return 'document.forms[' + i + '].elements[' + j + ']'; } function getTooltipDiv() { if ( document.getElementById ) return document.getElementById('divPicklistTooltip'); else if ( document.all ) return document.all.divPicklistTooltip; else return null; } function createTooltipDiv(objSel) { // var ev = "setupPicklist(" + getQualifiedName(objSel) + ")"; if ( !getTooltipDiv() ) // if this is the first time this function is { // called then create the tooltip text window. var tooltipDiv = ""; if ( document.body.insertAdjacentHTML ) { document.body.insertAdjacentHTML("beforeEnd",tooltipDiv); } else if ( document.createTextNode ) { var div = document.createElement("div"); div.innerHTML = tooltipDiv; document.body.appendChild(div); } else if ( document.body.innerHTML ) { document.body.innerHTML += tooltipDiv; } // necessary for netscape (don`t know why) // setTimeout(ev, 1 ); //setTimeout( "setupPicklist(" + getQualifiedName(objSel) + ")", 1 ); return true; } return false; } function showTooltipText(objSel) { if ( !objSel || objSel.Y==UNDEFINED ) // null or not setup { return false; } var divPicklistTooltip = getTooltipDiv(); var s = divPicklistTooltip.innerHTML = ""; with ( objSel ) { if ( strKeyInBuf=="" && title.length ) { s = '' + title + ''; } else if ( selectedIndex>=0 && strKeyInBuf==options[selectedIndex].text ) // unique match found { s = '' + strKeyInBuf + ''; } else { var c = strKeyInBuf.substring(strKeyInBuf.length-1,strKeyInBuf.length); c = ( c == ' ' ) ? ' ' : '' + c + ''; s = strKeyInBuf.substring(0,strKeyInBuf.length-1) + c; } divPicklistTooltip.innerHTML = '' + '
'+s+'
'; divPicklistTooltip.style.posLeft = divPicklistTooltip.style.left = (X + divPicklistTooltip.offsetWidth < document.body.clientWidth ? X : document.body.clientWidth - divPicklistTooltip.offsetWidth - 3); divPicklistTooltip.style.posTop = divPicklistTooltip.style.top = Y; hideConcurrentLayers(null); hideElement("SELECT", divPicklistTooltip); hideElement("APPLET", divPicklistTooltip); divPicklistTooltip.style.visibility = ""; } // end with return true; } function hideTooltipText(objSel) { if (objSel) objSel.strKeyInBuf = ""; var divPicklistTooltip = getTooltipDiv(); showElement("SELECT"); showElement("APPLET"); return divPicklistTooltip.innerHTML = ""; } function findSelectEntry( objSel, head, tail ) // uses divide-and-conquer search, assumes sorted list { with ( objSel ) { if ( options.length <= 0 ) { strKeyInBuf = ' No selections available. '; showTooltipText(objSel); top.status = strKeyInBuf = ""; return -1; } if ( strKeyInBuf == "" ) { showTooltipText(objSel); picklistChange(objSel, 0); picklistChange(objSel, options[selectedIndex].text.length ? -1 : 0); return( selectedIndex ); } var index = null; var match_count = 0; for (var i = 0; i < options.length; i++) { if (strKeyInBuf.toUpperCase() == options[i].text.substring(0,strKeyInBuf.length).toUpperCase() ) { match_count++; if (index === null) { index = i; // first match } } } if (index !== null) { picklistChange(objSel, index); if (match_count == 1) { // unique match found top.status = strKeyInBuf = options[index].text; } else { top.status = strKeyInBuf = options[index].text.substring(0,strKeyInBuf.length); } showTooltipText(objSel); return selectedIndex; } else { // then since no exact match was found, go back to previous strKeyInBuf (thus the length-1) strKeyInBuf = strKeyInBuf.substring(0,strKeyInBuf.length-1) return findSelectEntry( objSel ); } } // end with } function picklistFocusHandler(e) { var event = e ? e : window.event; // to handle both NS and IE events var objSel = event.target ? event.target : event.srcElement; picklistFocusHandler.objSel = objSel; // update data elements objSel.X = getX(objSel)+2; objSel.Y = getY(objSel)-20; objSel.strKeyInBuf = ""; // display the tooltip help (the title attribute by default) showTooltipText(objSel); } function picklistBlurHandler(e) { var event = e ? e : window.event; // to handle both NS and IE events var objSel = event.target ? event.target : event.srcElement; picklistFocusHandler.objSel = null; top.status = (objSel.selectedIndex>-1) ? objSel.options[objSel.selectedIndex].text : ""; hideTooltipText(objSel); return true; } function picklistMouseOverHandler(e) { var event = e ? e : window.event; // to handle both NS and IE events var objSel = event.target ? event.target : event.srcElement; showTooltipText(objSel); return true; } function picklistMouseOutHandler(e) { var event = e ? e : window.event; // to handle both NS and IE events var objSel = event.target ? event.target : event.srcElement; if ( objSel==picklistFocusHandler.objSel || objSel==document.activeElement ) return true; hideTooltipText(); return true; } function picklistKeyDownHandler(e) { var event = e ? e : window.event; // to handle both NS and IE events var objSel = event.target ? event.target : event.srcElement; var divPicklistTooltip = getTooltipDiv(); with ( objSel ) { // this is to correct the search bug when the list is left open after single-click if ( strKeyInBuf=="" && event.keyCode>40 ) { objSel.blur(); objSel.focus(); } switch(event.keyCode) { case(8): // backspace { if ( selectedIndex>=0 && strKeyInBuf==options[selectedIndex].text ) { top.status = strKeyInBuf = ""; } else { top.status = strKeyInBuf = strKeyInBuf.substring(0,strKeyInBuf.length-1); } picklistChange(objSel, findSelectEntry(objSel)); event.keyCode = 0; return false; } case(9): // tab case(13): // enter { event.keyCode = 9; // convert enter to tab return true; } case(27): // escape { top.status = strKeyInBuf = ""; picklistChange(objSel, 0); picklistChange(objSel, options[selectedIndex].text.length ? -1 : 0); showTooltipText(objSel); event.keyCode = 0; return false; } case(32): // space { top.status = strKeyInBuf += ' '; // this must be fired explicitely for spaces return picklistKeyPressHandler(event); } // I don't know if these are universal case(33): // page up case(34): // page down case(35): // end case(36): // home case(37): // left arrow case(38): // up arrow case(39): // right arrow case(40): // down arrow { top.status = hideTooltipText(objSel); return true; } } // end switch } // end with return true; } function picklistKeyPressHandler(e) { var event = e ? e : window.event; // to handle both NS and IE events var objSel = event.target ? event.target : event.srcElement; var inputChar = String.fromCharCode(event.keyCode ? event.keyCode : event.charCode); if ( inputChar=='\n' || inputChar=='\r' ) { top.status = objSel.strKeyInBuf = ( objSel.selectedIndex>-1 ? objSel.options[objSel.selectedIndex].text : "" ); } if ( isvalidchar(inputChar) && event.charCode!=0 ) { objSel.strKeyInBuf += inputChar; // must use setTimeout to override the default SELECT keypress event(s) setTimeout( "findSelectEntry(" + getQualifiedName(objSel) +")", 1 ); } return false; } function setupPicklist(objSel) { if ( !document.all && !document.getElementById ) return false; // browser not supported if ( !objSel || (""+objSel.type).substring(0,6).toLowerCase()!="select" ) return false; // null or not a select //alert('setup : ' + objSel.form); createTooltipDiv(objSel); // create/init data elements objSel.X = getX(objSel)+2; objSel.Y = getY(objSel)-20; objSel.strKeyInBuf = ""; // setup event handlers objSel.onclick = function(){top.status=hideTooltipText(this);} objSel.onfocus = picklistFocusHandler; objSel.onblur = picklistBlurHandler; objSel.onmouseover = picklistMouseOverHandler; objSel.onmouseout = picklistMouseOutHandler; objSel.onkeydown = picklistKeyDownHandler; objSel.onkeypress = picklistKeyPressHandler; objSel.onkeyup = null; return true; } function picklistChange(objSel, newindex) { if( objSel.selectedIndex != newindex ) { objSel.selectedIndex = newindex; if (typeof objSel.onchange == "function") { objSel.onchange(); } } } function setupPickListAll() { var fs = document.forms; for (var i = 0; i < fs.length; i++) { var f = fs[i].elements; for (var j = 0; j < f.length; j++) { if (f[j].type == 'select-one') { if (!f[j].title) { f[j].title = "Please type value in the pick-list below"; } setupPicklist(f[j]); } } } } addOnLoadFunc(setupPickListAll);