}\r
}\r
//now we can build the divShadow\r
- var divShadow = div.clone(false,false).empty().css({'zIndex':999,'borderColor':'#000','display':'none','backgroundColor':'#000'}).insertAfter(div);\r
+ var divShadow = div.clone(false,false).empty().css({\r
+ 'zIndex':999,\r
+ 'borderColor':'#000',\r
+ 'display':'none',\r
+ 'backgroundColor':'#000'\r
+ }).insertAfter(div);\r
//store the divs to be removed\r
this._cfg_.divsToDelete = [div,divShadow];\r
//add a listener to the document. If one of the content children is clicked/keypressed,\r
\r
divShadow.fadeTo(0,0.4, function(){\r
divShadow.css({\r
- 'top': (position.top+shadowOffset),\r
- 'left': (position.left+shadowOffset),\r
- 'width': div.outerWidth(true),\r
- 'height': div.outerHeight(true)\r
- });\r
+ 'top': (position.top+shadowOffset),\r
+ 'left': (position.left+shadowOffset),\r
+ 'width': div.outerWidth(true),\r
+ 'height': div.outerHeight(true)\r
+ });\r
\r
});\r
});\r
}\r
}\r
\r
+function PopupUtils(){\r
+ var $J= jQuery;\r
+ var wdow = $J(window); //reference the window object (doing it once speeds up a bit performances)\r
+ var doc = $J(document);\r
+ var screenRect = function(){\r
+ return {\r
+ x:wdow.scrollLeft(),\r
+ y:wdow.scrollTop(),\r
+ width:wdow.width(),\r
+ height:wdow.height()\r
+ };\r
+ };\r
+ \r
\r
-//var PopupClass=function(innerHTML,event){\r
-// var $J = jQuery; //reference to jQuery\r
-// var className = 'component'; //the optional div class name\r
-// var div = $J('<div/>').css({ //create the div (the popup)\r
-// position: 'absolute',\r
-// overflow:'auto', //necessary to properly display the content\r
-// display: 'none',\r
-// zIndex:1000\r
-// });\r
-// if(className){\r
-// div.addClass(className);\r
-// };\r
-//\r
-// if(content instanceof $J){\r
-// div.append(content);\r
-// }else{\r
-// div.html(content);\r
-// }\r
-// //create the div shadow\r
-// var divShadow = div.clone(false,false).empty().css({'zIndex':999,'borderColor':'#000','display':'none','backgroundColor':'#000'}).insertAfter(div);\r
-// //append to the body\r
-// var body = $J('body');\r
-// body.append(div);\r
-// divShadow.insertAfter(div);\r
-// div = div.add(divShadow);\r
-// //set the id\r
-// var time = new Date().getTime();\r
-// div.attr('id','popup_'+time);\r
-// divShadow.attr('id','popupshadow_'+time);\r
-// //make thid class a jQuery object:\r
-// $J.extend(this,div);\r
-// //override some methods:\r
-// //\r
-// //private function which binds/unbinds click and key events\r
-// var toggleBind = function(element, callback){\r
-// var clickNamespace = "click.popup__"+time;\r
-// var keydownNamespace = "keyup.popup__"+time;\r
-// element.unbind(clickNamespace);\r
-// element.unbind(keydownNamespace);\r
-// if(callback){\r
-// element.bind(clickNamespace, callback);\r
-// element.bind(keydownNamespace,callback);\r
-// }\r
-// };\r
-//\r
-// var doc = $J(document); //reference to the document\r
-//\r
-// //hide:\r
-// var hide = this.hide;\r
-// this.hide = function(){\r
-// toggleBind(doc);\r
-// };\r
-//\r
-// //remove:\r
-// var me = this;\r
-// var remove = this.remove;\r
-// this.remove = function(){\r
-// me.hide();\r
-// remove.apply(me,arguments);\r
-// };\r
-//\r
-// //show:\r
-// var shadowOffset = 5; //the shadow offset, change to increment/ decrement\r
-// var show = this.show;\r
-//\r
-// this.show = function(){\r
-// place($J(me[0]),event);\r
-// var position = $J(me[0]).offset();\r
-// $J(me[1]).css({\r
-// 'top': (position.top + shadowOffset),\r
-// 'left': (position.left + shadowOffset),\r
-// 'width': div.outerWidth(true),\r
-// 'height': div.outerHeight(true)\r
-// });\r
-// toggleBind(doc, me.hide);\r
-//\r
-// if(arguments.length>0){\r
-// var oldCallback = arguments[arguments.length-1];\r
-// arguments[arguments.length-1] = function(){\r
-// $J(me[1]).fadeTo(0,0.4,oldCallback);\r
-// }\r
-// show.apply(me, arguments);\r
-// }else{\r
-// show.apply(me);\r
-// $J(me[1]).fadeTo(0,0.4);\r
-// }\r
-//\r
-// };\r
-//\r
-//\r
-//\r
-//\r
-//\r
-// _cfg_:{\r
-// jQuery:jQuery,\r
-// div: function(){\r
-// var div = this.jQuery('<div/>').css({ //this is _cfg_\r
-// position: 'absolute',\r
-// overflow:'auto', //necessary to properly display the content\r
-// display: 'none',\r
-// border: '1px solid #e1e1e1',\r
-// zIndex:1000\r
-// });\r
-// if(this.className){\r
-// div.addClass(this.className);\r
-// }\r
-// return div;\r
-// },\r
-// className: 'component',\r
-// // mouseDownNamespace : "mousedown.popup__",\r
-// // keyDownNamespace : "keydown.popup__",\r
-//\r
-// //namespace: 'popup__', //used for namespaces when binding click to document\r
-// handlersToRestore: [],\r
-// event: null,\r
-// divsToDelete:null,\r
-// toggleBind: function(element, functionE){\r
-// var clickNamespace = "click.popup__";\r
-// var keydownNamespace = "keyup.popup__";\r
-// element.unbind(clickNamespace);\r
-// element.unbind(keydownNamespace);\r
-// if(functionE){\r
-// element.bind(clickNamespace, functionE);\r
-// element.bind(keydownNamespace,functionE);\r
-// }\r
-// }\r
-// },\r
-//\r
-// isShowing: function(){\r
-// return this._cfg_.divsToDelete ? true : false;\r
-// },\r
-//\r
-//\r
-// hide: function(){\r
-// var toggleBind = this._cfg_.toggleBind;\r
-//\r
-// var $J = this._cfg_.jQuery;\r
-//\r
-// toggleBind($J(document));\r
-// if(this._cfg_.divsToDelete){\r
-// for(var i=0; i < this._cfg_.divsToDelete.length; i++){\r
-// this._cfg_.divsToDelete[i].empty().remove();\r
-// }\r
-// }\r
-// if(this._cfg_.event && this._cfg_.handlersToRestore){\r
-// var type = this._cfg_.event.type; //which should be the same as h.type below, without namespaces?\r
-// var invokerElement = this._cfg_.event.target;\r
-// if(invokerElement){\r
-// var e = $J(invokerElement);\r
-// toggleBind(e);\r
-// if(type){\r
-// //e.unbind(type);\r
-// for(var i=0; i<this._cfg_.handlersToRestore.length; i++){\r
-// var h = this._cfg_.handlersToRestore[i];\r
-// var functionCode = h.handler;\r
-// var namespace = ""+h.namespace;\r
-// if(namespace.length>0){\r
-// namespace="."+namespace;\r
-// }\r
-// var what = h.type+ namespace;\r
-// e.bind(what, functionCode);\r
-// }\r
-// }\r
-// }\r
-// }\r
-// this._cfg_.event=null;\r
-// this._cfg_.handlersToRestore=null;\r
-// },\r
-//\r
-// show:function(content, optionalEvent){\r
-// consolelog("showing popup:"+optionalEvent);\r
-// //if showing, hide\r
-// if(this.isShowing()){\r
-// this.hide();\r
-// }\r
-//\r
-// var $J = this._cfg_.jQuery;\r
-// var div = this._cfg_.div();\r
-// //toggleBind sets the functions to hiding/keep shown the popup when clicking or\r
-// //using the keyboard keys\r
-// var toggleBind = this._cfg_.toggleBind;\r
-//\r
-// //remove the callback on invoker so that clicking on invoker does nothing\r
-// //moreover, toggleBind on invoker so that clicking invoker doesn't hide the popup\r
-// this.oldCallback = undefined;\r
-// var oldHandlers=[];\r
-// var invokerElement = optionalEvent && optionalEvent.target ? $J(optionalEvent.target) : undefined;\r
-// if(invokerElement){\r
-// optionalEvent.stopPropagation(); //othewrwise the popup hides immediately\r
-// //cause the event is catched from the document click (added later, see below)\r
-// // but apparently as soon as we add it it catches even the current event)\r
-// var type = optionalEvent.type;\r
-// var clickEvents =invokerElement.data("events")[type];\r
-// $J.each(clickEvents, function(key, value) {\r
-// oldHandlers.push(value);\r
-// })\r
-// invokerElement.unbind(type); //remove (temporarily) the binding to the event.\r
-// //for instance, if we show the popup by clicking invoker, when the popup is shown do nothing\r
-// //on clicking invoker until popup.hide is called\r
-// toggleBind(invokerElement,function(e){ //add bindings to stop cancel the popup in case the invoker is clicked again\r
-// e.stopPropagation();\r
-// return false;\r
-// });\r
-// }\r
-// //store the functions removed from invoker, if any, to restore them in this.hide\r
-// this._cfg_.handlersToRestore = oldHandlers;\r
-// this._cfg_.event = optionalEvent;\r
-//\r
-// //toggleBind on each child of content so that clicking and pressing keys on\r
-// //a child doesn't hide the popup\r
-// var children = $J(content).find('*');\r
-// $J(children).each(function(){\r
-// toggleBind($(this),function(e){\r
-// e.stopPropagation();\r
-// return false;\r
-// });\r
-// });\r
-// //showing\r
-// var doc = $J(document);\r
-// $J('body').append(div);\r
-//\r
-// content.css('position','static'); //this is really important to place the content in the normal flow\r
-// //within the div. static is the default\r
-// content.show(); //in case the div is display:none\r
-// div.append(content);\r
-//\r
-// //positioning div: center of the screen if no invoker, below the invoker otherwise\r
-// var wdow = $J(window); //reference the window object (doing it once speeds up a bit performances)\r
-// var windowH = wdow.height();\r
-// var windowW = wdow.width();\r
-// var position = div.offset();\r
-// var shadowOffset=5;\r
-// var size = {\r
-// width:div.outerWidth(true)+shadowOffset,\r
-// height:div.outerHeight(true)+shadowOffset\r
-// };\r
-// if(invokerElement){\r
-// position = invokerElement.offset();\r
-// position.top+= invokerElement.outerHeight(true);\r
-// }else{\r
-// position.top = wdow.scrollTop()+ (windowH-size.height)/2;\r
-// position.left = wdow.scrollLeft()+(windowW-size.width)/2;\r
-// }\r
-// //position div. This must be done immediately cause here below we want to get the div offset\r
-// //(div position in absolute - ie, document's - coordinates)\r
-// div.css({\r
-// 'top': position.top,\r
-// 'left': position.left,\r
-// 'right': 'auto', //in case right has been set by some css class rule\r
-// 'bottom': 'auto' //see above...\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
+// 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 oldShow = p.show;\r
+ // var pint = parseInt;\r
+ p.show = function(){\r
+\r
+ var rect = screenRect();\r
+ var offs = invokerAsJQueryObj.offset();\r
+ var height = invokerAsJQueryObj.outerHeight();\r
+\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
+\r
+ if(spaceAbove>spaceBelow){\r
+ p.css({'maxHeight':(spaceAbove-p.shadowoffset)+'px', 'top':rect.y+'px'});\r
+ }else{\r
+ p.css({'maxHeight':(spaceBelow-p.shadowoffset)+'px', 'top':(offs.top+height)+'px'});\r
+ }\r
+ p.css({'height':'auto','width' :'auto', 'maxWidth': (rect.x+rect.width-offs.left)+'px'});\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
-// //set the maximum size\r
-// //due to overflow:auto a scrollbar will automatically appear\r
-// var max = Math.max; //reference max immediately (speeds up performances a bit)\r
-// var maxSize = {\r
-// width: max(20,windowW + wdow.scrollLeft() -position.left-shadowOffset),\r
-// height: max(20, (windowH + wdow.scrollTop() -position.top- shadowOffset))\r
-// }\r
-// //position div and size:\r
-// var divPadding = {\r
-// left: div.outerWidth()-div.width(),\r
-// top:div.outerHeight()-div.height()\r
-// }; //setting width on a div means the width(),\r
-// //but calculations here are made according to outerWidth(true), so we need this variable (se below)\r
-//\r
-// //the shadow in the background will be created according to the actual div size\r
-// //However, since we do not specify neither width nor height, the calculation of the div size\r
-// //works if maxWidth and maxHeight do set a width and height. In order to do so, they\r
-// //must be lower or equal to the actual div width and height. That's why the "min" here below:'\r
-// div.css({\r
-// 'maxWidth': Math.min(div.width(), maxSize.width-divPadding.left),\r
-// 'maxHeight': Math.min(div.height(), maxSize.height-divPadding.top)\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
+ p.css({\r
+ 'minWidth':invokerAsJQueryObj.outerWidth()+'px',\r
+ 'left':invokerAsJQueryObj.offset().left+'px'\r
+ });\r
+\r
+ p.setPopupFocus(function(){p.hide();});\r
+\r
+ invokerAsJQueryObj.unbind('click').click(function(evt){\r
+ p.show();\r
+ return false;\r
+ });\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
+ * visible window width and height, respectively. Content can be a jQuery object (ie an array of html elements) or a string\r
+ * denoting the innerHTML of the dialog div. timeInMsec can be:\r
+ * a number (in msec) specifying after how much time the dialog will be removed (for fast messages)\r
+ * the string 'hide' to specify that the div will be hidden when it looses focus\r
+ * the string 'remove' to specify that the div will be removed when it looses the focus\r
+ *\r
+ */\r
+ this.showInfoDialog = function(content, timeInMsec){\r
+ var p = new DivDialog(content);\r
+ var oldShow = p.show;\r
+ var pint = parseInt;\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
+\r
+ p.refreshShadowPosition();\r
+\r
+ };\r
+ var rect = screenRect();\r
+ p.css({\r
+ 'maxWidth':pint(rect.width/2)+'px',\r
+ 'maxHeight':pint(rect.height/2)+'px'\r
+ });\r
+ \r
+ if(typeof timeInMsec == 'number'){ //set a timeout\r
+ setTimeout(function(){\r
+ p.remove();\r
+ p=null;\r
+ },timeInMsec);\r
+ }else if(timeInMsec == 'hide'){ //is a boolean\r
+ p.setPopupFocus(function(){p.hide();});\r
+ }else if(timeInMsec == 'remove'){ //is a boolean\r
+ p.setPopupFocus(function(){p.remove();});\r
+ }\r
+ p.show();\r
+ p.setFocus();\r
+ };\r
+}\r
+\r
+//content: string or jQueryElement\r
+//type 'popup',\r
+//DivDialog(content,type,attributes)\r
+\r
+var pppUtils = new PopupUtils();\r
+function DivDialog(content){\r
+ var $J = jQuery;\r
+ var doc = $J(document);\r
+ var firstFocusableElement = undefined; //set in focusout\r
+ var className = 'component';\r
+ var basecss = {\r
+ 'position':'absolute',\r
+ 'display':'none'\r
+ };\r
+ var popup = $J('<div/>').addClass(className).css(basecss).css({\r
+ 'zIndex':1000\r
+ });\r
+ var popupContent = $J('<div/>').css({\r
+ 'overflow':'auto'\r
+ });\r
+ \r
+ var popupshadow = popup.clone(true,true).removeAttr('id').empty().css({\r
+ 'backgroundColor':'#000',\r
+ 'border':'0px',\r
+ 'zIndex':900,\r
+ 'margin':'0px',\r
+ 'padding':'0px'\r
+ }).fadeTo(0,0.4);\r
+ var both = popup.add(popupshadow);\r
+\r
+\r
+ if(content){\r
+ if(content instanceof $J){\r
+ popupContent.empty().append(content);\r
+ }else{\r
+ popupContent.html(content);\r
+ }\r
+ }\r
+ popup.append(popupContent);\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
-// //last thing: if invoker element exist, set width at least invoker element width\r
-// if(invokerElement){\r
-// var iEw = invokerElement.outerWidth(); //no margins considered\r
-// if(iEw<maxSize.width && iEw>div.outerWidth()){\r
-// div.css({\r
-// 'minWidth':iEw-divPadding.left\r
-// });\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
+ };\r
+ this.minsize = function(size){\r
+ popup.css({'minHeight':size.height,'minWidth':size.width});\r
+ };\r
+ this.offset = function(){\r
+ var ret = popup.offset.apply(popup,arguments);\r
+ //refreshPosition();\r
+ return me;\r
+ };\r
+\r
+ //function (private) to refresh shadow position\r
+ this.shadowoffset = 5;\r
+ this.size = function(){\r
+ return {\r
+ width: popup.outerWidth(),\r
+ height:popup.outerHeight()\r
+ };\r
+ };\r
+\r
+\r
+\r
+ this.refreshShadowPosition = function(){\r
+ if(!popup.is(":visible")){\r
+ popupshadow.hide(); //to be sure\r
+ return;\r
+ }else{\r
+ popupshadow.show();\r
+ }\r
+ var offs = popup.offset();\r
+ offs.top+=this.shadowoffset;\r
+ offs.left+=this.shadowoffset;\r
+ popupshadow.offset(offs);\r
+ popupshadow.css({\r
+ 'width':popup.outerWidth()+'px',\r
+ 'height':popup.outerHeight()+'px'\r
+ });\r
+ popupContent.css({\r
+ 'maxWidth': (parseInt(popup.css('maxWidth')) -(popupContent.outerWidth()-popupContent.width())) +'px',\r
+ 'maxHeight':(parseInt(popup.css('maxHeight'))-(popupContent.outerHeight()-popupContent.height()))+'px'\r
+ });\r
+ };\r
+\r
+ //dummy overriding of some jquery functions\r
+ var me = this;\r
+ this.remove = function(){\r
+ both.empty();\r
+ both.remove.apply(both,arguments);\r
+ return me;\r
+ };\r
+ this.find = function(){\r
+ return popupContent.find.apply(popupContent,arguments);\r
+ };\r
+ this.hide = function(){\r
+ return both.hide.apply(both,arguments);\r
+ return me;\r
+ };\r
+ \r
+ this.show = function(){\r
+ if(!(popup.parent().length)){\r
+ $J('body').append(both);\r
+ }\r
+ var ret = popup.show.apply(popup,arguments);\r
+ //refreshPosition();\r
+ return me;\r
+ };\r
+\r
+ this.setFocus = function(){\r
+ if(firstFocusableElement && firstFocusableElement.parent().length && firstFocusableElement.is(':visible')){\r
+ firstFocusableElement.focus();\r
+ }\r
+ }\r
+ //popup specific functions\r
+\r
+ //set css: note that margin position and zIndex will be overridden\r
+ this.css = function(){\r
+ var arg = arguments;\r
+ if(arguments.length==2){ //setting a single css element\r
+ if(arguments[0] == 'margin' || arguments[0] == 'position' || arguments[0] == 'zIndex'){\r
+ return me;\r
+ }\r
+ }else if(arguments.length==1){ //single argument\r
+ if(typeof arguments[0] == 'string'){\r
+ return popup.css(arguments[0]);\r
+ }else{\r
+ var a = arguments[0];\r
+ for(var k in a){\r
+ if(k == 'margin' || k == 'position' || k == 'zIndex'){\r
+ delete a[k];\r
+ }\r
+ }\r
+ arg = [a];\r
+// consolelog('css');\r
+// consolelog(arg);\r
+ }\r
+ }else{\r
+ return me;\r
+ }\r
+ var ret = popup.css.apply(popup,arg);\r
+ //refreshPosition();\r
+ return me;\r
+ };\r
+\r
+\r
+\r
+// this.bindAsPopupFor = function(jQueryAnchorElement){\r
+// if(!jQueryAnchorElement.attr('id')){\r
+// jQueryAnchorElement.attr('id','popup_'+new Date().getTime());\r
// }\r
-// //now we can build the divShadow\r
-// var divShadow = div.clone(false,false).empty().css({'zIndex':999,'borderColor':'#000','display':'none','backgroundColor':'#000'}).insertAfter(div);\r
-// //store the divs to be removed\r
-// this._cfg_.divsToDelete = [div,divShadow];\r
-// //add a listener to the document. If one of the content children is clicked/keypressed,\r
-// //we won't come here. Otherwise hide popup\r
-// var me = this;\r
-// var hide = this.hide;\r
-// toggleBind(doc,function(e){\r
-// hide.apply(me);\r
-// e.stopPropagation();\r
-// });\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
+// var id = jQueryAnchorElement.attr('id');\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
-// if(inputs && inputs[0]){\r
-// inputs[0].focus();\r
-// }else{\r
-// inputs = $J(div).find('a');\r
-// if(inputs && inputs[0]){\r
-// inputs[0].focus();\r
-// }\r
-// }\r
+// anchorElement.click(function(){\r
//\r
-// divShadow.fadeTo(0,0.4, function(){\r
-// divShadow.css({\r
-// 'top': (position.top+shadowOffset),\r
-// 'left': (position.left+shadowOffset),\r
-// 'width': div.outerWidth(true),\r
-// 'height': div.outerHeight(true)\r
-// });\r
-//\r
-// });\r
-// });\r
-// return false; //to avoid scrolling if we clicked on an anchor\r
-// },\r
+// })\r
//\r
-// //field must be a dictionary of label:defaultValues (both strings)\r
-// //callbackOnOk is the callback to be executed on ok, if null ok will simply hide the dialog\r
-// createDivDialog : function(field,callbackOnOk){\r
-//\r
-// var $J = this._cfg_.jQuery;\r
-// var table = $J('<table/>');\r
-// var fieldElms = {};\r
-// for(var label in field){\r
-// var input = $('<input/>')\r
-// .attr('type','text').val(field[label]).attr("name",label);\r
-// table.append($J('<tr/>')\r
-// .append($J('<td/>').html(label))\r
-// .append($J('<td/>').append(input)));\r
-// fieldElms[label]=input;\r
-// }\r
-//\r
-// var p = this;\r
-// var onCancel= function(){\r
-// p.hide();\r
-// return false;\r
-// };\r
-//\r
-// var onOk= function(){\r
-// if(callbackOnOk){\r
-// var ret = {};\r
-// var inputs = table.find("input");\r
-// $J.each(inputs, function(key,value){\r
-// var v = $J(value);\r
-// ret[v.attr('name')] = v.val();\r
-// });\r
-// callbackOnOk(ret);\r
-// return false;\r
-// }else{\r
-// return onCancel();\r
-// }\r
-// };\r
-// var subdiv = $J('<div/>').css({\r
-// 'padding':'1ex',\r
-// 'float':'right'\r
-// }).\r
-// append(\r
-// $J('<a/>').\r
-// html('Ok').\r
-// addClass('component_icon').\r
-// addClass('button').\r
-// addClass('icon_ok').\r
-// attr('href','#').\r
-// click(function(){\r
-// return onOk();\r
-// })\r
-// );\r
-// if(callbackOnOk){\r
-// subdiv.append(\r
-// $J('<a/>').\r
-// html('Cancel').\r
-// addClass('component_icon').\r
-// addClass('button').\r
-// addClass('icon_cancel').\r
-// attr('href','#').\r
-// click(function(){\r
-// return onCancel();\r
-// })\r
-// );\r
-// }\r
-// //popupDialog(element,table,onOk);\r
-// return $J('<div/>').append(table).append(subdiv);\r
// }\r
-//}
\ No newline at end of file
+ \r
+ this.setPopupFocus = function(callbackOnFocusLost){\r
+ \r
+ //find all foccusable elements\r
+ var elementsWithFocus = $J(popupContent).find('textarea,a,input');\r
+ //focus must be given also to the containing popup beacuse\r
+ //if a scrollbar is present, moving the scrollbar sets the focus to popup (not popupContent. So\r
+ //apparently even if the scrollbar is caused by css 'popupContent.scroll=auto', it's like if it was\r
+ //'part' of the parent container popup)\r
+ //TODO: TEST IT WITH OTHER BROWSERS!!!! if not working, manda tutto affanculo and use click events\r
+ popup.attr('tabindex',1);\r
+ elementsWithFocus = elementsWithFocus.add(popup);\r
+ //build the attribute focus to recognize subelement of popup\r
+ var focusid = 'popupfocus'+(new Date().getTime());\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.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 = document.activeElement;\r
+ consolelog(v);\r
+ if(v && $J(v).attr(focusid)){\r
+ return;\r
+ }\r
+ callbackOnFocusLost();\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
+ //set the first focusable element\r
+ firstFocusableElement = $J(elementsWithFocus[0]);\r
+ };\r
+ \r
+ this.attr = function(){\r
+ var ret = popup.attr.apply(popup,arguments);\r
+ //refreshPosition();\r
+ return me;\r
+ };\r
+ this.html = function(){\r
+ if(arguments.length==0){\r
+ return popupContent.html();\r
+ }\r
+ var ret = popupContent.html.apply(popup,arguments);\r
+ //refreshPosition();\r
+ return me;\r
+ }\r
+ this.append = function(){\r
+ var ret = popupContent.append.apply(popup,arguments);\r
+ //refreshPosition();\r
+ return me;\r
+ }\r
+}\r
+\r
+\r