07/01/2009

JavaScript: Create Open Below Pop Ups (Ex// auto complete text box)

This is a simple method to open popups below text inputs (or any Html Element at that) using JavaScript. Please let me know if things are missing ... The intent of this script is to open a small pop up below a text box for use in a custom auto complete. As this is an ASP.Net control, and ASP.Net creates element ID's based on containers we need something to base our element id's on so we can do stuff with them. In this example I use a text box as the naming pivot upon which all other client ID's are based on.

// the previous document click event handler we've stored when we change the event.
// This implies when the pop up is open you'll need to cancel all click events therein so the popup doesn't close
var orignDocClick = null;
// the active pop up id. In another method I haven't provided here we determine if there is an active pop up and close it before we open a second.
var activePopId = null;

// the id of this element is provided VIA ASP.Net control but in this example is hard coded
// we want to show a Pop Under directly below this text box.
var inputTypeText = document.getElementById("ourTextBox");

// create the pop under by calling show pop.
var myNewPopUnder = ShowPop(inputTypeText.id + "_PopUp", inputTypeText);

myNewPopUnder.innerHTML = "Hello World";
// OR
myNewPopUnder.appendChild(document.createElement("br"));
// OR ....


function ShowPop(strPopUpId, objTextBox) {
// get the existing div control and remove it (it is merely a placeholder with ID's aligned as per ASP.Net Crap)
var popEl = document.getElementById(strPopUpId);
var parent = popEl.parentNode;
parent.removeChild(popEl);

// create a new pop up control and append it to the parent of the old auto complete pop up.
var newPop = document.createElement("div");
newPop.id = strPopUpId;
newPop.className = "AutoCompletePop";
parent.appendChild(newPop);

// determine the left and top positions for the pop under
var curleft = 0;
var curtop = parseFloat(objTextBox.offsetHeight);
var top = objTextBox;
do {
curleft += top.offsetLeft;
curtop += top.offsetTop;
} while (top = top.offsetParent);
newPop.style.top = curtop + "px";
newPop.style.left = curleft + "px";
newPop.style.display = "block";

// trap some document events to ensure we can close auto complete
orignDocClick = document.body.onclick;
document.body.onclick = DocHidePop;
activePopId = strPopUpId;

return newPop;
};

function DocHidePop() {
if (activePopId != null) {
HidePop(document.getElementById(activePopId));
}
};

function HidePop(objPopContainer) {
objPopContainer.style.display = "none";
document.body.onclick = orignDocClick;
activePopId = null;
};