},\r
\r
show:function(content, optionalEvent){\r
- consolelog("showing popup:"+optionalEvent);\r
//if showing, hide\r
if(this.isShowing()){\r
this.hide();\r
div.show(300, function(){ //basically in between fast (200) and slow (600)\r
//position div shadow:\r
divShadow.show();\r
- consolelog(div.outerHeight(true)+" "+div.outerHeight(false));\r
- consolelog(divShadow.outerHeight(true)+" "+divShadow.outerHeight(false));\r
\r
//set focus to the first input component, if any. Otherwise try with anchors, otherwise do nothing\r
var inputs = $J(div).find(':input');\r
* The workaround is quite tricky and maybe not well formed, as it uses a timeout function. However, any other implementation was trickier\r
* and with potential drawbacks. Note that any subelement of dialogDiv is assigned a "focus" attribute with the current time in millisecs\r
*/\r
-// var setAsPopup = function(dialogDiv, removeOnHide){\r
-// dialogDiv.setAsPopup(removeOnHide ? function(){dialogDiv.remove();} : function(){dialogDiv.hide();});\r
-// };\r
+ // var setAsPopup = function(dialogDiv, removeOnHide){\r
+ // dialogDiv.setAsPopup(removeOnHide ? function(){dialogDiv.remove();} : function(){dialogDiv.hide();});\r
+ // };\r
\r
this.bindClickToPopup = function(invokerAsJQueryObj, popupContent){\r
- var p = new DivDialog(popupContent);\r
+ var p = new DivDialog(popupContent);\r
var oldShow = p.show;\r
- // var pint = parseInt;\r
+ // var pint = parseInt;\r
p.show = function(){\r
\r
var rect = screenRect();\r
var spaceAbove = offs.top - rect.y;\r
var spaceBelow = rect.height - height - spaceAbove;\r
\r
- consolelog('wHeight:'+rect.height+ ' space above: '+spaceAbove + ' spacebelow: '+spaceBelow);\r
+ // consolelog('wHeight:'+rect.height+ ' space above: '+spaceAbove + ' spacebelow: '+spaceBelow);\r
\r
if(spaceAbove>spaceBelow){\r
- p.css({'maxHeight':(spaceAbove-p.shadowoffset)+'px', 'top':rect.y+'px'});\r
+ p.css({\r
+ 'maxHeight':(spaceAbove-p.shadowoffset)+'px',\r
+ 'top':rect.y+'px'\r
+ });\r
}else{\r
- p.css({'maxHeight':(spaceBelow-p.shadowoffset)+'px', 'top':(offs.top+height)+'px'});\r
+ p.css({\r
+ 'maxHeight':(spaceBelow-p.shadowoffset)+'px',\r
+ 'top':(offs.top+height)+'px'\r
+ });\r
}\r
- p.css({'height':'auto','width' :'auto', 'maxWidth': (rect.x+rect.width-offs.left)+'px'});\r
+ p.css({\r
+ 'height':'auto',\r
+ 'width' :'auto',\r
+ 'maxWidth': (rect.x+rect.width-offs.left)+'px'\r
+ });\r
\r
- //consolelog("size"); consolelog(size);\r
-// p.offset({\r
-// left: rect.x + pint((rect.width-size.width)/2),\r
-// top: rect.y + pint((rect.height-size.height)/2)\r
-// });\r
- //consolelog("offset"); consolelog({\r
- // left: rect.x + pint((rect.width-size.width)/2),\r
- // top: rect.y + pint((rect.height-size.height)/2)\r
- // });\r
+ //consolelog("size"); consolelog(size);\r
+ // p.offset({\r
+ // left: rect.x + pint((rect.width-size.width)/2),\r
+ // top: rect.y + pint((rect.height-size.height)/2)\r
+ // });\r
+ //consolelog("offset"); consolelog({\r
+ // left: rect.x + pint((rect.width-size.width)/2),\r
+ // top: rect.y + pint((rect.height-size.height)/2)\r
+ // });\r
\r
oldShow.apply(p,arguments);\r
p.refreshShadowPosition();\r
p.setFocus();\r
};\r
- consolelog(invokerAsJQueryObj);\r
+ //consolelog(invokerAsJQueryObj);\r
p.css({\r
'minWidth':invokerAsJQueryObj.outerWidth()+'px',\r
'left':invokerAsJQueryObj.offset().left+'px'\r
});\r
\r
- p.setPopupFocus(function(){p.hide();});\r
+ p.setPopupFocus(function(){\r
+ p.hide();\r
+ });\r
\r
invokerAsJQueryObj.unbind('click').click(function(evt){\r
- p.show();\r
- return false;\r
+ p.show();\r
+ return false;\r
});\r
- //p.show();\r
- //p.setFocus();\r
+ //p.show();\r
+ //p.setFocus();\r
}\r
/**\r
* Shows an info dialog centered in screeen. The dialog is a DivDialog with maxwidth and maxheight equals to the half of the\r
p.show = function(){\r
oldShow.apply(p,arguments);\r
var rect = screenRect();\r
-// var pint = parseInt;\r
-// p.css({\r
-// 'maxWidth':pint(rect.width/2)+'px',\r
-// 'maxHeight':pint(rect.height/2)+'px'\r
-// });\r
-//consolelog("screeenrect"); consolelog(rect);\r
- var size = p.size();\r
- //consolelog("size"); consolelog(size);\r
- p.offset({\r
- left: rect.x + pint((rect.width-size.width)/2),\r
- top: rect.y + pint((rect.height-size.height)/2)\r
- });\r
- //consolelog("offset"); consolelog({\r
- // left: rect.x + pint((rect.width-size.width)/2),\r
- // top: rect.y + pint((rect.height-size.height)/2)\r
- // });\r
+ // var pint = parseInt;\r
+ // p.css({\r
+ // 'maxWidth':pint(rect.width/2)+'px',\r
+ // 'maxHeight':pint(rect.height/2)+'px'\r
+ // });\r
+ //consolelog("screeenrect"); consolelog(rect);\r
+ var size = p.size();\r
+ //consolelog("size"); consolelog(size);\r
+ p.offset({\r
+ left: rect.x + pint((rect.width-size.width)/2),\r
+ top: rect.y + pint((rect.height-size.height)/2)\r
+ });\r
+ //consolelog("offset"); consolelog({\r
+ // left: rect.x + pint((rect.width-size.width)/2),\r
+ // top: rect.y + pint((rect.height-size.height)/2)\r
+ // });\r
\r
- p.refreshShadowPosition();\r
+ p.refreshShadowPosition();\r
\r
};\r
var rect = screenRect();\r
p=null;\r
},timeInMsec);\r
}else if(timeInMsec == 'hide'){ //is a boolean\r
- p.setPopupFocus(function(){p.hide();});\r
+ p.setPopupFocus(function(){\r
+ p.hide();\r
+ });\r
}else if(timeInMsec == 'remove'){ //is a boolean\r
- p.setPopupFocus(function(){p.remove();});\r
+ p.setPopupFocus(function(){\r
+ p.remove();\r
+ });\r
}\r
p.show();\r
p.setFocus();\r
\r
\r
\r
-// if(invoker.is('a') || invoker.is('input[type=button]') || invoker.is('button') ||\r
-// invoker.is('input[type=submit]')){\r
-// var w = invoker.outerWidth();\r
-// popup.css({'minWidth':w+'px'});\r
-// this.show = show1();\r
-// }else{\r
-//\r
-// }\r
+ // if(invoker.is('a') || invoker.is('input[type=button]') || invoker.is('button') ||\r
+ // invoker.is('input[type=submit]')){\r
+ // var w = invoker.outerWidth();\r
+ // popup.css({'minWidth':w+'px'});\r
+ // this.show = show1();\r
+ // }else{\r
+ //\r
+ // }\r
\r
this.maxSize = function(size){\r
- popup.css({'maxHeight':size.height,'maxWidth':size.width});\r
- popupContent.css({'maxHeight':size.height-(popup.outerHeight()-popup.height()),'maxWidth':size.width-(popup.outerWidth()-popup.width())});\r
+ popup.css({\r
+ 'maxHeight':size.height,\r
+ 'maxWidth':size.width\r
+ });\r
+ popupContent.css({\r
+ 'maxHeight':size.height-(popup.outerHeight()-popup.height()),\r
+ 'maxWidth':size.width-(popup.outerWidth()-popup.width())\r
+ });\r
};\r
this.minsize = function(size){\r
- popup.css({'minHeight':size.height,'minWidth':size.width});\r
+ popup.css({\r
+ 'minHeight':size.height,\r
+ 'minWidth':size.width\r
+ });\r
};\r
- this.offset = function(){\r
+ this.offset = function(){\r
var ret = popup.offset.apply(popup,arguments);\r
//refreshPosition();\r
return me;\r
}\r
}\r
arg = [a];\r
-// consolelog('css');\r
-// consolelog(arg);\r
+ // consolelog('css');\r
+ // consolelog(arg);\r
}\r
}else{\r
return me;\r
\r
\r
\r
-// this.bindAsPopupFor = function(jQueryAnchorElement){\r
-// if(!jQueryAnchorElement.attr('id')){\r
-// jQueryAnchorElement.attr('id','popup_'+new Date().getTime());\r
-// }\r
-// var id = jQueryAnchorElement.attr('id');\r
-//\r
-// anchorElement.click(function(){\r
-//\r
-// })\r
-//\r
-// }\r
+ // this.bindAsPopupFor = function(jQueryAnchorElement){\r
+ // if(!jQueryAnchorElement.attr('id')){\r
+ // jQueryAnchorElement.attr('id','popup_'+new Date().getTime());\r
+ // }\r
+ // var id = jQueryAnchorElement.attr('id');\r
+ //\r
+ // anchorElement.click(function(){\r
+ //\r
+ // })\r
+ //\r
+ // }\r
\r
this.setPopupFocus = function(callbackOnFocusLost){\r
\r
//otherwise execute callback\r
setTimeout(function(){\r
var v = document.activeElement;\r
- consolelog(v);\r
+ // consolelog(v);\r
if(v && $J(v).attr(focusid)){\r
return;\r
}\r
}\r
\r
\r
+\r
+\r
+\r
+//var PopupManager={\r
+//\r
+// //default properties:\r
+// $J: jQuery,\r
+// shadowOpacity: 0.4,\r
+// shadowOffset: 5,\r
+// zIndex: 1000,\r
+// infoDialogMaxSizeInWindowPercent: 0.5,\r
+// defaultClasses: 'control component',\r
+// createPopupDiv: function(content){\r
+// var $J = this.$J;\r
+// var wdw = $J(window);\r
+// var div = $J('<div/>').addClass(this.defaultClasses).css({\r
+// 'position':'absolute',\r
+// 'zIndex':this.zIndex,\r
+// 'visibility':'hidden',\r
+// 'left':wdw.scrollLeft()+'px',\r
+// 'top':wdw.scrollTop()+'px',\r
+// 'overflow':'auto',\r
+// 'padding':'1ex'\r
+// });\r
+// div.appendTo('body'); //necessary to properly display the div size\r
+// if(content instanceof $J){\r
+// div.append(content);\r
+// }else if(typeof content == 'string'){\r
+// div.html(""+content);\r
+// }else{\r
+// div.css('overflow',''); //clear overflow\r
+// var container = $J('<div/>').css('overflow','auto');\r
+// var table = $J('<table/>');\r
+// container.append(table);\r
+// var insert = function(e1,e2){\r
+// var t1 = $J('<td/>');\r
+// var t2 = $J('<td/>');\r
+// if(e1){\r
+// t1.append(e1);\r
+// }\r
+// if(e2){\r
+// t2.append(e2);\r
+// }\r
+// table.append($J('<tr/>').append(t1).append(t2));\r
+// }\r
+// var title, component;\r
+// for(var k in content){\r
+// var val = content[k];\r
+// if(val instanceof Function){\r
+// component = $J('<a/>').html(k).attr('href','#').click(function(evt){\r
+// val();\r
+// return false;\r
+// });\r
+// insert(component);\r
+// }else if(typeof val == 'string' || typeof val == 'number'){\r
+// title = $J('<span/>').html(k);\r
+// component = $('<input/>').attr('type','text').val(val).attr('name',k);\r
+// insert(title,component);\r
+// }else if(val === true || val === false){\r
+// title = $J('<span/>').html(k);\r
+// component = $('<input/>').attr('type','checkbox').attr('name',k);\r
+// if(val){\r
+// component.attr('checked','checked');\r
+// }else{\r
+// component.removeAttr('checked');\r
+// }\r
+// insert(title,component);\r
+// }\r
+// }\r
+// }\r
+// this.getId(div); //actually, sets an id (see below)\r
+// return div;\r
+// },\r
+//\r
+// showInfoDialog: function(content, timeInMSec){\r
+// var remove = this.remove;\r
+// var popup = this.createPopupDiv(content)\r
+// this.setBounds(popup,this.infoDialogMaxSizeInWindowPercent);\r
+// if(timeInMSec){\r
+// this.show(popup, function(){\r
+// setTimeout(function(){\r
+// remove(content)\r
+// },timeInMSec);\r
+// })\r
+// }else{\r
+// var focus = this.setPopupBehaviourAndReturnFocusElement(popup, true); //remove on hide\r
+// this.show(popup);\r
+// focus.focus();\r
+// }\r
+// },\r
+//\r
+// getId: function(div){\r
+// if(!(div.attr('id'))){\r
+// div.attr('id','popup_'+(new Date().getTime()));\r
+// }\r
+// return div.attr('id');\r
+// },\r
+// /**\r
+// * sets dialogDiv (a jQuery object or a DivDialog, see below) as popup mode. In other words,\r
+// * scans each sub-element of dialogDiv and assigns to it a onblur event: when the subselemnt looses the focus and the focus\r
+// * is NOT given to another dialogDiv subelement, hides or removes (depending on removeOnHide param) dialogDiv.\r
+// * The workaround is quite tricky and maybe not well formed, as it uses a timeout function. However, any other implementation was trickier\r
+// * and with potential drawbacks. Note that any subelement of dialogDiv is assigned a "focus" attribute with the current time in millisecs\r
+// */\r
+// bindPopupClick: function(invoker, popupDiv, removeOnBlur){\r
+// if(invoker.is('a') || invoker.is('input[type=button]') || invoker.is('button') ||\r
+// invoker.is('input[type=submit]')){\r
+// var $J = this.$J;\r
+// var focusElm = this.setPopupBehaviourAndReturnFocusElement(popupDiv, removeOnBlur ? this.remove(popupDiv) : this.hide(popupDiv));\r
+// var id = this.getId(popupDiv);\r
+// var me = this;\r
+// invoker.unbind('click').bind('click',function(evt){\r
+// var pup = $J('#'+id); //dont do anything if the popup is already visible\r
+// if(pup.length && pup.is(':visible')){\r
+// focusElm.focus();\r
+// return false;\r
+// }\r
+//// me.setBounds.apply(me, [popupDiv,invoker]);\r
+//// me.show.apply(me,[popupDiv, function(){focusElm.focus();}]);\r
+// me.show.apply(me,[popupDiv, function(){me.setBounds.apply(me, [popupDiv,invoker]);focusElm.focus();}]);\r
+// return false;\r
+// });\r
+// }\r
+// },\r
+//\r
+// //binds every child of popup that is focusable to a blur event\r
+// //TODO: TEST IT WITH OTHER BROWSERS!!!! if not working, manda tutto affanculo and use click events\r
+// setPopupBehaviourAndReturnFocusElement: function(popup, callbackOnBlur){\r
+// popup.attr('tabindex',0);\r
+// var $J = this.$J;\r
+// var elementsWithFocus = $J(popup).find('textarea,a,input');\r
+// var doc = document;\r
+// var ret = elementsWithFocus.length ? $J(elementsWithFocus[0]) : popup;\r
+// elementsWithFocus = elementsWithFocus.add(popup);\r
+// //build the attribute focus to recognize subelement of popup\r
+// var focusid = 'popupfocus'+(new Date().getTime());\r
+// var me = this;\r
+// //bind the blur to each focusable element:\r
+// elementsWithFocus.each(function(i,e){\r
+// var ee = $J(e);\r
+// ee.attr(focusid,'true');\r
+// ee.attr('tabindex',i+1);\r
+// ee.blur(function(){\r
+// //wait 250msec to see if the focus has been given to another popup focusable element: if yes, do nothing\r
+// //otherwise execute callback\r
+// setTimeout(function(){\r
+// var v = doc.activeElement;\r
+// //consolelog(v);\r
+// if(v && $J(v).attr(focusid)){\r
+// return;\r
+// }\r
+// if(callbackOnBlur){\r
+// me.hide.apply(me,[popup,callbackOnBlur]);\r
+// }else{\r
+// me.hide.apply(me,[popup]);\r
+// }\r
+// },200)\r
+// }); //set here another time delay. 300 seems to be the good compromise between visual hide and safetiness that\r
+// //meanwhile the focus has already been given to the next component\r
+// });\r
+// return ret;\r
+// },\r
+//\r
+//\r
+// hideAllPopups: function(){\r
+// this.hide(this.$J('div[name^="popup_"]'));\r
+// },\r
+//\r
+// //show(div, argumentsAsInJQueryShow)\r
+// //creates a shwdow and shows div and shadow\r
+// show: function(){\r
+// var div = arguments[0];\r
+// div.css({\r
+// 'display':'none',\r
+// 'visibility':'visible'\r
+// });\r
+// var body = this.$J('body');\r
+// if(!div.parent().length){\r
+// div.appendTo('body');\r
+// }\r
+// //TODO: avoid clone and empty?\r
+// var shadow = div.clone(true,true).empty().css({\r
+// 'backgroundColor':'#000',\r
+// 'borderColor':'#000',\r
+// 'zIndex':this.zIndex-1\r
+// }).removeAttr('tabindex').fadeTo(0,this.shadowOpacity);\r
+// var id = this.getId(div);\r
+// shadow.attr('id',id+'_shadow'); //for use in hide\r
+// body.append(shadow);\r
+//\r
+// var both = div.add(shadow);\r
+//\r
+// var me = this;\r
+// var placeShadow = function(){\r
+// var rect = me.getBounds.apply(me,[div]);\r
+// shadow.css({\r
+// 'left':(rect.x + me.shadowOffset)+'px',\r
+// 'top':(rect.y + me.shadowOffset)+'px',\r
+// 'width':(rect.width)+'px',\r
+// 'height':(rect.height)+'px'\r
+// });\r
+// }\r
+// //calling show with the specified arguments:\r
+// var args = [];\r
+// for(var i=1; i<arguments.length; i++){\r
+// args.push(arguments[i]);\r
+// }\r
+// if(args.length==0 || !(args[args.length-1] instanceof Function)){\r
+// args.push(placeShadow);\r
+// }else{\r
+// var fcn = args[args.length-1];\r
+// args[args.length-1] = function(){\r
+// placeShadow();\r
+// fcn();\r
+// }\r
+// }\r
+// both.show.apply(both,args);\r
+// },\r
+//\r
+// //hide(div, argumentsAsInJQueryShow)\r
+// hide: function(){\r
+// var $J = this.$J;\r
+// var div = arguments[0];\r
+// var shadow = $J([]);\r
+// $J.each(div, function(i,e){\r
+// shadow = shadow.add($J('#'+$J(e).attr('id')+'_shadow'));\r
+// });\r
+// var both = div.add(shadow);\r
+// //calling hide with the specified arguments:\r
+// var removeShadow = new function(){\r
+// shadow.remove();\r
+// };\r
+// var args = [];\r
+// for(var i=1; i<arguments.length; i++){\r
+// args.push(arguments[i]);\r
+// }\r
+// if(args.length<1 || !(args[args.length-1] instanceof Function)){\r
+// args.push(removeShadow);\r
+// }else{\r
+// var f = args[args.length-1];\r
+// var newf = function(){\r
+// removeShadow();\r
+// f();\r
+// }\r
+// args[args.length-1] = newf;\r
+// }\r
+// both.hide.apply(both, args);\r
+// },\r
+//\r
+// remove: function(div){\r
+// var shadow = $J('#'+div.attr('id')+'_shadow');\r
+// var both = div.add(shadow);\r
+// both.remove();\r
+// },\r
+//\r
+// setMaxSize: function(div, size){\r
+// this.convertSize(div, size);\r
+// var css = {};\r
+// if('width' in size){\r
+// css.maxWidth = size.width+'px';\r
+// }\r
+// if('height' in size){\r
+// css.maxHeight = size.height+'px';\r
+// }\r
+// if(css){\r
+// div.css(css);\r
+// }\r
+// return size;\r
+// },\r
+// setMinSize: function(div, size){\r
+// this.convertSize(div, size);\r
+// var css = {};\r
+// if('width' in size){\r
+// css.minWidth = size.width+'px';\r
+// }\r
+// if('height' in size){\r
+// css.minHeight = size.height+'px';\r
+// }\r
+// if(css){\r
+// div.css(css);\r
+// }\r
+// return size;\r
+// },\r
+// //div must be display!=hidden. size is a dict with at least one of the fields 'width' and 'height'\r
+// convertSize: function(div, size){\r
+// var eD = {\r
+// 'width': div.outerWidth(true)-div.width(),\r
+// 'height':div.outerHeight(true)-div.height()\r
+// };\r
+// if('width' in size){\r
+// size.width -= (eD.width + this.shadowOffset);\r
+// }\r
+// if('height' in size){\r
+// size.height -= (eD.height + this.shadowOffset);\r
+// }\r
+// },\r
+//\r
+// setSize: function(div, size){ //does it works like that?\r
+// this.setMaxSize(div, size);\r
+// this.setMinSize(div, size);\r
+// },\r
+//\r
+// offset: function(div, offs){\r
+// //if offs is a jquery element, size it as a popup.\r
+// div.offset(offs);\r
+// },\r
+//\r
+// //div must be display!=hidden\r
+// centerInParent: function(div, parent, maxPercentageSize){\r
+// var bounds = this.getBounds(parent);\r
+// var x=bounds.x;\r
+// var y = bounds.y;\r
+// var w = bounds.width\r
+// var h = bounds.height;\r
+// var pInt = parseInt;\r
+// if(maxPercentageSize){\r
+// this.setMaxSize(div,{\r
+// 'width':pInt(w*maxPercentageSize),\r
+// 'height':pInt(h*maxPercentageSize)\r
+// });\r
+// }\r
+// var offs = {\r
+// 'left':x+pInt((w-div.outerWidth())/2),\r
+// 'top':y+pInt((h-div.outerHeight())/2)\r
+// };\r
+// div.offset(offs);\r
+// },\r
+// //setBounds(div, invokerAsjQueryElement): sets the maxsize, minwidth and offset relative ot invokerAs...\r
+// //setBounds(div, 0.5) sets the maxsize and the offset relative to the window\r
+// setBounds: function(popupDiv, argument){\r
+// if(typeof invokerAsJQueryObj == 'number'){\r
+// this.centerInParent(popupDiv, this.$J(window), argument);\r
+// return;\r
+// }\r
+// var popupOffset = {\r
+// 'left':argument.offset().left,\r
+// 'top':0\r
+// };\r
+// var windowRectangle = this.getBounds(); //returns the window rectangle\r
+// var invokerOffset = argument.offset();\r
+// var invokerOuterHeight = argument.outerHeight();\r
+//\r
+// var spaceAbove = invokerOffset.top - windowRectangle.y;\r
+// var spaceBelow = windowRectangle.height - invokerOuterHeight - spaceAbove;\r
+//\r
+// // consolelog('wHeight:'+rect.height+ ' space above: '+spaceAbove + ' spacebelow: '+spaceBelow);\r
+//\r
+// var popupMaxSize={\r
+// height:0,\r
+// width:(windowRectangle.x+windowRectangle.width-invokerOffset.left)\r
+// };\r
+// if(spaceAbove>spaceBelow){\r
+// popupMaxSize.height = (spaceAbove-popupDiv.shadowoffset);\r
+// popupOffset.top = invokerOffset.top - popupDiv.outerHeight(true);\r
+//\r
+// //p.css({'maxHeight':(spaceAbove-p.shadowoffset)+'px', 'top':rect.y+'px'});\r
+// }else{\r
+// popupMaxSize.height =(spaceBelow-popupDiv.shadowoffset);\r
+// popupOffset.top = (invokerOffset.top+invokerOuterHeight);\r
+// //p.css({'maxHeight':(spaceBelow-p.shadowoffset)+'px', 'top':(offs.top+height)+'px'});\r
+// }\r
+// this.setMaxSize(popupDiv, popupMaxSize);\r
+// this.setMinSize(popupDiv, {\r
+// width: argument.outerWidth()\r
+// });\r
+// this.offset(popupDiv, popupOffset);\r
+//\r
+// consolelog('maxSize');\r
+// consolelog(popupMaxSize);\r
+// consolelog('minWidth');\r
+// consolelog(argument.outerWidth());\r
+// consolelog('offset');\r
+// consolelog(popupOffset);\r
+// consolelog('maxWidth: '+popupDiv.css('maxWidth')+' maxHeight: '+popupDiv.css('maxHeight')+\r
+// ' width: '+popupDiv.css('width')+' height: '+popupDiv.css('height')+' left '+popupDiv.css('left')+' top '+popupDiv.css('top'));\r
+// },\r
+// //returns a dictionary with x,y,width and height keys representing the\r
+// //rectangle where jQueryElement lies. width and height are jQuery.width() and jQuery.height() respectively\r
+// //if jQueryElement is missing, jQuery(window) is used\r
+// //jQueryElement must be display!=none\r
+// getBounds: function(jQueryElement){\r
+// var ret = {\r
+// x:0,\r
+// y:0,\r
+// width:0,\r
+// height:0\r
+// };\r
+// if(!jQueryElement){\r
+// jQueryElement = this.$J(window);\r
+// }\r
+// if(jQueryElement[0] === window){\r
+// ret.x = jQueryElement.scrollLeft();\r
+// ret.y = jQueryElement.scrollTop();\r
+// }else{\r
+// var offs = jQueryElement.offset();\r
+// ret.x = offs.left;\r
+// ret.y = offs.top;\r
+// }\r
+// ret.width = jQueryElement.width();\r
+// ret.height = jQueryElement.height();\r
+// return ret;\r
+// }\r
+//\r
+//\r
+//};\r
+\r
+function PopupDiv(content){\r
+ var $J = this.$J;\r
+ //var wdw = $J(window);\r
+ var div = $J('<div/>').addClass(this.defaultClasses).css({\r
+ 'position':'absolute',\r
+ 'zIndex':this.zIndex,\r
+// 'display':'none',\r
+// 'left':wdw.scrollLeft()+'px',\r
+// 'top':wdw.scrollTop()+'px',\r
+ 'overflow':'auto',\r
+ 'padding':'1ex',\r
+ 'border':'1px solid #666'\r
+ });\r
+ //div.appendTo('body'); //necessary to properly display the div size\r
+ if(content instanceof $J){\r
+ div.append(content);\r
+ }else if(typeof content == 'string'){\r
+ div.html(""+content);\r
+ }else{\r
+ div.css('overflow',''); //clear overflow\r
+ var container = $J('<div/>').css('overflow','auto');\r
+ var table = $J('<table/>');\r
+ container.append(table);\r
+ var insert = function(e1,e2){\r
+ var t1 = $J('<td/>');\r
+ var t2 = $J('<td/>');\r
+ if(e1){\r
+ t1.append(e1);\r
+ }\r
+ if(e2){\r
+ t2.append(e2);\r
+ }\r
+ table.append($J('<tr/>').append(t1).append(t2));\r
+ }\r
+ var title, component;\r
+ for(var k in content){\r
+ var val = content[k];\r
+ if(val instanceof Function){\r
+ component = $J('<a/>').html(k).attr('href','#').click(function(evt){\r
+ val();\r
+ return false;\r
+ });\r
+ insert(component);\r
+ }else if(typeof val == 'string' || typeof val == 'number'){\r
+ title = $J('<span/>').html(k);\r
+ component = $('<input/>').attr('type','text').val(val).attr('name',k);\r
+ insert(title,component);\r
+ }else if(val === true || val === false){\r
+ title = $J('<span/>').html(k);\r
+ component = $('<input/>').attr('type','checkbox').attr('name',k);\r
+ if(val){\r
+ component.attr('checked','checked');\r
+ }else{\r
+ component.removeAttr('checked');\r
+ }\r
+ insert(title,component);\r
+ }\r
+ }\r
+ }\r
+ div.attr('id',this.defaultId+"_"+(new Date().getTime()));\r
+ this.getFocusId = function(){\r
+ return this.defaultId+'_focus';\r
+ }\r
+ this.getDiv = function(){\r
+ return div;\r
+ }\r
+ \r
+ this.callbackPreShow = null;\r
+ this.callbackPostShow = null;\r
+}\r
+(function(p){\r
+ //populating the prototype:\r
+ //properties:\r
+ p.defaultFadeTime='fast',\r
+ p.$J = jQuery;\r
+ p.shadowOpacity = 0.4;\r
+ p.shadowOffset = 5;\r
+ p.zIndex = 1000;\r
+ p.defaultClasses = 'control component';\r
+ p.defaultId = 'popup_'+(new Date().getTime());\r
+ p.focusId = p.defaultId+'_focus';\r
+\r
+ //p.wdow = p.$J(window);\r
+ //methods:\r
+ p.getId = function(){\r
+ var div = this.getDiv();\r
+ if(!(div.attr('id'))){\r
+ div.attr('id',this.defaultId+'_'+(new Date().getTime()));\r
+ }\r
+ return div.attr('id');\r
+ };\r
+ //p.createButtons({'ok':function...,'cancel':function,...});\r
+ \r
+\r
+ p.setAsPopupOf = function(invoker,removeOnBlur){\r
+ if(!(invoker.is('a') || invoker.is('input[type=button]') || invoker.is('button') ||\r
+ invoker.is('input[type=submit]'))){\r
+ return;\r
+ }\r
+ invoker.attr('tabindex',0).attr(this.focusId,'true');\r
+ //invoker.attr(this.getFocusId(),'true');\r
+ var me =this;\r
+ this.callbackPreShow = function(){\r
+ me.setBounds.apply(me,[invoker]);\r
+ };\r
+ this.callbackPostShow = function(){\r
+ var fcn = removeOnBlur ? me.remove : me.hide;\r
+ me.setFocusable.apply(me,[function(){\r
+ fcn.apply(me);\r
+ }]);\r
+ var elm = me.getFirstFocusableElement();\r
+ elm.focus();\r
+ };\r
+\r
+ var popupDiv = this.getDiv();\r
+ invoker.unbind('click').bind('click',function(evt){\r
+ if(popupDiv.length && popupDiv.is(':visible')){\r
+ me.getFirstFocusableElement().focus();\r
+ return false;\r
+ }\r
+ // me.setBounds.apply(me, [popupDiv,invoker]);\r
+ // me.show.apply(me,[popupDiv, function(){focusElm.focus();}]);\r
+ me.show.apply(me);\r
+ return false;\r
+ });\r
+ };\r
+\r
+ p.setAsWindowDialog = function(timeInMsec, windowPercentSize){\r
+\r
+ var me =this;\r
+ this.callbackPreShow = function(){\r
+ me.setBounds.apply(me,[windowPercentSize]);\r
+ }\r
+\r
+ if(timeInMsec){\r
+ this.callbackPostShow = function(){\r
+ setTimeout(timeInMsec, function(){\r
+ me.remove.apply(me);\r
+ });\r
+ }\r
+ }else{\r
+ this.callbackPostShow = function(){\r
+ var elm = me.setFocusable.apply(me,function(){\r
+ me.remove.apply(me);\r
+ });\r
+ elm.focus();\r
+ };\r
+ }\r
+ };\r
+ p.setFocusable = function(callbackOnBlur){\r
+ var popup = this.getDiv();\r
+ popup.attr('tabindex',0);\r
+ var $J = this.$J;\r
+ var elementsWithFocus = $J(popup).find('textarea,a,input');\r
+ var doc = document;\r
+ var ret = elementsWithFocus.length ? $J(elementsWithFocus[0]) : popup;\r
+ elementsWithFocus = elementsWithFocus.add(popup);\r
+ //build the attribute focus to recognize subelement of popup\r
+ var focusid =this.focusId;\r
+ \r
+ //bind the blur to each focusable element:\r
+ elementsWithFocus.each(function(i,e){\r
+ var ee = $J(e);\r
+ ee.removeAttr(focusid).attr(focusid,'true'); //makes sense?\r
+ ee.attr('tabindex',i+1);\r
+ ee.unbind('blur').blur(function(){\r
+ //wait 250msec to see if the focus has been given to another popup focusable element: if yes, do nothing\r
+ //otherwise execute callback\r
+ setTimeout(function(){\r
+ var v = doc.activeElement;\r
+ //consolelog(v);\r
+ if(v && $J(v).attr(focusid)){\r
+ return;\r
+ }\r
+ if(callbackOnBlur){\r
+ callbackOnBlur();\r
+ }\r
+ },200)\r
+ }); //set here another time delay. 300 seems to be the good compromise between visual hide and safetiness that\r
+ //meanwhile the focus has already been given to the next component\r
+ });\r
+ this.getFirstFocusableElement = function(){\r
+ return ret;\r
+ }\r
+ };\r
+\r
+ p.show = function(){\r
+ var div = this.getDiv();\r
+\r
+ if(!div.parent().length){\r
+ div.appendTo('body');\r
+ }\r
+ //set the div as opacity 0 but displayable\r
+ div.css({\r
+ 'visibility':'visible'\r
+ }).fadeTo(0,0).show();\r
+\r
+ if(this.callbackPreShow){\r
+ this.callbackPreShow();\r
+ }\r
+\r
+ \r
+ //TODO: avoid clone and empty?\r
+ var shadow = div.clone(true,true).empty().css({\r
+ 'backgroundColor':'#000',\r
+ 'borderColor':'#000',\r
+ 'zIndex':this.zIndex-1\r
+ }).removeAttr('tabindex').fadeTo(0,0);\r
+ var id = this.getId();\r
+ shadow.attr('id',id+'_shadow'); //for use in hide\r
+ shadow.insertAfter(div);\r
+\r
+ var me = this;\r
+ var postShowFcn = function(){\r
+ var rect = me.getBounds.apply(me);\r
+ shadow.css({\r
+ 'left':(rect.x + me.shadowOffset)+'px',\r
+ 'top':(rect.y + me.shadowOffset)+'px',\r
+ 'width':(rect.width)+'px',\r
+ 'height':(rect.height)+'px'\r
+ }).fadeTo(0,me.shadowOpacity);\r
+ if(me.callbackPostShow){\r
+ me.callbackPostShow.apply(me);\r
+ }\r
+ }\r
+\r
+ var arg1 = arguments.length && arguments[0] instanceof Function ? arguments[0] : this.defaultFadeTime;\r
+ var arg2 = arguments.length && arguments[arguments.length-1] instanceof Function ? arguments[arguments.length-1] : undefined;\r
+\r
+ div.fadeTo(arg1,1,function(){\r
+ postShowFcn();\r
+ if(arg2){\r
+ arg2();\r
+ }\r
+ });\r
+ };\r
+ //setBounds(0.5)\r
+ //setBounds(jQueryDisplayedElement)\r
+ p.setBounds = function(arg){\r
+ if(typeof arg == ' number'){\r
+ this.centerIn(this.$J(window), arg);\r
+ return;\r
+ }\r
+ var invoker = arg;\r
+ var popupDiv = this.getDiv();\r
+\r
+ var popupOffset = {\r
+ 'left':invoker.offset().left,\r
+ 'top':0\r
+ };\r
+ var windowRectangle = this.getBoundsOf(this.$J(window)); //returns the window rectangle\r
+ var invokerOffset = invoker.offset();\r
+ var invokerOuterHeight = invoker.outerHeight();\r
+\r
+ var spaceAbove = invokerOffset.top - windowRectangle.y;\r
+ var spaceBelow = windowRectangle.height - invokerOuterHeight - spaceAbove;\r
+\r
+ var popupMaxSize={\r
+ height:0,\r
+ width:(windowRectangle.x+windowRectangle.width-invokerOffset.left)\r
+ };\r
+ if(spaceAbove>spaceBelow){\r
+ popupMaxSize.height = spaceAbove;\r
+ popupOffset.top = invokerOffset.top - Math.min(spaceAbove, popupDiv.outerHeight(true));\r
+\r
+ //p.css({'maxHeight':(spaceAbove-p.shadowoffset)+'px', 'top':rect.y+'px'});\r
+ }else{\r
+ popupMaxSize.height = Math.min(spaceBelow, popupDiv.outerHeight(true));\r
+ popupOffset.top = (invokerOffset.top+invokerOuterHeight);\r
+ //p.css({'maxHeight':(spaceBelow-p.shadowoffset)+'px', 'top':(offs.top+height)+'px'});\r
+ }\r
+ this.setMaxSize(popupMaxSize);\r
+ this.setMinSize({\r
+ width: invoker.outerWidth()\r
+ });\r
+ this.offset(popupOffset);\r
+\r
+ consolelog('maxSize:');\r
+ consolelog(popupMaxSize);\r
+ consolelog('minWidth:'+ invoker.outerWidth());\r
+ consolelog('offset:');\r
+ consolelog(popupOffset);\r
+ consolelog('maxWidth: '+popupDiv.css('maxWidth')+' maxHeight: '+popupDiv.css('maxHeight')+\r
+ ' width: '+popupDiv.css('width')+' height: '+popupDiv.css('height')+' left '+popupDiv.css('left')+' top '+popupDiv.css('top'));\r
+ };\r
+\r
+ p.centerIn = function(parent, maxPercentageSize){\r
+ var div = this.getDiv();\r
+ var bounds = this._getBounds(parent);\r
+ var x=bounds.x;\r
+ var y = bounds.y;\r
+ var w = bounds.width\r
+ var h = bounds.height;\r
+ var pInt = parseInt;\r
+ if(maxPercentageSize){\r
+ this.setMaxSize(div,{\r
+ 'width':pInt(w*maxPercentageSize),\r
+ 'height':pInt(h*maxPercentageSize)\r
+ });\r
+ }\r
+ var offs = {\r
+ 'left':x+pInt((w-div.outerWidth())/2),\r
+ 'top':y+pInt((h-div.outerHeight())/2)\r
+ };\r
+ div.offset(offs);\r
+ };\r
+ p.getBounds = function(){\r
+ return this.getBoundsOf(this.getDiv());\r
+ },\r
+ //TODO: change argument\r
+ p.getBoundsOf = function(jQueryElement){\r
+ var ret = {\r
+ x:0,\r
+ y:0,\r
+ width:0,\r
+ height:0\r
+ };\r
+ if(!jQueryElement){\r
+ jQueryElement = this.$J(window);\r
+ }\r
+ if(jQueryElement[0] === window){\r
+ ret.x = jQueryElement.scrollLeft();\r
+ ret.y = jQueryElement.scrollTop();\r
+ }else{\r
+ var offs = jQueryElement.offset();\r
+ ret.x = offs.left;\r
+ ret.y = offs.top;\r
+ }\r
+ ret.width = jQueryElement.width();\r
+ ret.height = jQueryElement.height();\r
+ return ret;\r
+ }\r
+\r
+ p.setMaxSize = function(size){\r
+ var div = this.getDiv();\r
+ this._convertSize(div, size);\r
+ var css = {};\r
+ if('width' in size){\r
+ css.maxWidth = size.width+'px';\r
+ }\r
+ if('height' in size){\r
+ css.maxHeight = size.height+'px';\r
+ }\r
+ if(css){\r
+ div.css(css);\r
+ }\r
+ return size;\r
+ };\r
+ p.setMinSize = function(size){\r
+ var div = this.getDiv();\r
+ this._convertSize(div, size);\r
+ var css = {};\r
+ if('width' in size){\r
+ css.minWidth = size.width+'px';\r
+ }\r
+ if('height' in size){\r
+ css.minHeight = size.height+'px';\r
+ }\r
+ if(css){\r
+ div.css(css);\r
+ }\r
+ return size;\r
+ },\r
+ //div must be display!=hidden. size is a dict with at least one of the fields 'width' and 'height'\r
+ p._convertSize = function(div, size){\r
+ var eD = {\r
+ 'width': div.outerWidth(true)-div.width(),\r
+ 'height':div.outerHeight(true)-div.height()\r
+ };\r
+ if('width' in size){\r
+ size.width -= (eD.width + this.shadowOffset);\r
+ }\r
+ if('height' in size){\r
+ size.height -= (eD.height + this.shadowOffset);\r
+ }\r
+ },\r
+\r
+ p.setSize = function(div, size){ //does it works like that?\r
+ this.setMaxSize(div, size);\r
+ this.setMinSize(div, size);\r
+ };\r
+\r
+ p.offset = function(offs){\r
+ //if offs is a jquery element, size it as a popup.\r
+ this.getDiv().offset(offs);\r
+ };\r
+\r
+ p.hide = function(){\r
+ var div = this.getDiv();\r
+ var $J = this.$J;\r
+ var shadow = $J([]);\r
+ $J.each(div, function(i,e){\r
+ shadow = shadow.add($J('#'+$J(e).attr('id')+'_shadow'));\r
+ });\r
+ var both = div.add(shadow);\r
+ //calling hide with the specified arguments:\r
+ var removeShadow = new function(){\r
+ shadow.remove();\r
+ };\r
+ var args = [];\r
+ for(var i=1; i<arguments.length; i++){\r
+ args.push(arguments[i]);\r
+ }\r
+ if(args.length<1 || !(args[args.length-1] instanceof Function)){\r
+ args.push(removeShadow);\r
+ }else{\r
+ var f = args[args.length-1];\r
+ var newf = function(){\r
+ removeShadow();\r
+ f();\r
+ }\r
+ args[args.length-1] = newf;\r
+ }\r
+ both.hide.apply(both, args);\r
+ };\r
+\r
+ p.remove = function(){\r
+ var div = this.getDiv();\r
+ var shadow = $J('#'+div.attr('id')+'_shadow');\r
+ var both = div.add(shadow);\r
+ both.remove();\r
+ };\r
+})(PopupDiv.prototype);
\ No newline at end of file