Click here to Skip to main content
15,891,423 members
Articles / Web Development / ASP.NET

ASP.Net User Controls as Static or Movable PopUps

Rate me:
Please Sign up or sign in to vote.
4.63/5 (21 votes)
2 Feb 2007CPOL2 min read 110.6K   2.8K   103  
Use form controls as static informational popups or movable control windows.
//*****************************************************************************
//*
//*		DISPLAY_UTILS.JS
//*
//*		Javascript functions for PopUp user controls
//*
//*		Requires: utility.js
//*
//*		(C)2004-2007 CarboniSoftware, LLC
//*
//*		If you understand this code, feel free to use, modify, or disect at will
//*		as there are no radically new or complicated ideas here.  If you don't
//*		understand this code, please leave as is with author reference.
//*
//*****************************************************************************


var PopId="";  //global popup identifier - change this to array if more than one popup is visible
var SelId="";  //kludge fix for IE - if popup is over a select element, need to clip this element
var selCtrlIDs=new Array();  //more IE kludge - controls to hide if popup covers them
var clipWidth=0;
var clipHeight=0;
var xClip=0;
var yClip=0;
var Loaded=false;
var PopOn=false;
var PopX;
var PopY;
var PopXStart;
var PopYStart;
var PopXOffset;
var PopYOffset;

/////////////////////////////////////////////////////////////////////
// This allows the popup(s) to be hidden by clicking off the popup
// on the document.  Comment this out to make popup(s) strictly
// modal.  See also information about Mozilla bug in hideAllPopups.
document.onclick = hideAllPopups;
/////////////////////////////////////////////////////////////////////

var timer;
function timeKill(){
	timer = setTimeout('hideAllPopups()',250);
}
function resetTimer(){
	if (timer) clearTimeout(timer);
}

