[FlexJS] Finding (x,y) position

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

[FlexJS] Finding (x,y) position

Peter Ent-2
Hi,

While working on drag-and-drop, I've made an "interesting" discovery having to do with the HTML-side's x and y getter functions.

Let's say you have a nesting of <div>s:

<div style="position:relative" id="outer">
   <div id="header" style="height:30px">…</div>
    <div id="wrapper">
        <div id="inner">
             <div class="ItemRenderer" id="first">…</div>
        </div>
    </div>
</div>

(this structure is similar to what is generated for DataGrid).

If you attempt to get the y location of "first" itemRenderer, you will get 30 back as the answer. That happens because the y getter first looks to see if the object has a "top" style value and, finding none, returns its offsetTop. In this case, offsetTop is 30 and offsetParent is "outer". If you get the y value of "inner" you will also get 30 as the answer for the same reason.

If each of the <div>s had position:relative (or absolute), then offsetTop would be as you would expect with each offsetParent being the <div> above it.

Our layout functions (and x and y setters) do not normally set the position style on element. I removed this a good while ago. Now I am trying to place a drop target indicator and to do that I need accurate (x,y) locations.

I have a couple of solutions:


  1.  For any element, look at its getBoundingClientRect and compare with its elementParent.getBoundingClientRect. The difference between then gives the child's position relative to the parent. This seems reliable.
  2.  Attempt to divine a child's position using the offset information. I can't make this work.
  3.  Modify the layouts to check the contentView's value of position and if not set already, set it to "relative". This makes the x and y getters return the right thing but may have unintended consequences.

Any advice from seasoned JavaScript developers is greatly appreciated!

Thanks,
Peter

Reply | Threaded
Open this post in threaded view
|

RE: [FlexJS] Finding (x,y) position

yishayw
Peter,

Is PointUtils.localToGlobal() not working for you? From what I understand it takes approach (1).

From: Peter Ent<mailto:[hidden email]>
Sent: Tuesday, August 29, 2017 11:29 PM
To: [hidden email]<mailto:[hidden email]>
Subject: [FlexJS] Finding (x,y) position

Hi,

While working on drag-and-drop, I've made an "interesting" discovery having to do with the HTML-side's x and y getter functions.

Let's say you have a nesting of <div>s:

<div style="position:relative" id="outer">
   <div id="header" style="height:30px">…</div>
    <div id="wrapper">
        <div id="inner">
             <div class="ItemRenderer" id="first">…</div>
        </div>
    </div>
</div>

(this structure is similar to what is generated for DataGrid).

If you attempt to get the y location of "first" itemRenderer, you will get 30 back as the answer. That happens because the y getter first looks to see if the object has a "top" style value and, finding none, returns its offsetTop. In this case, offsetTop is 30 and offsetParent is "outer". If you get the y value of "inner" you will also get 30 as the answer for the same reason.

If each of the <div>s had position:relative (or absolute), then offsetTop would be as you would expect with each offsetParent being the <div> above it.

Our layout functions (and x and y setters) do not normally set the position style on element. I removed this a good while ago. Now I am trying to place a drop target indicator and to do that I need accurate (x,y) locations.

I have a couple of solutions:


  1.  For any element, look at its getBoundingClientRect and compare with its elementParent.getBoundingClientRect. The difference between then gives the child's position relative to the parent. This seems reliable.
  2.  Attempt to divine a child's position using the offset information. I can't make this work.
  3.  Modify the layouts to check the contentView's value of position and if not set already, set it to "relative". This makes the x and y getters return the right thing but may have unintended consequences.

Any advice from seasoned JavaScript developers is greatly appreciated!

Thanks,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: [FlexJS] Finding (x,y) position

Peter Ent-2
PointUtils works when it has the correct data. For example, if you are
over an itemRenderer, say the first one, and want to get its global
location, you might do:

var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)

and use pt0 in PointUtils.localToGlobal function. The problem is,
itemRenderer.x/y are not correct at all times. Because this itemRenderer
is the first itemRenderer and in the upper-left corner of its List, you
would expect it to be (0,0) but instead it is (0,30) for example where 30
is the height of the ButtonBar used for the header.

Further, the itemRenderer's parent, a <div>, also has location (0,30) and
its parent, again a <div> is (0,30).

This happens because the layout used to place everything is just relying
on display:block and none of the <div>s have position set to anything; the
only <div> with position is the one representing the DataGrid itself.

The .x and .y functions look at the "left" and "top" styles first. Finding
these are not set, the functions then return offsetLeft and offsetTop,
which are the offsets from the ancestor with position set. That's the
<div> for the DataGrid. Hence they are at (0,30).

I see two choices: use getClientBoundingRect or change the layouts to set
position:relative on their contentView but this might break something else
at some point.

I was wondering if anyone had experience trying to figure out screen
positions when using the offset properties.


‹peter

On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:

