12 out of 30 rated this helpful - Rate this topic

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

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Alternative popup with <DIV> element
Popups with <DIV> element uses the style position: absolute. And even spammed they do not prevent user from closing window, so they are not a security risk.

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 = "&nbsp;";
  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"] : "&nbsp;&#9633;&nbsp;") + '</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"] : "&nbsp;&times;&nbsp;") +
   '</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;
}

anomalies - isActive, clipboard, parent.method,...

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).

Positioning quirks
There are some positioning quirks of the popup that differ between IE6 and IE8. 

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.