function showPop(pID, selID, eventObj, bTimer, offX, offY, bVAlign, ctrlIDs, bAnimate) 
{
	/////////////////////////////////////////////////////////////////
	// First make sure no other popup is active.  If multi-popups are
	// allowed by changing PopId to array, this can be removed.
	if (PopId != "")
	{
		hideAllPopups();
	}

	//////////////////////////////////////	
	// These are global vars
	PopId = pID;
	SelId = selID;

	if (ctrlIDs != null)
		registerIEWindowCtrls(ctrlIDs);
	//////////////////////////////////////

	var obj = getObject(PopId);
	if (!obj)
	{
		alert('No popup found: ' + pID);
		return;
	}

	var styobj = getStyleObject(PopId);
	if (!styobj)
	{
		alert('No popup style:' + pID);
		return;
	}	

	if (nav)
	{
		document.captureEvents(Event.MOUSEMOVE);
		document.captureEvents(Event.MOUSEOVER);
	}

	/////////////////////////////////////////////////////////////////
	// Popups can be auto closed after a specific time.  Timer
	// count starts when mouse leaves the popup area.
	if (bTimer)
	{
		obj.onmouseout = timeKill;
 		obj.onmouseover = resetTimer;
	}

	var viewWidth  = (ie)?document.body.clientWidth:window.innerWidth;
	var viewHeight = (ie)?document.body.clientHeight:window.innerHeight;

	/////////////////////////////////////////////////////////////////
	// Popup positioning - the popup is initially positioned as 
	// close to the point of the event as possible.  The caller
	// can offset this position by passing in values.  If no event
	// object is defined, the position defaults to screen center.
	var x=0;
	var y=0;
	if ((eventObj != null))
	{
		x = (nav)?eventObj.pageX:event.clientX+document.body.scrollLeft;
		y = (nav)?eventObj.pageY:event.clientY+document.body.scrollTop;
		x += offX;
		y += offY;
	}
	else
	{
		x = viewWidth/2;
		x += (ie)?document.body.scrollLeft:window.pageXOffset;
		x -= obj.offsetWidth/2;
		if (x<0) x=0;
		y = viewHeight/2;
		y += (ie)?document.body.scrollTop:window.pageYOffset;
		y -= obj.offsetHeight/2;
		if (y<0) y=0;
	}

	if(mac&&ie){//mac ie bug fix
		winWidth = document.body.clientWidth;
		if(winWidth > 612) x -= (winWidth - 612)/2;
	}

	/////////////////////////////////////////////////////////////////
	// If the x-position will cause the popup to disappear off the
	// right side of the window, try to move the popup to the left
	// so that the maximum amount of popup will be visible.
	if ((x+obj.offsetWidth) > viewWidth)
	{
		x -= ((x+obj.offsetWidth) - viewWidth);
		x -= 40;
		if (x < 0) x=5;
	}

	/////////////////////////////////////////////////////////////////
	// Caller can specify that the popup is vertically aligned in
	// the visible browser window.
	if (bVAlign)
	{	
		y = viewHeight/2;
		y += (ie)?document.body.scrollTop:window.pageYOffset;
		y -= obj.offsetHeight/2;
		if (y<0) y=0;
	}

	/////////////////////////////////////////////////////////////////
	// Move the popup to final x,y position
	moveObject(PopId, x, y);
	PopX = x;
	PopY = y;

	/////////////////////////////////////////////////////////////////
	// IE 6 bug fix.  Selection controls (listboxes, droplists) do not
	// have valid z-orders in IE.  These controls will always display
	// on top of other controls.  Therefore, these type of controls
	// need to be hidden if the popup overlaps them.  
	//
	// There are two types of selection items that can be referenced
	// from this function.  The first type is a known selection control
	// position that the popup will overlap.  This control is much
	// larger than the popup, and is clipped rather than fully hidden.
	if ((SelId != '') && ie && !browser.isIE7x)
	{
		// The selection control is referenced in global SelId
		var selDim = getStyleObject(SelId);
		if (selDim)
		{
			selDim.position = 'absolute';
			nObjHeight = obj.offsetHeight - 20;
			selDim.clip = 'rect(' + nObjHeight + ' auto auto auto)';
		}
	}
	//
	// The second type of selection control(s) are controls that
	// are known to be somewhere on the display, and may or may
	// not interfere with the popup.  These controls are checked
	// one at a time for location and overlap with the popup.  If
	// the controls overlap, only then are they hidden.
	if (ie && !browser.isIE7x && (selCtrlIDs.length > 0))
		hideSelectObjects(x, y, obj.offsetWidth, obj.offsetHeight);		 
	//
	/////////////////////////////////////////////////////////////////

	if (styobj.display == 'none')
		styobj.display='inline';
		
	if (!bAnimate)
	{
		obj.onmousedown = startPopMove;

		/////////////////////////////////////////////////////////////////
		// Make the popup visible
		if(changeObjectVisibility(PopId, 'visible')) 
		{
			if (eventObj != null)
				eventObj.cancelBubble = true;
			Loaded = true;
			return true;
		} 
		else 
		{
			return false;
		}
	}
	else
	{
		clipWidth  = obj.offsetWidth;
		clipHeight = obj.offsetHeight;	
		xClip = 0;
		yClip = 0;
		setTimeout('showClip()', 2);
		return true;
	}
}

function showClip()
{
	var styobj = getStyleObject(PopId);
	if (!styobj)
		return;

	styobj.visibility = 'visible';
	
	var ratio = (clipWidth >= clipHeight) ? clipWidth / clipHeight : clipHeight / clipWidth;
	var xMod = (clipWidth <= clipHeight) ? 1 : ratio;
	var yMod = (clipHeight <= clipWidth) ? 1 : ratio;
	
	styobj.clip = 'rect(auto ' + xClip + ' ' + yClip + ' auto)';
	if (xClip < clipWidth)
		xClip += xMod * 6;
	else
		xClip = clipWidth;
	if (yClip < clipHeight)
		yClip += yMod * 6;
	else
		yClip = clipHeight;
	if ((yClip < clipHeight) || (xClip < clipWidth))
	{
		setTimeout('showClip()', 1);
		return;
	}
	
	styobj.clip = 'rect(auto auto auto auto)';
	Loaded = true;
}