>Peter,
>
>Is PointUtils.localToGlobal() not working for you? From what I understand
>it takes approach (1).
>
>From: Peter Ent<mailto:[hidden email]>
>Sent: Tuesday, August 29, 2017 11:29 PM
>To: [hidden email]<mailto:[hidden email]>
>Subject: [FlexJS] Finding (x,y) position
>
>Hi,
>
>While working on drag-and-drop, I've made an "interesting" discovery
>having to do with the HTML-side's x and y getter functions.
>
>Let's say you have a nesting of <div>s:
>
><div style="position:relative" id="outer">
>   <div id="header" style="height:30px">Š</div>
>    <div id="wrapper">
>        <div id="inner">
>             <div class="ItemRenderer" id="first">Š</div>
>        </div>
>    </div>
></div>
>
>(this structure is similar to what is generated for DataGrid).
>
>If you attempt to get the y location of "first" itemRenderer, you will
>get 30 back as the answer. That happens because the y getter first looks
>to see if the object has a "top" style value and, finding none, returns
>its offsetTop. In this case, offsetTop is 30 and offsetParent is "outer".
>If you get the y value of "inner" you will also get 30 as the answer for
>the same reason.
>
>If each of the <div>s had position:relative (or absolute), then offsetTop
>would be as you would expect with each offsetParent being the <div> above
>it.
>
>Our layout functions (and x and y setters) do not normally set the
>position style on element. I removed this a good while ago. Now I am
>trying to place a drop target indicator and to do that I need accurate
>(x,y) locations.
>
>I have a couple of solutions:
>
>
>  1.  For any element, look at its getBoundingClientRect and compare with
>its elementParent.getBoundingClientRect. The difference between then
>gives the child's position relative to the parent. This seems reliable.
>  2.  Attempt to divine a child's position using the offset information.
>I can't make this work.
>  3.  Modify the layouts to check the contentView's value of position and
>if not set already, set it to "relative". This makes the x and y getters
>return the right thing but may have unintended consequences.
>
>Any advice from seasoned JavaScript developers is greatly appreciated!
>
>Thanks,
>Peter
>

Reply | Threaded
Open this post in threaded view
|

RE: [FlexJS] Finding (x,y) position

yishayw
I see what you’re saying. I think we worked around that issue in our app by relying on MouseEvent.clientX, MouseEvent.clientY. But let’s hear other ideas for a more complete solution.

From: Peter Ent<mailto:[hidden email]>
Sent: Wednesday, August 30, 2017 4:48 PM
To: [hidden email]<mailto:[hidden email]>
Subject: Re: [FlexJS] Finding (x,y) position

PointUtils works when it has the correct data. For example, if you are
over an itemRenderer, say the first one, and want to get its global
location, you might do:

var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)

and use pt0 in PointUtils.localToGlobal function. The problem is,
itemRenderer.x/y are not correct at all times. Because this itemRenderer
is the first itemRenderer and in the upper-left corner of its List, you
would expect it to be (0,0) but instead it is (0,30) for example where 30
is the height of the ButtonBar used for the header.

Further, the itemRenderer's parent, a <div>, also has location (0,30) and
its parent, again a <div> is (0,30).

This happens because the layout used to place everything is just relying
on display:block and none of the <div>s have position set to anything; the
only <div> with position is the one representing the DataGrid itself.

The .x and .y functions look at the "left" and "top" styles first. Finding
these are not set, the functions then return offsetLeft and offsetTop,
which are the offsets from the ancestor with position set. That's the
<div> for the DataGrid. Hence they are at (0,30).

I see two choices: use getClientBoundingRect or change the layouts to set
position:relative on their contentView but this might break something else
at some point.

I was wondering if anyone had experience trying to figure out screen
positions when using the offset properties.


‹peter

On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:

>Peter,
>
>Is PointUtils.localToGlobal() not working for you? From what I understand
>it takes approach (1).
>
>From: Peter Ent<mailto:[hidden email]>
>Sent: Tuesday, August 29, 2017 11:29 PM
>To: [hidden email]<mailto:[hidden email]>
>Subject: [FlexJS] Finding (x,y) position
>
>Hi,
>
>While working on drag-and-drop, I've made an "interesting" discovery
>having to do with the HTML-side's x and y getter functions.
>
>Let's say you have a nesting of <div>s:
>
><div style="position:relative" id="outer">
>   <div id="header" style="height:30px">Š</div>
>    <div id="wrapper">
>        <div id="inner">
>             <div class="ItemRenderer" id="first">Š</div>
>        </div>
>    </div>
></div>
>
>(this structure is similar to what is generated for DataGrid).
>
>If you attempt to get the y location of "first" itemRenderer, you will
>get 30 back as the answer. That happens because the y getter first looks
>to see if the object has a "top" style value and, finding none, returns
>its offsetTop. In this case, offsetTop is 30 and offsetParent is "outer".
>If you get the y value of "inner" you will also get 30 as the answer for
>the same reason.
>
>If each of the <div>s had position:relative (or absolute), then offsetTop
>would be as you would expect with each offsetParent being the <div> above
>it.
>
>Our layout functions (and x and y setters) do not normally set the
>position style on element. I removed this a good while ago. Now I am
>trying to place a drop target indicator and to do that I need accurate
>(x,y) locations.
>
>I have a couple of solutions:
>
>
>  1.  For any element, look at its getBoundingClientRect and compare with
>its elementParent.getBoundingClientRect. The difference between then
>gives the child's position relative to the parent. This seems reliable.
>  2.  Attempt to divine a child's position using the offset information.
>I can't make this work.
>  3.  Modify the layouts to check the contentView's value of position and
>if not set already, set it to "relative". This makes the x and y getters
>return the right thing but may have unintended consequences.
>
>Any advice from seasoned JavaScript developers is greatly appreciated!
>
>Thanks,
>Peter
>

