You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Andrew Robinson (JIRA)" <de...@myfaces.apache.org> on 2007/09/02 06:51:19 UTC

[jira] Commented: (TRINIDAD-673) tr:panelPopup positions itself with regards to the document body, not the offset parent

    [ https://issues.apache.org/jira/browse/TRINIDAD-673?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12524319 ] 

Andrew Robinson commented on TRINIDAD-673:
------------------------------------------

I have extended prototype.js even further. Some of my extensions are in this code. Here are the major ones:

Functions on every HTML Element:

  getPagePosition: function(element)
  {
    var curleft = 0;
    var curtop = 0;
    var obj = element;
    while (obj)
    {
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
    return { x: curleft, y: curtop };
  },
  centerOnScreen: function(elem)
  {
    elem = $(elem);
    
    elem.style.position = 'absolute';
    var vis = elem.getStyle('visibility');
    elem.style.visibility = 'hidden';
    
    var loc;
    if (Globals.isInternetExplorer())
    {
      loc = document.body.scrollLeft +
        ((document.body.clientWidth - elem.clientWidth) / 2);
      elem.style.left = loc + "px";
      loc = document.body.scrollTop +
        ((document.body.clientHeight - elem.clientHeight) / 2);
      elem.style.top = loc + "px";
    }
    else
    {
      loc = window.pageXOffset + ((window.innerWidth - elem.clientWidth) / 2)
      elem.style.left = loc + "px"
      loc = window.pageYOffset + ((window.innerHeight - elem.clientHeight)/2);
      elem.style.top= loc + "px"
    }
    elem.style.visibility = vis;
  },
  hitTest: function(elem, x, y)
  {
    var pos = $(elem).getPagePosition();
    if (pos.x > x || pos.y > y)
    {
      return false;
    }
    return pos.x + elem.offsetWidth >= x &&
      pos.y + elem.offsetHeight >= y;
  },
  fitOnScreen: function(elem)
  {
    elem = $(elem);
    var vis = elem.getStyle('visibility');
    elem.style.visibility = 'hidden';
    if (elem.origX)
    {
      elem.style.left = elem.origX + 'px';
    }
    if (elem.origY)
    {
      elem.style.top = elem.origY + 'px';
    }
    var w = elem.offsetWidth;
    var h = elem.offsetHeight;
    var pos = elem.getPagePosition();
    var x = pos.x;
    var y = pos.y;
    var ww = document.body.offsetWidth;
    var wh = document.body.offsetHeight;
    if (x + w > ww)
    {
      var diff = (x + w) - ww;
      var ox = elem.offsetLeft;
      if (!elem.origX)
      {
        elem.origX = ox;
      }
      elem.style.left = (ox - diff) + 'px';
    }
    if (y + h > wh)
    {
      var diff = (y + h) - wh;
      var oy = elem.offsetTop;
      if (!elem.origY)
      {
        elem.origY = oy;
      }
      elem.style.top = (oy - diff) + 'px';
    }
    elem.style.visibility = vis;
  }


Function on the Event:

  getPosition: function(evt)
  {
    var locx = Event.pointerX(evt);
    var locy = Event.pointerY(evt);
    return { x: locx, y: locy };
  }



> tr:panelPopup positions itself with regards to the document body, not the offset parent
> ---------------------------------------------------------------------------------------
>
>                 Key: TRINIDAD-673
>                 URL: https://issues.apache.org/jira/browse/TRINIDAD-673
>             Project: MyFaces Trinidad
>          Issue Type: Bug
>          Components: Components
>    Affects Versions: 1.0.2-core
>            Reporter: Andrew Robinson
>         Attachments: popup.js
>
>
> I have been working for a large part of the day on my own renderer of the tr:panelPopup as the core one unfortunately doesn't work for my needs. The problem is that the PanelPopup.js assumes that the panel's offsetParent is the document.body/window. With CSS styling, this is very rarely the case. As a result a tr:panelPopup inside of a relative or absolute HTML element will not be rendered in the correct location on the screen. 
> Furthermore, the panel is often not visible if the parent's overflow is hidden. 
> Proposed solution:
> The best way to ensure that the popup is positioned correctly is to have all measurements made using absolute (page) co-ordinates. Also, it is imperative to have the popup inside a container that is not cropped or scrolling in any way to ensure the dialog stays visible. 
> Steps:
> 1) When the popup is shown, move it to the parent FORM element (use the form to ensure that form elements inside the popup do not break)
> 2) if the popup is not in a form, then relocate the popup to the document.body
> 3) have event listeners on the popup and the trigger.
> 4) in the mouse out, check to see if the events X and Y co-ordinates fall in the page X and page Y co-ordinates of either the trigger or the popup. If the event is outside both sets of co-ordinates, hide the popup
> 5) when hiding the popup, move it back to it's original parent
> Technical notes:
> - to determine absolute co-ordinates relative to the page, one must loop through all the parent nodes, checking offsetTop and offsetLeft until the offsetParent is null

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.