function startPopMove(eventObj)
{
	var obj = getObject(PopId);
	if (!obj || !Loaded)
	{
		alert("bad start");
		return;
	}

	var x = (nav)?eventObj.pageX:event.clientX+document.body.scrollLeft;
	var y = (nav)?eventObj.pageY:event.clientY+document.body.scrollTop;
	
	if (y>PopY+20)
		return;
	
	var styobj = getStyleObject(PopId);
	if (styobj)
	{
		if (browser.isIE)		
			styobj.cursor = "move";
		else if (browser.equivalentMozilla)
			styobj.cursor = "-moz-grab";
		else
			styobj.cursor = "move";
	}
		
	PopXStart = x;
	PopYStart = y;
	PopXOffset = x - PopX;
	PopYOffset = y - PopY;
	
	document.onmousemove = movePop;
	document.onmouseup = endPopMove;
	PopOn = true;
}

function movePop(eventObj)
{
	x = (nav)?eventObj.pageX:event.clientX+document.body.scrollLeft;
	y = (nav)?eventObj.pageY:event.clientY+document.body.scrollTop;
	
	if (y-PopYOffset > 0)
		moveObject(PopId, x-PopXOffset, y-PopYOffset);

	var obj = getObject(PopId);
	if (ie && !browser.isIE7x && (selCtrlIDs.length > 0))
		hideSelectObjects(x, y, obj.offsetWidth, obj.offsetHeight);		 
}

function endPopMove(eventObj)
{
	var obj = getObject(PopId);
	if (obj && Loaded)
	{
		var styobj = getStyleObject(PopId);
		if (styobj)
			styobj.cursor = 'default';

		x = (nav)?eventObj.pageX:event.clientX+document.body.scrollLeft;
		y = (nav)?eventObj.pageY:event.clientY+document.body.scrollTop;

		PopX = x-PopXOffset;
		PopY = y-PopYOffset;
		moveObject(PopId, PopX, PopY);

		obj.onmouseup = null;
		obj.onmousemove = null;

		if (ie && !browser.isIE7x && (selCtrlIDs.length > 0))
		{
			showSelectObjects();
			hideSelectObjects(x, y, obj.offsetWidth, obj.offsetHeight);		 
		}
	}
	
	PopXStart=0;
	PopYStart=0;
	PopXOffset=0;
	PopYOffset=0;
	
	PopOn=false;
	
	document.onmouseup = null;
	document.onmousemove = null;
}

function hidePop(pID)
{
	changeObjectVisibility(pID, 'hidden');
	
	if (PopOn)
		endPopMove(event);
	
	if (pID == PopId)
	{
		PopId = '';
		Loaded = false;
		
		if (ie && (SelId != '')){
			selcIdStyle = getStyleObject(SelId);
			if (selcIdStyle)
			{
				selcIdStyle.position = '';
				selcIdStyle.clip = 'rect(auto auto auto auto)';
			}
			
			//changeObjectVisibility(SelId, 'visible');
		}
		if (ie && !browser.isIE7x && (selCtrlIDs.length > 0))
			showSelectObjects();
			
	}
}

function hideSelectObjects(x, y, width, height)
{
	var i=0;
	var selCtrlID;
	var objCtrlID;
	for (i=0; i<selCtrlIDs.length; i++)
	{
		var hidden = false;
		selCtrlID = selCtrlIDs[i];
		objCtrlID = getObject(selCtrlID);
		if (objCtrlID)
		{
			if ((hLineInElement(x, x+width, y, selCtrlID)) ||
				(hLineInElement(x, x+width, y+height, selCtrlID)) ||
				(vLineInElement(y, y+height, x+width, selCtrlID)) ||
				(vLineInElement(y, y+height, x, selCtrlID)))
			{
				hidden = true;
			}
				
			var objPos = getElementPosition(selCtrlID);
			var objX = objPos.left;
			var objY = objPos.top;
			if ((objX >= x) && (objX <= x+width) && (objY >= y) && (objY <= y+height))
				hidden = true;
			
			if (hidden)
			{
			    var styCtrlID = getStyleObject(selCtrlID);
			    if (styCtrlID)
					styCtrlID.visibility = 'hidden';
			}
		}
	}
}