Reply | Threaded
Open this post in threaded view
|

RE: [FlexJS] Finding (x,y) position

yishayw
Strike that. I don’t see what you’re saying. Why not just use 0,0? Why do you need x,y? Or you could add w/2, h/2 if you want to center the drop target.

Looking at PointUtils.localToGlobal() it just calls element.getBoundingClientRect() (as you suggested) and adds the given x,y to the result.

From: Yishay Weiss<mailto:[hidden email]>
Sent: Wednesday, August 30, 2017 5:11 PM
To: [hidden email]<mailto:[hidden email]>
Subject: RE: [FlexJS] Finding (x,y) position

I see what you’re saying. I think we worked around that issue in our app by relying on MouseEvent.clientX, MouseEvent.clientY. But let’s hear other ideas for a more complete solution.

From: Peter Ent<mailto:[hidden email]>
Sent: Wednesday, August 30, 2017 4:48 PM
To: [hidden email]<mailto:[hidden email]>
Subject: Re: [FlexJS] Finding (x,y) position

PointUtils works when it has the correct data. For example, if you are
over an itemRenderer, say the first one, and want to get its global
location, you might do:

var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)

and use pt0 in PointUtils.localToGlobal function. The problem is,
itemRenderer.x/y are not correct at all times. Because this itemRenderer
is the first itemRenderer and in the upper-left corner of its List, you
would expect it to be (0,0) but instead it is (0,30) for example where 30
is the height of the ButtonBar used for the header.

Further, the itemRenderer's parent, a <div>, also has location (0,30) and
its parent, again a <div> is (0,30).

This happens because the layout used to place everything is just relying
on display:block and none of the <div>s have position set to anything; the
only <div> with position is the one representing the DataGrid itself.

The .x and .y functions look at the "left" and "top" styles first. Finding
these are not set, the functions then return offsetLeft and offsetTop,
which are the offsets from the ancestor with position set. That's the
<div> for the DataGrid. Hence they are at (0,30).

I see two choices: use getClientBoundingRect or change the layouts to set
position:relative on their contentView but this might break something else
at some point.

I was wondering if anyone had experience trying to figure out screen
positions when using the offset properties.


‹peter

On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:

>Peter,
>
>Is PointUtils.localToGlobal() not working for you? From what I understand
>it takes approach (1).
>
>From: Peter Ent<mailto:[hidden email]>
>Sent: Tuesday, August 29, 2017 11:29 PM
>To: [hidden email]<mailto:[hidden email]>
>Subject: [FlexJS] Finding (x,y) position
>
>Hi,
>
>While working on drag-and-drop, I've made an "interesting" discovery
>having to do with the HTML-side's x and y getter functions.
>
>Let's say you have a nesting of <div>s:
>
><div style="position:relative" id="outer">
>   <div id="header" style="height:30px">Š</div>
>    <div id="wrapper">
>        <div id="inner">
>             <div class="ItemRenderer" id="first">Š</div>
>        </div>
>    </div>
></div>
>
>(this structure is similar to what is generated for DataGrid).
>
>If you attempt to get the y location of "first" itemRenderer, you will
>get 30 back as the answer. That happens because the y getter first looks
>to see if the object has a "top" style value and, finding none, returns
>its offsetTop. In this case, offsetTop is 30 and offsetParent is "outer".
>If you get the y value of "inner" you will also get 30 as the answer for
>the same reason.
>
>If each of the <div>s had position:relative (or absolute), then offsetTop
>would be as you would expect with each offsetParent being the <div> above
>it.
>
>Our layout functions (and x and y setters) do not normally set the
>position style on element. I removed this a good while ago. Now I am
>trying to place a drop target indicator and to do that I need accurate
>(x,y) locations.
>
>I have a couple of solutions:
>
>
>  1.  For any element, look at its getBoundingClientRect and compare with
>its elementParent.getBoundingClientRect. The difference between then
>gives the child's position relative to the parent. This seems reliable.
>  2.  Attempt to divine a child's position using the offset information.
>I can't make this work.
>  3.  Modify the layouts to check the contentView's value of position and
>if not set already, set it to "relative". This makes the x and y getters
>return the right thing but may have unintended consequences.
>
>Any advice from seasoned JavaScript developers is greatly appreciated!
>
>Thanks,
>Peter
>

Reply | Threaded
Open this post in threaded view
|

Re: [FlexJS] Finding (x,y) position

Peter Ent-2
I'm trying to draw a drop indicator above the row in the DataGrid where
new data would be inserted if the user releases the mouse button at that
point.

The drop indicator is being drawn in a layer (added by a new bead) that is
floating above the <div> containing the DataGrid's column lists.

As the mouse is detected over an itemRenderer, I need to know the
itemRenderer's position within its list so I can translate that into
global space and then into the space of the layer.

However, what you just wrote gave me another idea that might just work.

Thanks!
—peter

