popup object
[This documentation is preliminary and is subject to change.]
A special type of overlapped window typically used for dialog boxes, message boxes, and other temporary windows that appear separate from an application's main window.
This object is not supported for Metro style apps using JavaScript.
Standards information
There are no standards that apply here.
Members
The popup object does not define any members.
Remarks
This object is available in script as of Microsoft Internet Explorer 5.5.
Windows Internet Explorer 7. This object inherits the writingMode of its parent containing block.
Examples
The following example demonstrates the use of the popup object. The code creates a pop-up window and displays it.
<script language="JScript"> var oPopup = window.createPopup(); var oPopupBody = oPopup.document.body; oPopupBody.innerHTML = "Display some <B>HTML</B> here."; oPopup.show(100, 100, 200, 50, document.body); </script>
The following example demonstrates some different uses of the popup object.
Code example: http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/popup/default.htm
See also
- Reference
- createPopup
- writingMode
- Conceptual
- Using the Popup Object
Build date: 3/8/2012
Here is a function that will enable you to display popups with optional menu bar with text, expand and close buttons and ability to drag & drop, plus determine how they should close (fragile, activeElement or solid)
- overlayPop(html_to_display, flags) : Display popup, flags attributes are optional
"position" = "center" "at pointer"(mouse event/on top of element) "next to"(element) "below"(element)
"ref object" = position popup according to event or html element
"id" = string to identify <div> used ; without id "popupLayer" is used and created/replaced
"width" = string to specify width of popup
"x" = "345" // Fixed px position
"y" = "500" // Fixed px position
"keep as" = "fragile" "activeElement" "solid"/"" // Specify when to close popup
// Fragile is removed at "complete" status of remote scripting and before another created popup that is not fragile also
// activeElement is removed when active element goes out of popup
// Solid is removed only when ordered
"styles" = string with styles // this overrule some other styles
"container" = html element // specify container as boundaries for popup
"closebutton" = html; // display close button; html to specify own style or empty for using defaults; set to false to not use
"expandbutton" = html; // display expand button;
"menu" = html; // display html in panel section with close+expand buttons
"panelStyles" = string with styles // this overrule some other styles in panel
"draggable" = boolean // defaults to true; set whether pop can be dragged from panel
flags ex.: {"ref object" : evt, "width" : "100px"} -> place popup at evt(from event with mouse position)
flags ex.: {"x" : "240", "y" : "140", "width" : "30%", "id" : "popID", "keep as" : "activeElement", "expandbutton" : "", "menu" : "This is menu line", "draggable" : false} -> popup with close button but not draggable, will auto-close when not active
flags ex.: {"width" : "60%", "id" : "popID", "closebutton" : false} -> popup without any buttons or menu line
flags ex.: {"width" : "10%", "id" : "popID", "expandbutton" : "", "menu" : "This is menu line"} -> popup with expand(and then also close) button and menu
To make option "keep as" complete, you should call function that close all "fragile" popups at end of each remote scripting actions and call to close all "activeElement" popups at end of each onkeydown event to check if popup has lost active element
To make this work here are first some very generel functions:
/* *******************************************************************************************************************************************************************
- getElementPos(e) : returns x, y, width, height of html element "e"
- elementInContainer(obj, container, inclusive) : return boolean true if object is in container !
- setCustomCSS(CSS, ID) : Set CSS; ID is optional
ex. setCustomCSS(' .dotted { border-style: dotted; border-width: 1px; ', "CUSTOM_CSS") -> will remove earlier styles with ID "CUSTOM_CSS" and insert new one
- dragDiv(id, e) : Make element draggable
******************************************************************************************************************************************************************** */
// Get XY position of html element
function getElementPos(e) {
var pe = e, x=e.offsetLeft, y=e.offsetTop;
while(pe = pe.offsetParent) { x += pe.offsetLeft; y += pe.offsetTop; }
return {"x" : x, "y" : y, "width" : e.offsetWidth, "height" : e.offsetHeight};
}
// return boolean true if object is in container ! the element method "contains" throw exception and do not always work but this func does
function elementInContainer(obj, container, inclusive) {
if (inclusive && obj == container) return true;
var sch = container.firstChild;
while (sch) {
if (obj == sch || elementInContainer(obj, sch)) return true;
sch = sch.nextSibling;
}
return false;
}
// Set generel style to elements
function setCustomCSS(CSS, ID) {
var head = document.getElementsByTagName("head")[0];
var ss = (ID ? document.getElementById(ID) : undefined);
if (ss) { head.removeChild(ss); }
if (!CSS) { return; }
ss = document.createElement("style");
ss.setAttribute("type", "text/css");
// ss.setAttribute("media", "screen");
if (ID) ss.setAttribute("id", ID);
if (ss.styleSheet) { ss.styleSheet.cssText = CSS; }
else { ss.appendChild(document.createTextNode(CSS)); }
head.appendChild(ss);
}
//mouse down on dragged DIV element
var dragging, onmousemoveOld, onmouseupOld; // Global var of storing element dragged
function dragDiv(id, e) {
dragging = document.getElementById(id);
if (e.preventDefault) e.preventDefault();
e.cancelBubble = true;
onmousemoveOld = document.onmousemove;
onmouseupOld = document.onmouseup;
document.onmousemove=dragDiv_;
document.onmouseup=dragDiv_stop;
dragging.dragX = e.clientX;
dragging.dragY = e.clientY;
return false;
}
//move the DIV
function dragDiv_(e) {
if (!e) e = event;
dragging.style.left = (dragging.offsetLeft + e.clientX - dragging.dragX)+"px";
dragging.style.top = (dragging.offsetTop + e.clientY - dragging.dragY)+"px";
dragging.dragX = e.clientX;
dragging.dragY = e.clientY;
dragging.style.cursor = "move";
return false;
}
//restore event-handlers
function dragDiv_stop() {
document.onmousemove=onmousemoveOld;
document.onmouseup=onmouseupOld;
dragging.style.cursor = "auto";
}
// AND HERE IS THE MAIN FUNCTION to create popups:
// Global variables
var
popupLayers = [], // Array with popups data in order to redisplay popup incase of window resizing..
popIndexStart = 900;
document.body.onmousedown = activeElementHandler; // use onmousedown for both left and rightclick. click + contextmenu are used by other functions
// Setting generel styles
setCustomCSS(
' .PopExpandButton { ' +
' background-color: grey; ' +
' cursor: auto; ' +
' color: white; ' +
' border-right: 1px solid white; ' +
' m: expression(this.onmouseover = new Function("this.className = \'PopExpandButtonF\';")); ' +
' } ' +
' .PopExpandButtonF { ' +
' background-color: black; ' +
' cursor: hand; ' +
' color: white; ' +
' border-right: 1px solid white; ' +
' m: expression(this.onmouseout = new Function("this.className = \'PopExpandButton\';")); ' +
' } ' +
' .PopCloseButton { ' +
' background-color: #ee2222; ' +
' cursor: auto; ' +
' color: white; ' +
' m: expression(this.onmouseover = new Function("this.className = \'PopCloseButtonF\';")); ' +
' } ' +
' .PopCloseButtonF { ' +
' background-color: #7c0000; ' +
' cursor: hand; ' +
' color: white; ' +
' m: expression(this.onmouseout = new Function("this.className = \'PopCloseButton\';")); ' +
' } ' +
' .PopPanel { ' +
' width: 108%; ' +
' padding: 0px; ' +
' margin: -5px -5px 4px -5px; ' +
' border-bottom: 1px solid black; ' +
' background-color: #d6ecef; ' +
' line-height: 14px; ' +
' } ' +
' .PopPanelMenu { ' +
' text-align: left; ' +
' padding: 0px; ' +
' font-size: 10pt; ' +
' } ' +
' .PopPanelButtons { ' +
' text-align: right; ' +
' padding: 0px; ' +
' font-size: 12pt; ' +
' } ' +
'', 'PopOverlayStyles');
if (!document.body) { alert("HTML error: document is without BODY element!"); } // This error makes appending popups impossible
// Display popup, flags attributes are optional
function overlayPop(html_to_display, flags) {
if (!flags) { flags = {}; } // Center popup
// New popup always first in row; since others have been removed
if (!flags["id"]) { flags["id"] = "popupLayer"; } // default ID
if (!flags["keep as"] || flags["keep as"] != "fragile") { removeTopPop(undefined, "fragile"); } // Only fragile popup can stay on top of fragile
var aPopupObj = document.getElementById(flags["id"]);
if (!aPopupObj) {
aPopupObj = document.createElement("div");
aPopupObj.id = flags["id"];
aPopupObj.style.textAlign = "left";
aPopupObj.style.border = "solid 1px gray";
aPopupObj.style.backgroundColor = "white";
aPopupObj.style.padding = "4px";
if (flags["styles"]) aPopupObj.style.cssText = flags["styles"];
aPopupObj.style.position = "absolute";
aPopupObj.style.zIndex = (flags["id"] == "popupLayer" ? removePops() : removePops(inc_pop_zIndex()));
aPopupObj.innerHTML = " ";
document.body.appendChild(aPopupObj);
window.popupLayers.unshift({"divObj" : aPopupObj}); // Always adds new div data to beginning of array
}
else { removePops(aPopupObj.style.zIndex + 1); }
if (flags["ref object"]) {
// if ref object is mouse pointer in event
var x = flags["ref object"].x || flags["ref object"].clientX;
var y = flags["ref object"].y || flags["ref object"].clientY;
if (x && y) { window.popupLayers[0]["xy"] = {"x" : x, "y" : y}; }
else {
window.popupLayers[0]["ref object"] = flags["ref object"];
if (!flags["position"] || flags["position"] == "center") { window.popupLayers[0]["position"] = "next to"; }
else { window.popupLayers[0]["position"] = flags["position"]; }
}
}
else if (flags["x"] && flags["y"]) { window.popupLayers[0]["xy"] = {"x" : flags["x"], "y" : flags["y"]}; }
else { window.popupLayers[0]["position"] = "center"; }
window.popupLayers[0]["width"] = flags["width"];
window.popupLayers[0]["keep as"] = (flags["keep as"] ? flags["keep as"] : "solid");
if (flags["container"]) window.popupLayers[0]["container"] = flags["container"];
var buttons =
// Expand button
(typeof flags["expandbutton"] == "undefined" ? '' :
'<SPAN CLASS="PopExpandButton" TITLE="Maximize" onclick="return expandPop(\'' + aPopupObj.id + '\');">' + (typeof flags["expandbutton"] == "string" &&
flags["expandbutton"].length > 0 ? flags["expandbutton"] : " □ ") + '</SPAN>') +
// Close button
(typeof flags["expandbutton"] == "undefined" && typeof flags["closebutton"] == "boolean" && flags["closebutton"] == false ? '' :
'<SPAN CLASS="PopCloseButton" TITLE="Close" onclick="return removePops(undefined, \'' + aPopupObj.id + '\', true);">' + (flags["closebutton"] ? flags["closebutton"] : " × ") +
'</SPAN>');
aPopupObj.innerHTML = (flags["menu"] || buttons ? '<TABLE CLASS="PopPanel" STYLE="' +
(flags["panelStyles"] ? flags["panelStyles"] : '') + '"><TR' + (typeof flags["draggable"] == "undefined" || flags["draggable"] ?
' ONMOUSEDOWN="dragDiv(\'' + aPopupObj.id + '\', event);"' : '') + '>' + (flags["menu"] ? '<TD CLASS="PopPanelMenu">' +
flags["menu"] + '</TD>' : '') + (buttons ? '<TD CLASS="PopPanelButtons">' + buttons + '</TD>' : '') + '</TR></TABLE>' : '') +
html_to_display;
if (flags["menu"] || buttons) aPopupObj.style.padding = "4px";
aPopupObj.style.display = "block";
var inputCol = aPopupObj.getElementsByTagName("INPUT"); if (inputCol && inputCol[0]) inputCol[0].setActive(); // Look for input element and activate first element
adjustPops(true);
}
// AND LASTLY SOME MORE SUPPORT FUNCTIONS in order to close popups etc.
/* *******************************************************************************************************************************************************************
- removeTopPop(zIndex_limit, only_if) : Remove one popup; returns true on success
zIndex_limit is number in zIndex that specify which div element to put on top
only_if can be:
fragile - 3 priority - remove all fragile
activeElement - 2 priority remove this and any fragile
solid - 1 priority remove any
ex. removeTopPop(undefined, "fragile") -> will remove all fragile popups("pops")
ex. removeTopPop() -> will remove last popup
- removePops(zIndex_limit, layer_id, inclusive) : remove all popups as specified
ex. removePops(undefined, "directories", true) -> will remove all popups from popup with id "directories" inclusive it
- inc_pop_zIndex() : return incremented zIndex from last popup
* onmousedown // is used to check active element in relation to popups with "activeElement" set
- pops_ondeactivate_handler() : will close popup that has lost active element
- topPop_has_activeElement() : check if top popup currently has active element
- popAddContent(html_to_add, layer_id) : add html content to popup
******************************************************************************************************************************************************************** */
// Adjusting popup sizes after create or resize
function adjustPops(onlyTop) {
var window_width = window.innerWidth || document.body.clientWidth;
var window_height = window.innerHeight || document.body.clientHeight;
// Set popup bondaries
for (var idx in window.popupLayers) {
var aPopupObj = window.popupLayers[idx]["divObj"];
// element can be gone ...
if (aPopupObj.style.display == "block" && aPopupObj.offsetHeight > 0) {
aPopupObj.style.height = "auto"; // Default
aPopupObj.style.overflowY = "visible"; // Default
aPopupObj.style.width = window.popupLayers[idx]["width"]; // Width specified by user
// Set container vars
var con = (window.popupLayers[idx]["container"] ? getElementPos(window.popupLayers[idx]["container"]) // Get XY position of html element
: {"x" : 0, "y" : 0, "width" : window_width, "height" : window_height});
if (aPopupObj.offsetHeight > con["height"]) {
aPopupObj.style.overflowY = "auto";
aPopupObj.style.height = con["height"];
}
// If popup is expanded
if (window.popupLayers[idx]["expand"]) {
aPopupObj.style.left = con["x"] + "px";
aPopupObj.style.top = con["y"] + "px";
aPopupObj.style.width = con["width"] + "px";
aPopupObj.style.height = con["height"] + "px";
}
// If popup is supposed to be centered...
else if (window.popupLayers[idx]["position"] == "center") {
aPopupObj.style.left = (50 - ((aPopupObj.offsetWidth * 100 / window_width) / 2)) + "%";
aPopupObj.style.top = (50 - ((aPopupObj.offsetHeight * 100 / window_height) / 2)) + "%";
}
// If popup is supposed to be relative positioned ...
else {
if (window.popupLayers[idx]["xy"]) {
aPopupObj.style.left = window.popupLayers[idx]["xy"]["x"] + "px";
aPopupObj.style.top = window.popupLayers[idx]["xy"]["y"] + "px";
}
else if (window.popupLayers[idx]["ref object"]) {
var elmtPos = getElementPos(window.popupLayers[idx]["ref object"]);
aPopupObj.style.left = (elmtPos["x"] + (window.popupLayers[idx]["position"] == "next to" ? elmtPos["width"] : 0)) + "px";
aPopupObj.style.top = (elmtPos["y"] + (window.popupLayers[idx]["position"] == "below" ? elmtPos["height"] : 0)) + "px";
}
}
// If popup exceeds bondaries...
// Height
if (aPopupObj.style.top + aPopupObj.style.height >= (con["y"] + con["height"])) { aPopupObj.style.top = (con["height"] - aPopupObj.style.height) + "px"; }
if (aPopupObj.style.top < con["y"]) aPopupObj.style.top = con["y"] + "px";
// Width
if (aPopupObj.style.left + aPopupObj.style.width >= (con["x"] + con["width"])) { aPopupObj.style.left = (con["width"] - aPopupObj.style.width) + "px"; }
if (aPopupObj.style.left < con["x"]) aPopupObj.style.left = con["x"] + "px";
}
if (onlyTop) break; // Only position top popup
}
}
// Remove one popup
function removeTopPop(zIndex_limit, only_if) {
// only_if specify to remove popup after level of keep as: only_if "solid" removes any; "fragile" only removes fragile
if (!window.popupLayers[0] || zIndex_limit && window.popupLayers[0]["divObj"].style.zIndex < zIndex_limit || only_if &&
(only_if != "solid" &&
(window.popupLayers[0]["keep as"] == "solid" || window.popupLayers[0]["keep as"] == "activeElement" && only_if != "activeElement"))
) return false;
var repeatThisProc = window.popupLayers[0]["keep as"] == "fragile" && only_if != "activeElement"; // Remove all fragile except activeElement
document.body.removeChild(window.popupLayers[0]["divObj"]);
window.popupLayers.shift(); // Always close divs as opened, first one is top
if (repeatThisProc) return removeTopPop(zIndex_limit, only_if);
return true;
}
// Remove popup from zIndex value or id name; and it can not be redisplayed
function removePops(zIndex_limit, layer_id, inclusive) {
if (layer_id) {
var popObj = document.getElementById(layer_id);
if (!popObj) return false;
zIndex_limit = popObj.style.zIndex;
}
if (!zIndex_limit || zIndex_limit < popIndexStart) { zIndex_limit = popIndexStart; }
else if (!inclusive) { zIndex_limit += 1; } // if inclusive is false it will remove after specified id or zIndex_limit
while (removeTopPop(zIndex_limit)) {}
return zIndex_limit;
}
// Returns the highest zIndex + 1
function inc_pop_zIndex() { return (window.popupLayers[0] ? window.popupLayers[0]["divObj"].style.zIndex + 1 : popIndexStart); }
// Check if active element has changed
function activeElementHandler() { setTimeout("pops_ondeactivate_handler()",0); return true; } // Run check after other functions ...
// activate element has changed and new element is checked if out of popup: activeElement
var lastActiveElementRef;
function pops_ondeactivate_handler() {
if (lastActiveElementRef == document.activeElement) return;
lastActiveElementRef = document.activeElement;
do {
// active element has changed ..
if (!window.popupLayers[0] || window.popupLayers[0]["keep as"] == "solid" || elementInContainer(lastActiveElementRef, window.popupLayers[0]["divObj"], true)) return;
} while (removeTopPop(undefined, "activeElement"));
}
// check if top popup currently has active element
function topPop_has_activeElement() {
if (!window.popupLayers[0] || !elementInContainer(document.activeElement, window.popupLayers[0]["divObj"]), true) return false;
return true;
}
// Add html content to pop
function popAddContent(html_to_add, layer_id) {
var popObj = (layer_id ? document.getElementById(layer_id) : (window.popupLayers[0] ? window.popupLayers[0]["divObj"] : undefined));
if (!popObj) return false;
popObj.innerHTML += html_to_add;
return true;
}
// Return current index number to pop
function getPopIndex(id) { for (var idx in window.popupLayers) { if (id == window.popupLayers[idx]["divObj"].id) return idx; } return undefined; }
// expand pop
function expandPop(id) {
var idx = getPopIndex(id); if (!idx) return false;
window.popupLayers[idx]["expand"] = !Boolean(window.popupLayers[idx]["expand"]);
adjustPops();
return false;
}
- 2/14/2011
- Hobby Developer
When a popup calls up another popup--
1. isActive is cross-inherited (transferred) and will-not fire onactivate in the new popup ... (even though popup does not receive focus; and even though popup does not inherit isActive from its parent).
2. It momentarily throws itself to the new screen position, before displaying the new popup content.
When a popup is invoked, it also--
3. clears the clipboard, so that the browser cannot undo/redo;
4. loses cursor-visibility, albeit its position is still there;
5. defeats the mouse wheel, so that it cannot roll about the page
6.
on-escape hides the parent-cursor (or sets its 'thickness' to unshown; cf other thicknesses: thin, thick)
7. N.B. Use parent.method(), to access windows-dependent methods from a popup: e.g. with(parent) clearTimeout(timerN).
8. [2008-11-23] Buttons have gone intermittent, now-usually closing the popup onclick (without involving a timer).
9. [2009-12-11] Buttons show 'selected' (dotted line even though focus is not possible).
10. [2010-09-05] Drag-drop to/from a popup invokes window-history-problems/-hangs/etc. (e.g. Ctrl-Z Undo will instead Back-document).
- 9/30/2008
- Mr. Raymond Kenneth Petry
- 9/6/2010
- Mr. Raymond Kenneth Petry
In IE6, the pop-up will not be displayed off screen in any circumstances. Instead the pop-up will reposition itself to stay on screen.
In IE8, the pop-up can be positioned off screen. It will not reposition itself to stay on screen.
This behaviour occurs if the setting, "allow script-initiated windows without size or position constraints", is set to "enabled" in the current security zone. If the setting is "disabled", then both browsers contrain the pop-up within the browser window.
The setting is "disabled" by default in the internet zone, and "enabled" by default in the local intranet zone.
- 5/17/2010
- whernside