function showSelectObjects()
{
	var i=0;
	var selCtrlID;
	var styCtrlID;
	for (i=0; i<selCtrlIDs.length; i++)
	{
		selCtrlID = selCtrlIDs[i];
		styCtrlID = getStyleObject(selCtrlID);
		if (styCtrlID)
			styCtrlID.visibility = 'visible';
	}
}

function registerIEWindowCtrls(ctrlIDs)
{
	var i=0, j=0;
	var bFound = false;
	for (i=0; i<ctrlIDs.length; i++)
	{
		for (j=0; j<selCtrlIDs.length; j++)
		{
			if (selCtrlIDs[j] == ctrlIDs[i])
			{
				bFound = true;
				break;
			}
		}
		
		if (!bFound)
			selCtrlIDs[selCtrlIDs.length] = ctrlIDs[i];
	}
}

function hideAllPopups(eventObj) 
{
	if ((PopId == '') || (Loaded == false))
		return;

	if (PopOn)
		endPopMove(eventObj);
	
	if (!ie)
	{
		// Fix for bug in Mozilla browers.  Description of bug:
		// http://www.howtocreate.co.uk/mozBugs/testcapture.html
		// Workaround is to see if mouse was clicked inside of
		// popup window.  If so, ignore the click and return.
		
		if (!eventObj) eventObj = window.event;
		
		if (eventObj)
		{
			var mouseX=(nav)?eventObj.pageX:event.clientX+document.body.scrollLeft;
			var mouseY=(nav)?eventObj.pageY:event.clientY+document.body.scrollTop;
			var menuPos = getElementPosition(PopId);
			
			
			objMenu = getObject(PopId);
			if (objMenu)
			{
				if ((mouseX > menuPos.left) && (mouseX < (menuPos.left + objMenu.clientWidth)) &&
					(mouseY > menuPos.top)  && (mouseY < (menuPos.top  + objMenu.clientHeight)))
				{
					return;
				}
			}
		}
	}
	
	Loaded = false;
	
	changeObjectVisibility(PopId, 'hidden');
	PopId = '';
	if (ie && (SelId != '')){
		selcIdStyle = getStyleObject(SelId);
		if (selcIdStyle)
		{
			selcIdStyle.position = '';
			selcIdStyle.clip = 'rect(auto auto auto auto)';
		}
		
		//changeObjectVisibility(SelId, 'visible');
	}
	if (ie && !browser.isIE7x && (selCtrlIDs.length > 0))
		showSelectObjects();
		
	if(nav){
   		document.releaseEvents(Event.MOUSEMOVE);
		document.releaseEvents(Event.MOUSEOVER);
	}
}

function setmsg(msg) {
  window.status=msg
  return true
}

var WorkingWindow = null; 

function showWorking(gifPath)
{
	if (WorkingWindow != null)
	{
		WorkingWindow.close();
		WorkingWindow = null;
	}
		
	WorkingWindow = window.open(gifPath, "Working", 
		"menubar=no,height=120,width=160,scrollbars=no,status=no,resizable=yes" );
		
}

function hideWorking(gifPath)
{
	if (WorkingWindow != null)
	{
		WorkingWindow.close();
		WorkingWindow = null;
		return;
	}
		
	WorkingWindow = window.open(gifPath, "Working", 
		"menubar=no,height=120,width=160,scrollbars=no,status=no,resizable=yes" );
	WorkingWindow.close();	
}

function addWorkingImage(locID, workClass)
{
	var locObj = getObject(locID);
	if (locObj)
	{
		if (ie)
		{
			while (locObj.childNodes[0])
				locObj.removeChild(locObj.childNodes[0]);
		}
		else
		{
			location = document.location;
		}
		locObj.className = workClass;
		pause(100);
	}
}




By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Software architect and developer with over 20 years of experience, specializing in GUI designs and intranet systems in MFC/C++ and ASP.Net using C#.

Comments and Discussions