On 8/30/17, 10:30 AM, "Yishay Weiss" <[hidden email]> wrote:

>Strike that. I don’t see what you’re saying. Why not just use 0,0? Why do
>you need x,y? Or you could add w/2, h/2 if you want to center the drop
>target.
>
>Looking at PointUtils.localToGlobal() it just calls
>element.getBoundingClientRect() (as you suggested) and adds the given x,y
>to the result.
>
>From: Yishay Weiss<mailto:[hidden email]>
>Sent: Wednesday, August 30, 2017 5:11 PM
>To: [hidden email]<mailto:[hidden email]>
>Subject: RE: [FlexJS] Finding (x,y) position
>
>I see what you’re saying. I think we worked around that issue in our app
>by relying on MouseEvent.clientX, MouseEvent.clientY. But let’s hear
>other ideas for a more complete solution.
>
>From: Peter Ent<mailto:[hidden email]>
>Sent: Wednesday, August 30, 2017 4:48 PM
>To: [hidden email]<mailto:[hidden email]>
>Subject: Re: [FlexJS] Finding (x,y) position
>
>PointUtils works when it has the correct data. For example, if you are
>over an itemRenderer, say the first one, and want to get its global
>location, you might do:
>
>var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)
>
>and use pt0 in PointUtils.localToGlobal function. The problem is,
>itemRenderer.x/y are not correct at all times. Because this itemRenderer
>is the first itemRenderer and in the upper-left corner of its List, you
>would expect it to be (0,0) but instead it is (0,30) for example where 30
>is the height of the ButtonBar used for the header.
>
>Further, the itemRenderer's parent, a <div>, also has location (0,30) and
>its parent, again a <div> is (0,30).
>
>This happens because the layout used to place everything is just relying
>on display:block and none of the <div>s have position set to anything; the
>only <div> with position is the one representing the DataGrid itself.
>
>The .x and .y functions look at the "left" and "top" styles first. Finding
>these are not set, the functions then return offsetLeft and offsetTop,
>which are the offsets from the ancestor with position set. That's the
><div> for the DataGrid. Hence they are at (0,30).
>
>I see two choices: use getClientBoundingRect or change the layouts to set
>position:relative on their contentView but this might break something else
>at some point.
>
>I was wondering if anyone had experience trying to figure out screen
>positions when using the offset properties.
>
>
>‹peter
>
>On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:
>
>>Peter,
>>
>>Is PointUtils.localToGlobal() not working for you? From what I understand
>>it takes approach (1).
>>
>>From: Peter Ent<mailto:[hidden email]>
>>Sent: Tuesday, August 29, 2017 11:29 PM
>>To: [hidden email]<mailto:[hidden email]>
>>Subject: [FlexJS] Finding (x,y) position
>>
>>Hi,
>>
>>While working on drag-and-drop, I've made an "interesting" discovery
>>having to do with the HTML-side's x and y getter functions.
>>
>>Let's say you have a nesting of <div>s:
>>
>><div style="position:relative" id="outer">
>>   <div id="header" style="height:30px">Š</div>
>>    <div id="wrapper">
>>        <div id="inner">
>>             <div class="ItemRenderer" id="first">Š</div>
>>        </div>
>>    </div>
>></div>
>>
>>(this structure is similar to what is generated for DataGrid).
>>
>>If you attempt to get the y location of "first" itemRenderer, you will
>>get 30 back as the answer. That happens because the y getter first looks
>>to see if the object has a "top" style value and, finding none, returns
>>its offsetTop. In this case, offsetTop is 30 and offsetParent is "outer".
>>If you get the y value of "inner" you will also get 30 as the answer for
>>the same reason.
>>
>>If each of the <div>s had position:relative (or absolute), then offsetTop
>>would be as you would expect with each offsetParent being the <div> above
>>it.
>>
>>Our layout functions (and x and y setters) do not normally set the
>>position style on element. I removed this a good while ago. Now I am
>>trying to place a drop target indicator and to do that I need accurate
>>(x,y) locations.
>>
>>I have a couple of solutions:
>>
>>
>>  1.  For any element, look at its getBoundingClientRect and compare with
>>its elementParent.getBoundingClientRect. The difference between then
>>gives the child's position relative to the parent. This seems reliable.
>>  2.  Attempt to divine a child's position using the offset information.
>>I can't make this work.
>>  3.  Modify the layouts to check the contentView's value of position and
>>if not set already, set it to "relative". This makes the x and y getters
>>return the right thing but may have unintended consequences.
>>
>>Any advice from seasoned JavaScript developers is greatly appreciated!
>>
>>Thanks,
>>Peter
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: [FlexJS] Finding (x,y) position

Alex Harui-2
Hopefully Peter will find a solution based on your input.  But I think a
problem still exists.

The basic problem is how to find the x,y position of a child within its
parent.  I believe Peter is saying that the x and y getters in UIBase are
not reporting correct values in many cases in the browser.  Apparently,
you can ask for the child.x and child.y of a child that is visibly not at
0,0 in its parent and you will get 0.  I think we haven't noticed that
because nobody currently cares, but it kinds of bugs me that something
that "basic" doesn't do the right thing all of the time.

Thoughts?
-Alex


