//var isIE = (window.ActiveXObject); var completeTable; var completeField; var autocompleteControl; var container; var baseContainer; var isMaxHeightSupported = true; //add onload handler to window addEventHandler("load", init ); String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); } String.prototype.booleanValue = function() { switch(this.toLowerCase()) { case "1": case "true": case "yes": return true; case "0": case "false": case "no": return false; default: return Boolean(this); } } String.prototype.highlightSearchString = function(cell, searchString, highlightClass) { if (highlightClass) { var re = new RegExp("^" + searchString, "i"); var matchedString = this.match(re); if (matchedString) { var matchSpan = createElement("span", null, highlightClass); matchSpan.appendChild(document.createTextNode( matchedString )); cell.appendChild(matchSpan); return RegExp.rightContext; } } return this; } Function.prototype.bind = function(object) { var method = this; arguments.slice = Array.prototype.slice; var oldArguments = arguments.slice(1); return function() { return method.apply(object, oldArguments.concat(Array.prototype.slice.apply(arguments))); }; } function createElement(type, id, className) { var elem = document.createElement(type); if (id) elem.id = id; if (className) elem.className = className; return elem; } function findPos(elt) { var curleft = 0; var curtop = 0; if (elt.offsetParent) { do { curleft += elt.offsetLeft; curtop += elt.offsetTop; } while (elt = elt.offsetParent); } return { left: curleft ,top: curtop }; }; function init() { autocompleteControl = document.getElementById("AutocompleteControl"); completeField = document.getElementById("complete-field"); var label = document.getElementById("AutocompleteTextFieldLabel"); var searchButton = document.getElementById("submit_btn"); var searchBtnDiv = document.getElementById("AutocompleteSubmit"); setCssPath(); setLabelText(label); setEltClass( label, labelClass); setEltClass( completeField, textFieldClass ); setButtonText( searchButton, searchButtonText); setEltClass( searchBtnDiv, searchButtonClass ); //add the key handler addEventHandler.call( completeField, "keyup", autoComplete ); //completeField.onkeyup = autoComplete; //add handler for Enter Key addEventHandler("keydown", handleEnterKey ); isMaxHeightSupported = testForMaxHeightSupport(); //create the containing DIV //container = document.createElement("div"); container = createElement("div", "container"); //container = document.getElementById("container"); with (container) { if (scrollbarColorClass) className = scrollbarColorClass; style.left = findPos(completeField).left - findPos(autocompleteControl).left + "px"; style.top = autocompleteControl.clientHeight + "px"; } completeTable = createElement("table", "completeTable"); container.appendChild(completeTable); baseContainer = (addDropShadow(container) || container); autocompleteControl.appendChild(baseContainer); } function testForMaxHeightSupport() { //var outerDiv = document.createElement("div"); //outerDiv.className = "maxHeightTest"; var outerDiv = createElement("div", null, "maxHeightTest"); //var innerDiv = document.createElement("div"); var innerDiv = createElement("div"); innerDiv.style.height = "200px"; outerDiv.appendChild(innerDiv); autocompleteControl.appendChild(outerDiv); var isMaxHeightSupported = (innerDiv.clientHeight > outerDiv.clientHeight); autocompleteControl.removeChild(outerDiv); return isMaxHeightSupported; } function setButtonText( button, buttonText) { if ( buttonText && button ) { button.value = buttonText; } } function setEltClass( elt, className) { if ( className && elt ) { elt.className = className; } } function setCssPath() { if (cssPath && document.styleSheets) { var styleSheet = document.styleSheets["AutocompleteCSS"]; if ( styleSheet ) { if ( styleSheet.setAttribute ) { styleSheet.setAttribute('HREF', cssPath); } else { styleSheet.href = cssPath; } } } } function setLabelText(label) { if ( labelText && label && label.firstChild.nodeName == "#text") { label.firstChild.nodeValue = labelText; } } function initRequest(url) { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } } function autoComplete(e) { if (!e) e = window.event; if (handleSpecialKeys(e)) return; var searchString = completeField.value.trim(); if (!searchString) { clearTable(); } else { var url = "autocomplete?action=complete&searchString=" + searchString; var req = initRequest(url); req.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200) //OK { parseMessages(this.responseText, searchString); } else if (this.status == 204) //No Content { clearTable(); } } }.bind( req, searchString ); req.open("GET", url, true); req.send(null); } } function parseMessages(responseText, searchString) { clearTable(); if (!responseText.length) { return; } //display error message else if ( /^".+"&/.test(responseText) ) { alert( responseText.replace(/^"|"$/, "") ); } else { var jsonObj; try { jsonObj = json_parse(responseText); } catch(e) { var prop; var msg = "An error occured while parsing the JSON-formatted responseText:\n"; //caught a SyntaxError exception for (prop in e) { msg += prop + ": " + e[prop] + "\n"; } alert(msg); return; } for (var loop = 0; loop < jsonObj.length; loop++) { appendFund.call(jsonObj[loop], searchString); } //put in a scrollbar if applicable setListHeight(jsonObj.length); setListWidth(); baseContainer.style.visibility = "visible"; } } function addDropShadow(elt) { var shadows = 6; var shadow = new Array(shadows); if (!dropShadow || !dropShadow.booleanValue()) return; var shadowContainer = createElement("div", "shadow-container"); shadowContainer.style.left = parseInt(elt.style.left) + shadows - 1 + "px"; shadowContainer.style.top = parseInt(elt.style.top) + shadows - 1 + "px"; elt.className += " container"; shadow[0] = createElement("div", null, "shadow1"); shadowContainer.appendChild( shadow[0] ); for (var i=1; i ' + containerHeight + '?"' + containerHeight + 'px"' + ':document.getElementById("completeTable").clientHeight' , 'JavaScript'); } else { container.style.maxHeight = containerHeight + "px"; } container.className += " scrollbar"; } setListHeight = function() {}; } function setListWidth() { if ( /\bscrollbar\b/.test(container.className) ) { container.style.width = (completeTable.clientHeight > container.clientHeight ? completeTable.clientWidth + 16 : completeTable.clientWidth) + "px"; } } function addEventHandler( eventName, eventHandler ) { var CAPTURING_PHASE = true, BUBBLING_PHASE = false; var obj = this; if( obj.addEventListener ) { obj.addEventListener( eventName, eventHandler, BUBBLING_PHASE ); } else if( obj.attachEvent ) { obj.attachEvent( 'on' + eventName, eventHandler ); } } function clearTable() { if (completeTable) { baseContainer.style.visibility = "hidden"; for (var loop = completeTable.childNodes.length -1; loop >= 0 ; loop--) { completeTable.removeChild(completeTable.childNodes[loop]); RowManager.resetRowCount(); } } } function handleMouseEvent(e) { var row = this; if (!e) e = event; if (/^mouse(over)|(up)|(down)|(out)$/.test(e.type)) RowManager.highlightRow(row, "popupRow", "popupRow " + e.type); if (/^mouseout$/.test(e.type)) RowManager.setHighlightedRow(null); //row.className = "popupRow " + e.type; } function appendFund( searchString ) { var row, symbolCell, nameCell; var fund = this; if (completeTable.insertRow) { row = completeTable.insertRow(completeTable.rows.length); symbolCell = row.insertCell(0); nameCell = row.insertCell(1); } else { //row = document.createElement("tr"); //symbolCell = document.createElement("td"); //nameCell = document.createElement("td"); row = createElement("tr"); symbolCell = createElement("td"); nameCell = createElement("td"); row.appendChild(symbolCell); row.appendChild(nameCell); completeTable.appendChild(row); } row.className = "popupRow"; row.onmouseover = handleMouseEvent; row.onmouseout = handleMouseEvent; row.onmousedown = handleMouseEvent; row.onmouseup = handleMouseEvent; row.onclick = function() { document.location.href = "autocomplete?action=lookup&symbol=" + fund.symbol; }; RowManager.addRow(row); var text = fund.symbol.highlightSearchString(symbolCell, searchString, highlightClass); symbolCell.appendChild(document.createTextNode(text)); symbolCell.className = "popupItem"; symbolCell.id = "symbolCell"; text = fund.name.highlightSearchString(nameCell, searchString, highlightClass); nameCell.appendChild(document.createTextNode(text)); nameCell.className = "popupItem"; } function handleEnterKey(e) { if (!e) e = event; //switch (e.keyCode) // { // Tab // case 9: // clearTable(); // break; // Return/Enter if (e.keyCode == 13) { var row = RowManager.getHighlightedRow(); if (row) { if (row.fireEvent) //IE { row.fireEvent("onclick"); } else if (row.dispatchEvent) //Mozilla { var BUBBLES = true, CANCELABLE = true; var evt = document.createEvent("HTMLEvents"); evt.initEvent("click", BUBBLES, CANCELABLE); row.dispatchEvent(evt); } //e.stopPropagation(); e.returnValue = false; e.cancelBubble = true; } } } function handleSpecialKeys(e) { switch (e.keyCode) { // Escape case 27: clearTable(); break; // Up arrow case 38: RowManager.highlightPreviousRow("popupRow", "popupRow mouseover"); RowManager.scrollList(); break; // left & right arrow keys. Absorb them. case 37: case 39: break; // Down arrow case 40: RowManager.highlightNextRow("popupRow", "popupRow mouseover"); RowManager.scrollList(); break; default: return false; } //sets the return value of the event //(if false, the action is canceled). e.returnValue = false; //Sets whether or not the current event //stops bubbling through the document hierarchy. e.cancelBubble = true; return true; } var RowManager = (function() { var counter = 0; var firstRow, lastRow, highlightedRow; //private methods function getPreviousRow() { return highlightedRow && highlightedRow.previousSibling ? highlightedRow.previousSibling : lastRow; } function getNextRow() { return highlightedRow && highlightedRow.nextSibling ? highlightedRow.nextSibling : firstRow; } function getHighlightedRow() { return highlightedRow; } function setHighlightedRow(row) { highlightedRow = row; } function resetRowCount() { counter = firstRow = lastRow = highlightedRow = 0; }; function addRow(row) { if (!counter++) firstRow = row; lastRow = row; }; function highlightPreviousRow(nonHighlightedStyle, highlightedStyle) { //var previousRow = getPreviousRow(); if (highlightedRow !== firstRow) { highlightRow(getPreviousRow(), nonHighlightedStyle, highlightedStyle); } } function highlightNextRow(nonHighlightedStyle, highlightedStyle) { if (highlightedRow !== lastRow) { highlightRow(getNextRow(), nonHighlightedStyle, highlightedStyle); } } function highlightRow(row, nonHighlightedStyle, highlightedStyle) { //turn off current row if (highlightedRow) highlightedRow.className = nonHighlightedStyle; row.className = highlightedStyle; setHighlightedRow(row); } function scrollList() { var highlightedRow = getHighlightedRow(); if (highlightedRow) { if ( highlightedRow.offsetTop < container.scrollTop ) { //scroll to the highlighted row container.scrollTop = highlightedRow.offsetTop } else { var rowOffsetBottom = highlightedRow.offsetTop + highlightedRow.clientHeight; if ( rowOffsetBottom > container.scrollTop + container.clientHeight ) { container.scrollTop = rowOffsetBottom - container.clientHeight; } } } } return ({ "resetRowCount": resetRowCount ,"addRow": addRow ,"highlightPreviousRow": highlightPreviousRow ,"highlightNextRow": highlightNextRow ,"highlightRow": highlightRow ,"scrollList": scrollList ,"getHighlightedRow": getHighlightedRow ,"setHighlightedRow": setHighlightedRow }); })();