PDA

View Full Version : get list item component x,y position in an item tap event



scheid
17 Jan 2012, 7:35 PM
Hi All,

I feel like this is an obvious one, but couldn't find any answers in my search so far. I'm using Touch v2.0 PR3. My issue is that I have a list and have an item tap event hooked up to it. No problems there, the event fires just fine. But I'm trying to figure out how to get the exact x.y position on the screen of the list item component that was tapped (or actually just the y position; I guess x would always be 0), so I can display an Ext.Sheet (sized sort of small like a pop up menu) directly under (or over) the tapped list item. I've been going through the various params on the itemtap event, but can't seem to obtain the list item component position from any of them.

So, with the first param of the item tapevent, the list component, I've tried using getAt, getComponent, getItems, getSelected, etc., passing in the idx value, and none seem to give me the actual list item component that was clicked on. I'm assuming I can get the list item component, and getTop will give me what I need.

I've also tried using the offsetTop property of the dom target param of itemtap , like: target.dom.offsetTop , but that doesn't behave consistently either.

Currently I'm positioning the sheet using the event param, like: evt.touch.pageX and evt.touch.pageY, which works OK, but would like to position it based on the list item instead.

Am I just missing something obvious here? Thanks for helping out a noob.

mitchellsimoens
18 Jan 2012, 4:30 AM
Do you want the position of the list item or where you touch?

To do where you touch it is as easy as:


listeners : {
itemtap : function(list, index, node, e) {
var x = e.pageX,
y = e.pageY;
}
}

To get the position of the list item:


listeners : {
itemtap : function(list, index, node, e) {
var el = Ext.get(node),
xy = el.getXY(), //will be top-left corner of el
size = el.getSize();

xy[0] = xy[0] + size.width / 2; //if you want it at the center of the x axis
xy[1] = xy[1] + size.height; //if you want it at the bottom of the el
}
}

By default, the xy will be the top-left of the el. If you want it at the bottom and middle of the el, then you can get the size and do some math.

scheid
18 Jan 2012, 8:34 AM
Hi Mitchell,

Thanks for the quick reply. Your solution works for placing the sheet, *however*, the target element passed into the itemtap event seems to be pointing to the overall list itself, and not the individual item that was tapped on. My sheet/view is displayed, but is shown at the bottom of the list regardless of which item I tap on. This is why I was having issues before in using the target dom element.

mitchellsimoens
18 Jan 2012, 9:35 AM
You can get any element that is under where you tapped via e.getTarget('div.some-class', null, true)

replacing 'div.some-class' with the DOM selector of your element

scheid
18 Jan 2012, 10:44 AM
OK, thanks. Is there a rule for the element id naming to know how I could use the index value to get the exact list item? Using something like e.getTarget('x-list-item', null, true) still seems like I wouldn't know how to obtain the exact list item. I see in the generated dom that each of the list item divs have an 'itemindex' attribute that corresponds to the index of the item in the list, so I guess I could somehow use a query to get the div I wanted, like Ext.ComponentQuery.query("itemindex = " + idx, target) ? But based on what you've suggested and what I've read in the docs, isn't it a bug that the whole list container element is passed in instead of just the tapped list item element?

mitchellsimoens
18 Jan 2012, 10:48 AM
The default target should be the 'div.x-list-item' so when you are doing getTarget, you would try to find a component under that list item.

scheid
18 Jan 2012, 5:21 PM
Thanks for the help with this. Below is what I ended up doing to get it to work the way I needed it to.





doListItemTap: function(listCmp, idx, target, evt, options ) {

//get my view, which is just a sized down Ext.Sheet
var view = this.getItemMenuView().create();


//note that the quotes around the itemindex value here are required to include and don't seem to be in the sencha docs; this function was failing until I included the quotes
var itemEl = Ext.select("div.x-list-item[itemindex=\"" + idx + "\"]", listCmp.getId() );

//I know that the array returned by Ext.select above will only ever be a single element array, so we just grab the first element here
var el = itemEl.first();


var x = el.getX();
var y = el.getY();
var size = el.getSize();


x = x + size.width / 2;
y = y + size.height;


view.setTop(y);
view.setLeft(10);


view.show();


}

epicflux
9 Feb 2012, 2:21 PM
Could you confirm that your code works with the latest beta release of Sencha Touch 2. I have code very similar to yours, but when I try to use the 'first' function I get this error:



Uncaught TypeError: Object [object Object] has no method 'attach'


var itemEl = Ext.select("div.x-item-selected", this.getHeadlinesList().getId());
console.log(Ext.select("div.x-item-selected", this.getHeadlinesList().getId())); //this works
console.log(itemEl.first()); //this throws the above error