On 8/30/17, 7:53 AM, "Peter Ent" <[hidden email]> wrote:

>I'm trying to draw a drop indicator above the row in the DataGrid where
>new data would be inserted if the user releases the mouse button at that
>point.
>
>The drop indicator is being drawn in a layer (added by a new bead) that is
>floating above the <div> containing the DataGrid's column lists.
>
>As the mouse is detected over an itemRenderer, I need to know the
>itemRenderer's position within its list so I can translate that into
>global space and then into the space of the layer.
>
>However, what you just wrote gave me another idea that might just work.
>
>Thanks!
>—peter
>
>On 8/30/17, 10:30 AM, "Yishay Weiss" <[hidden email]> wrote:
>
>>Strike that. I don’t see what you’re saying. Why not just use 0,0? Why do
>>you need x,y? Or you could add w/2, h/2 if you want to center the drop
>>target.
>>
>>Looking at PointUtils.localToGlobal() it just calls
>>element.getBoundingClientRect() (as you suggested) and adds the given x,y
>>to the result.
>>
>>From: Yishay Weiss<mailto:[hidden email]>
>>Sent: Wednesday, August 30, 2017 5:11 PM
>>To: [hidden email]<mailto:[hidden email]>
>>Subject: RE: [FlexJS] Finding (x,y) position
>>
>>I see what you’re saying. I think we worked around that issue in our app
>>by relying on MouseEvent.clientX, MouseEvent.clientY. But let’s hear
>>other ideas for a more complete solution.
>>
>>From: Peter Ent<mailto:[hidden email]>
>>Sent: Wednesday, August 30, 2017 4:48 PM
>>To: [hidden email]<mailto:[hidden email]>
>>Subject: Re: [FlexJS] Finding (x,y) position
>>
>>PointUtils works when it has the correct data. For example, if you are
>>over an itemRenderer, say the first one, and want to get its global
>>location, you might do:
>>
>>var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)
>>
>>and use pt0 in PointUtils.localToGlobal function. The problem is,
>>itemRenderer.x/y are not correct at all times. Because this itemRenderer
>>is the first itemRenderer and in the upper-left corner of its List, you
>>would expect it to be (0,0) but instead it is (0,30) for example where 30
>>is the height of the ButtonBar used for the header.
>>
>>Further, the itemRenderer's parent, a <div>, also has location (0,30) and
>>its parent, again a <div> is (0,30).
>>
>>This happens because the layout used to place everything is just relying
>>on display:block and none of the <div>s have position set to anything;
>>the
>>only <div> with position is the one representing the DataGrid itself.
>>
>>The .x and .y functions look at the "left" and "top" styles first.
>>Finding
>>these are not set, the functions then return offsetLeft and offsetTop,
>>which are the offsets from the ancestor with position set. That's the
>><div> for the DataGrid. Hence they are at (0,30).
>>
>>I see two choices: use getClientBoundingRect or change the layouts to set
>>position:relative on their contentView but this might break something
>>else
>>at some point.
>>
>>I was wondering if anyone had experience trying to figure out screen
>>positions when using the offset properties.
>>
>>
>>‹peter
>>
>>On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:
>>
>>>Peter,
>>>
>>>Is PointUtils.localToGlobal() not working for you? From what I
>>>understand
>>>it takes approach (1).
>>>
>>>From: Peter Ent<mailto:[hidden email]>
>>>Sent: Tuesday, August 29, 2017 11:29 PM
>>>To: [hidden email]<mailto:[hidden email]>
>>>Subject: [FlexJS] Finding (x,y) position
>>>
>>>Hi,
>>>
>>>While working on drag-and-drop, I've made an "interesting" discovery
>>>having to do with the HTML-side's x and y getter functions.
>>>
>>>Let's say you have a nesting of <div>s:
>>>
>>><div style="position:relative" id="outer">
>>>   <div id="header" style="height:30px">Š</div>
>>>    <div id="wrapper">
>>>        <div id="inner">
>>>             <div class="ItemRenderer" id="first">Š</div>
>>>        </div>
>>>    </div>
>>></div>
>>>
>>>(this structure is similar to what is generated for DataGrid).
>>>
>>>If you attempt to get the y location of "first" itemRenderer, you will
>>>get 30 back as the answer. That happens because the y getter first looks
>>>to see if the object has a "top" style value and, finding none, returns
>>>its offsetTop. In this case, offsetTop is 30 and offsetParent is
>>>"outer".
>>>If you get the y value of "inner" you will also get 30 as the answer for
>>>the same reason.
>>>
>>>If each of the <div>s had position:relative (or absolute), then
>>>offsetTop
>>>would be as you would expect with each offsetParent being the <div>
>>>above
>>>it.
>>>
>>>Our layout functions (and x and y setters) do not normally set the
>>>position style on element. I removed this a good while ago. Now I am
>>>trying to place a drop target indicator and to do that I need accurate
>>>(x,y) locations.
>>>
>>>I have a couple of solutions:
>>>
>>>
>>>  1.  For any element, look at its getBoundingClientRect and compare
>>>with
>>>its elementParent.getBoundingClientRect. The difference between then
>>>gives the child's position relative to the parent. This seems reliable.
>>>  2.  Attempt to divine a child's position using the offset information.
>>>I can't make this work.
>>>  3.  Modify the layouts to check the contentView's value of position
>>>and
>>>if not set already, set it to "relative". This makes the x and y getters
>>>return the right thing but may have unintended consequences.
>>>
>>>Any advice from seasoned JavaScript developers is greatly appreciated!
>>>
>>>Thanks,
>>>Peter
>>>
>>
>

