PDA

View Full Version : Scroll to view the selected list item function



elwhiz
22 Aug 2012, 12:58 AM
Hi,

We have an application that has a list with many items.
In Portrait mode on the iPad, the user can see about 5 items. We maintain a "currently" selected item in the list.
Is there a function that I can call, to ensure the currently Selected item is always visible?

For example...
Let's say there are 50 items in the list.
Then, let's say the user has scrolled down and selected item #40.
Then, the list gets refreshed.
After the list is reloaded, I need to call a function that will automatically scroll item #40 into view.

Is there such a function ?

Thanks

mitchellsimoens
23 Aug 2012, 12:09 PM
You need to get the position of the selected item and then scroll to it.


var store = list.getStore(),
selected = list.getSelection()[0],
idx = store.indexOf(selected),
els = list.container.getViewItems(),
el = els[idx],
offset = el.dom.offsetTop;

list.getScrollable().getScroller().scrollTo(0, offset);

*typed from top of my head*

shweta.saxena09
25 Sep 2012, 3:03 AM
Uncaught TypeError: Cannot read property 'offsetTop' of undefined

Error is showing

mitchellsimoens
25 Sep 2012, 4:54 AM
may have to do Ext.get(el).dom.offsetTop then

shweta.saxena09
25 Sep 2012, 4:58 AM
onItemTap: function(list, index, target, record, e) {
var store = list.getStore(),
selected = list.getSelection()[0],
idx = store.indexOf(selected),
els = list.container.getViewItems(),
el = els[idx],
offset = Ext.get(el).dom.offsetTop;


list.getScrollable().getScroller().scrollTo(0, offset);
}

Not working

mitchellsimoens
25 Sep 2012, 5:00 AM
Which part? Have you tried anything else?

shweta.saxena09
25 Sep 2012, 5:02 AM
when itemtap event fire the selected item should be set on top....

But without disturbing his default scrolling functionality.......

shweta.saxena09
25 Sep 2012, 5:20 AM
Even this code is not working with simple static data list...................
I have changed the scrollTo(0, offset) to scrollTo(0, 0) now cursor jump on top of the list...... but selected item is still in same position... i have to scroll to reach.....

shweta.saxena09
9 Oct 2012, 9:34 PM
Issue solved

Thanks

mitchellsimoens
10 Oct 2012, 4:11 AM
Container does not have a getViewItems() method. What were you trying to get to, Mitchell?

Sure it does: http://docs.sencha.com/touch/2-0/#!/api/Ext.dataview.component.Container-method-getViewItems

scottd
11 Oct 2012, 10:32 AM
How was this issue solved? I'm facing the same problem of needing to scroll a selectfield list. Do you have working code that you can share?

shweta.saxena09
11 Oct 2012, 10:15 PM
How was this issue solved? I'm facing the same problem of needing to scroll a selectfield list. Do you have working code that you can share?

Well I have used same code provided by mitchell

var pageoffset=0;
pageoffset=parseInt(80)*parseInt(node.data.index);

list.getScrollable().getScroller().scrollTo(0,pageoffset, true);
// here 80 is the height of the list item, bcoz I have fixed height list item u can change it to //dynamically

its working for me.... i don't know its correct way or not.... but i was on deadline that time......so I chose this....

x33z
31 Oct 2012, 9:52 AM
I've tried the code above, and for the life of me can't figure out why



var offset = Ext.get(el).dom.offsetTop;


Is not returning a value. I log at it in the console, and Ext.get(el) has dom, and the offsetTop value is shown in there. But when I run the code above, it always returns 0.

I've attached the output for the following, which, to me, says I have the proper element.



console.log(Ext.get(el));


What dumb thing am I doing?

Thanks!

mistik1
30 Dec 2012, 2:52 PM
I managed to get this working by using the Ext.fly and the el that is return is an HTMLElement not and Ext.Element which is what you need to have .dom.offsetTop



var store = list.getStore(),
selected = list.getSelection()[0],
idx = store.indexOf(selected),
els = list.container.getViewItems(),
el = Ext.fly(els[idx]),
offset = el.dom.offsetTop;

list.getScrollable().getScroller().scrollTo(0, offset, true);

scottd
31 Dec 2012, 2:35 PM
Thanks. Where in your code did you apply this approach? In an event handler?

matthewdfleming
18 Jan 2013, 8:07 AM
Hey guys,

I thought I'd post my solution to this problem. The key for me was to look at how the 'List.js' class handled the scrolling with regard to clicking on an index in the 'index bar.' Here's how I was able to get the scrolling to work.

I have a component that has a list within it... and the outer component is a panel that doesn't always show. So I added this to the config for the outer component:



listeners: {
show: function (outerComponent) {
var list = outerComponent.down('list');
var task = Ext.create('Ext.util.DelayedTask', function () {
var store = list.getStore();
var selected = list.getSelection()[0];
if (selected) {
var idx = store.indexOf(selected),
scroller = list.getScrollable().getScroller(),
containerSize = scroller.getContainerSize().y,
size = scroller.getSize().y,
maxOffset = size - containerSize,
offsetTop = list.getItemMap().map[idx],
offset = (offsetTop > maxOffset) ? maxOffset : offsetTop;
scroller.stopAnimation();
scroller.scrollTo(0, (offset > 0) ? offset : 0, true);
}


});
task.delay(200);
}
}


I couldn't find an event that was 'after show' or 'after render' so the best I could do is schedule something to run. Anyone have a better way to test that something has been shown. I'm a little worried that the delay (in this case 200ms) might be too short, I was hoping to test for some attribute that gets set to true after a component has been displayed.

Btw, the problem with the other solutions (listed in this thread) is that the way the get the offsetTop is wrong in that


list.container.getViewItems()

will only return the elements 'showing'. The component seems to window things by moving items in and out of the 'viewItems' list. So if the view only has 10 items but your list has 20, this method doesn't work. Hence the solution above, where I use getItemMap instead.

Edit: I had to make the timeout greater for my phone.. like 500ms. Still looking for the attribute to test, so I can delay again if I have to..

-Matt

remolina
23 Jan 2013, 8:48 AM
I ran into the same need yesterday and after a little digging through the API, I found the function setScrollToTopOnRefresh() on the list. As you noticed, when you call refresh(), the list goes back to the top. So if you call setScrollToTopOnRefresh(false), it will not go to the top after refresh.

samaresh2009
2 Apr 2013, 2:35 AM
el = els[idx]at this point el is coming undefiend

scottd
18 Jun 2013, 2:26 PM
We just started using version 2.2.0 and have discovered that our list scrolling workaround no longer works . Now we have no method at all to keep our UI from failing to scroll to the selected item.

We used to use this code on a selectfield's list to find the offset of the item that was programmatically selected:

var map = Mob.ref.RoleList.getItemMap();
var offsetTop = map.map[index];

This works in 2.1.1. Now, with 2.2.0, the item map's map property (map.map) returns an empty array. Anybody know what replaces it, if anything?

Rohit421991
5 Jul 2013, 8:02 AM
@shweta.saxena09
Please can you explain me how your problem is solved (set scoll to selected list item).

Thanks.