Reply | Threaded
Open this post in threaded view
|

RE: [FlexJS] Finding (x,y) position

yishayw
This [1] discussion touches on it.

A PAYG approach might be to add PointUtils.getPositionInParent(uibase:UIBase) which would do the same thing PointUtils.localToGlobal() for element and parent and output the difference.

[1] http://apache-flex-development.2333347.n4.nabble.com/FlexJS-Layouts-td61120.html#a61330

From: Alex Harui<mailto:[hidden email]>
Sent: Wednesday, August 30, 2017 7:02 PM
To: [hidden email]<mailto:[hidden email]>
Subject: Re: [FlexJS] Finding (x,y) position

Hopefully Peter will find a solution based on your input.  But I think a
problem still exists.

The basic problem is how to find the x,y position of a child within its
parent.  I believe Peter is saying that the x and y getters in UIBase are
not reporting correct values in many cases in the browser.  Apparently,
you can ask for the child.x and child.y of a child that is visibly not at
0,0 in its parent and you will get 0.  I think we haven't noticed that
because nobody currently cares, but it kinds of bugs me that something
that "basic" doesn't do the right thing all of the time.

Thoughts?
-Alex


On 8/30/17, 7:53 AM, "Peter Ent" <[hidden email]> wrote:

>I'm trying to draw a drop indicator above the row in the DataGrid where
>new data would be inserted if the user releases the mouse button at that
>point.
>
>The drop indicator is being drawn in a layer (added by a new bead) that is
>floating above the <div> containing the DataGrid's column lists.
>
>As the mouse is detected over an itemRenderer, I need to know the
>itemRenderer's position within its list so I can translate that into
>global space and then into the space of the layer.
>
>However, what you just wrote gave me another idea that might just work.
>
>Thanks!
>—peter
>
>On 8/30/17, 10:30 AM, "Yishay Weiss" <[hidden email]> wrote:
>
>>Strike that. I don’t see what you’re saying. Why not just use 0,0? Why do
>>you need x,y? Or you could add w/2, h/2 if you want to center the drop
>>target.
>>
>>Looking at PointUtils.localToGlobal() it just calls
>>element.getBoundingClientRect() (as you suggested) and adds the given x,y
>>to the result.
>>
>>From: Yishay Weiss<mailto:[hidden email]>
>>Sent: Wednesday, August 30, 2017 5:11 PM
>>To: [hidden email]<mailto:[hidden email]>
>>Subject: RE: [FlexJS] Finding (x,y) position
>>
>>I see what you’re saying. I think we worked around that issue in our app
>>by relying on MouseEvent.clientX, MouseEvent.clientY. But let’s hear
>>other ideas for a more complete solution.
>>
>>From: Peter Ent<mailto:[hidden email]>
>>Sent: Wednesday, August 30, 2017 4:48 PM
>>To: [hidden email]<mailto:[hidden email]>
>>Subject: Re: [FlexJS] Finding (x,y) position
>>
>>PointUtils works when it has the correct data. For example, if you are
>>over an itemRenderer, say the first one, and want to get its global
>>location, you might do:
>>
>>var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)
>>
>>and use pt0 in PointUtils.localToGlobal function. The problem is,
>>itemRenderer.x/y are not correct at all times. Because this itemRenderer
>>is the first itemRenderer and in the upper-left corner of its List, you
>>would expect it to be (0,0) but instead it is (0,30) for example where 30
>>is the height of the ButtonBar used for the header.
>>
>>Further, the itemRenderer's parent, a <div>, also has location (0,30) and
>>its parent, again a <div> is (0,30).
>>
>>This happens because the layout used to place everything is just relying
>>on display:block and none of the <div>s have position set to anything;
>>the
>>only <div> with position is the one representing the DataGrid itself.
>>
>>The .x and .y functions look at the "left" and "top" styles first.
>>Finding
>>these are not set, the functions then return offsetLeft and offsetTop,
>>which are the offsets from the ancestor with position set. That's the
>><div> for the DataGrid. Hence they are at (0,30).
>>
>>I see two choices: use getClientBoundingRect or change the layouts to set
>>position:relative on their contentView but this might break something
>>else
>>at some point.
>>
>>I was wondering if anyone had experience trying to figure out screen
>>positions when using the offset properties.
>>
>>
>>‹peter
>>
>>On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:
>>
>>>Peter,
>>>
>>>Is PointUtils.localToGlobal() not working for you? From what I
>>>understand
>>>it takes approach (1).
>>>
>>>From: Peter Ent<mailto:[hidden email]>
>>>Sent: Tuesday, August 29, 2017 11:29 PM
>>>To: [hidden email]<mailto:[hidden email]>
>>>Subject: [FlexJS] Finding (x,y) position
>>>
>>>Hi,
>>>
>>>While working on drag-and-drop, I've made an "interesting" discovery
>>>having to do with the HTML-side's x and y getter functions.
>>>
>>>Let's say you have a nesting of <div>s:
>>>
>>><div style="position:relative" id="outer">
>>>   <div id="header" style="height:30px">Š</div>
>>>    <div id="wrapper">
>>>        <div id="inner">
>>>             <div class="ItemRenderer" id="first">Š</div>
>>>        </div>
>>>    </div>
>>></div>
>>>
>>>(this structure is similar to what is generated for DataGrid).
>>>
>>>If you attempt to get the y location of "first" itemRenderer, you will
>>>get 30 back as the answer. That happens because the y getter first looks
>>>to see if the object has a "top" style value and, finding none, returns
>>>its offsetTop. In this case, offsetTop is 30 and offsetParent is
>>>"outer".
>>>If you get the y value of "inner" you will also get 30 as the answer for
>>>the same reason.
>>>
>>>If each of the <div>s had position:relative (or absolute), then
>>>offsetTop
>>>would be as you would expect with each offsetParent being the <div>
>>>above
>>>it.
>>>
>>>Our layout functions (and x and y setters) do not normally set the
>>>position style on element. I removed this a good while ago. Now I am
>>>trying to place a drop target indicator and to do that I need accurate
>>>(x,y) locations.
>>>
>>>I have a couple of solutions:
>>>
>>>
>>>  1.  For any element, look at its getBoundingClientRect and compare
>>>with
>>>its elementParent.getBoundingClientRect. The difference between then
>>>gives the child's position relative to the parent. This seems reliable.
>>>  2.  Attempt to divine a child's position using the offset information.
>>>I can't make this work.
>>>  3.  Modify the layouts to check the contentView's value of position
>>>and
>>>if not set already, set it to "relative". This makes the x and y getters
>>>return the right thing but may have unintended consequences.
>>>
>>>Any advice from seasoned JavaScript developers is greatly appreciated!
>>>
>>>Thanks,
>>>Peter
>>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: [FlexJS] Finding (x,y) position

Alex Harui-2
I think [1] is more about setting x,y.  I think the current problem is
getting x,y especially when position isn't set to absolute or relative.

Now maybe this isn't an important problem because nobody writes code that
reads x and y very often so having a getPositionInParent will be
sufficient.  I'm wondering how much code expects that x,y reports an
accurate value given that on the JS side we generally are letting HTML
layouts position items.  I think this issue has been around for a while
and we only now ran into it.

Thoughts?
-Alex

On 8/30/17, 10:17 AM, "Yishay Weiss" <[hidden email]> wrote:

>This [1] discussion touches on it.
>
>A PAYG approach might be to add
>PointUtils.getPositionInParent(uibase:UIBase) which would do the same
>thing PointUtils.localToGlobal() for element and parent and output the
>difference.
>
>[1]
>https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fle
>x-development.2333347.n4.nabble.com%2FFlexJS-Layouts-td61120.html%23a61330
>&data=02%7C01%7C%7C1a363cd8bd364a4e227a08d4efcb16f0%7Cfa7b1b5a7b34438794ae
>d2c178decee1%7C0%7C0%7C636397102925232200&sdata=ZKnEGJbsPHIJwjtwDy9dkYZcOL
>bLfcVcqKIt4VniVOw%3D&reserved=0
>
>From: Alex Harui<mailto:[hidden email]>
>Sent: Wednesday, August 30, 2017 7:02 PM
>To: [hidden email]<mailto:[hidden email]>
>Subject: Re: [FlexJS] Finding (x,y) position
>
>Hopefully Peter will find a solution based on your input.  But I think a
>problem still exists.
>
>The basic problem is how to find the x,y position of a child within its
>parent.  I believe Peter is saying that the x and y getters in UIBase are
>not reporting correct values in many cases in the browser.  Apparently,
>you can ask for the child.x and child.y of a child that is visibly not at
>0,0 in its parent and you will get 0.  I think we haven't noticed that
>because nobody currently cares, but it kinds of bugs me that something
>that "basic" doesn't do the right thing all of the time.
>
>Thoughts?
>-Alex
>
>
>On 8/30/17, 7:53 AM, "Peter Ent" <[hidden email]> wrote:
>
>>I'm trying to draw a drop indicator above the row in the DataGrid where
>>new data would be inserted if the user releases the mouse button at that
>>point.
>>
>>The drop indicator is being drawn in a layer (added by a new bead) that
>>is
>>floating above the <div> containing the DataGrid's column lists.
>>
>>As the mouse is detected over an itemRenderer, I need to know the
>>itemRenderer's position within its list so I can translate that into
>>global space and then into the space of the layer.
>>
>>However, what you just wrote gave me another idea that might just work.
>>
>>Thanks!
>>—peter
>>
>>On 8/30/17, 10:30 AM, "Yishay Weiss" <[hidden email]> wrote:
>>
>>>Strike that. I don’t see what you’re saying. Why not just use 0,0? Why
>>>do
>>>you need x,y? Or you could add w/2, h/2 if you want to center the drop
>>>target.
>>>
>>>Looking at PointUtils.localToGlobal() it just calls
>>>element.getBoundingClientRect() (as you suggested) and adds the given
>>>x,y
>>>to the result.
>>>
>>>From: Yishay Weiss<mailto:[hidden email]>
>>>Sent: Wednesday, August 30, 2017 5:11 PM
>>>To: [hidden email]<mailto:[hidden email]>
>>>Subject: RE: [FlexJS] Finding (x,y) position
>>>
>>>I see what you’re saying. I think we worked around that issue in our app
>>>by relying on MouseEvent.clientX, MouseEvent.clientY. But let’s hear
>>>other ideas for a more complete solution.
>>>
>>>From: Peter Ent<mailto:[hidden email]>
>>>Sent: Wednesday, August 30, 2017 4:48 PM
>>>To: [hidden email]<mailto:[hidden email]>
>>>Subject: Re: [FlexJS] Finding (x,y) position
>>>
>>>PointUtils works when it has the correct data. For example, if you are
>>>over an itemRenderer, say the first one, and want to get its global
>>>location, you might do:
>>>
>>>var pt0:Point = new Point(itemRenderer.x, itemRenderer.y)
>>>
>>>and use pt0 in PointUtils.localToGlobal function. The problem is,
>>>itemRenderer.x/y are not correct at all times. Because this itemRenderer
>>>is the first itemRenderer and in the upper-left corner of its List, you
>>>would expect it to be (0,0) but instead it is (0,30) for example where
>>>30
>>>is the height of the ButtonBar used for the header.
>>>
>>>Further, the itemRenderer's parent, a <div>, also has location (0,30)
>>>and
>>>its parent, again a <div> is (0,30).
>>>
>>>This happens because the layout used to place everything is just relying
>>>on display:block and none of the <div>s have position set to anything;
>>>the
>>>only <div> with position is the one representing the DataGrid itself.
>>>
>>>The .x and .y functions look at the "left" and "top" styles first.
>>>Finding
>>>these are not set, the functions then return offsetLeft and offsetTop,
>>>which are the offsets from the ancestor with position set. That's the
>>><div> for the DataGrid. Hence they are at (0,30).
>>>
>>>I see two choices: use getClientBoundingRect or change the layouts to
>>>set
>>>position:relative on their contentView but this might break something
>>>else
>>>at some point.
>>>
>>>I was wondering if anyone had experience trying to figure out screen
>>>positions when using the offset properties.
>>>
>>>
>>>‹peter
>>>
>>>On 8/30/17, 3:02 AM, "Yishay Weiss" <[hidden email]> wrote:
>>>
>>>>Peter,
>>>>
>>>>Is PointUtils.localToGlobal() not working for you? From what I
>>>>understand
>>>>it takes approach (1).
>>>>
>>>>From: Peter Ent<mailto:[hidden email]>
>>>>Sent: Tuesday, August 29, 2017 11:29 PM
>>>>To: [hidden email]<mailto:[hidden email]>
>>>>Subject: [FlexJS] Finding (x,y) position
>>>>
>>>>Hi,
>>>>
>>>>While working on drag-and-drop, I've made an "interesting" discovery
>>>>having to do with the HTML-side's x and y getter functions.
>>>>
>>>>Let's say you have a nesting of <div>s:
>>>>
>>>><div style="position:relative" id="outer">
>>>>   <div id="header" style="height:30px">Š</div>
>>>>    <div id="wrapper">
>>>>        <div id="inner">
>>>>             <div class="ItemRenderer" id="first">Š</div>
>>>>        </div>
>>>>    </div>
>>>></div>
>>>>
>>>>(this structure is similar to what is generated for DataGrid).
>>>>
>>>>If you attempt to get the y location of "first" itemRenderer, you will
>>>>get 30 back as the answer. That happens because the y getter first
>>>>looks
>>>>to see if the object has a "top" style value and, finding none, returns
>>>>its offsetTop. In this case, offsetTop is 30 and offsetParent is
>>>>"outer".
>>>>If you get the y value of "inner" you will also get 30 as the answer
>>>>for
>>>>the same reason.
>>>>
>>>>If each of the <div>s had position:relative (or absolute), then
>>>>offsetTop
>>>>would be as you would expect with each offsetParent being the <div>
>>>>above
>>>>it.
>>>>
>>>>Our layout functions (and x and y setters) do not normally set the
>>>>position style on element. I removed this a good while ago. Now I am
>>>>trying to place a drop target indicator and to do that I need accurate
>>>>(x,y) locations.
>>>>
>>>>I have a couple of solutions:
>>>>
>>>>
>>>>  1.  For any element, look at its getBoundingClientRect and compare
>>>>with
>>>>its elementParent.getBoundingClientRect. The difference between then
>>>>gives the child's position relative to the parent. This seems reliable.
>>>>  2.  Attempt to divine a child's position using the offset
>>>>information.
>>>>I can't make this work.
>>>>  3.  Modify the layouts to check the contentView's value of position
>>>>and
>>>>if not set already, set it to "relative". This makes the x and y
>>>>getters
>>>>return the right thing but may have unintended consequences.
>>>>
>>>>Any advice from seasoned JavaScript developers is greatly appreciated!
>>>>
>>>>Thanks,
>>>>Peter
>>>>
>>>
>>
>