Scroll to top in VirtualList

Hi.. i am trying to find function to "scroll to top" in VirtualList. Is there any?
Thanks

Comments

  • Here's how I did it:
    var scroller = this.$.virtualList.$.scroller;
    scroller.adjustTop(0);
    scroller.top = 0;
  • thanks rsanchez1
    i tried the code that you shared above.
    after porting, although syntactically all is correct, but it did not move up the LIST to top :(
  • hi rsanchez, correction of my testing. it did move up, but not up to the top. The top displayed is fourth element in the list.
  • Oh, forgot one line. Add this at the end:

    this.$.virtualList.punt();
  • it did not work either... it did scroll up, but not till to top
  • If the punt method doesn't work then there is likely something wrong with your layout. Can you post your VirtualList code?
  • I don't know if this applies to lists as well, but I discovered with a Repeater, if you're trying to scroll it to the top, and send it a re-render event, you need to send the scrollTo to the scroller first, then do the refresh on nextTick .. such as:
    		this.$.Scroller.scrollTo(0,0);
    enyo.nextTick(this, this.$.Repeater.render);
    Otherwise, it would appear to trigger some sort of race condition that would have it not necessarily scrolling to the right place, or at all.
  • thanks ekdikeo, but the problem persist event without attempt to re-render list (unless if implicitly re-render is called). I just execute line by line using javascript console (so it does not likely async issue that solved by nextTick).
    Below is the partial code, but it is pretty standard..

    the owner:
    {name: "list", kind: "CompList"}
    the components:
    enyo.kind({
    name: "enyo.CompList",
    kind: "VirtualList",
    height: Config.listHeight //global variable,
    components: [
    {name: "listItem", onclick : "itemClick", kind: "Item", layoutKind: "HFlexLayout", tapHighlight: true, components: [
    {name: "itemId", className : "invisible"},
    {layoutKind: "VFlexLayout", tapHighlight: true, flex: 1, components: [
    {name: "itemBookmark", src: "images/nbm_l.png", kind: "Image", style: "height: 17px; width: 17px;"},
    {name: "itemLike", src: "images/_love_2.png", kind: "Image", style: "height: 15px; width: 15px;"}
    ]},
    {layoutKind: "VFlexLayout", tapHighlight: true, flex: 10, components: [
    {name: "itemTitle", className : "itemTitle"},
    {layoutKind: "HFlexLayout", components:[
    {name: "itemDetail1", flex:1, className: "enyo-item-secondary enyo-text-ellipsis itemDetail1"},
    {name: "itemDistance", className: "itemDistance"}
    ]},
    {name: "itemDetail2", className: "enyo-item-ternary enyo-text-ellipsis"}
    ]}
    , {name: "itemIcon", src: "images/garden.jpg", kind: "Image", style: "height: 50px; width: 50px;"}
    ]} //end of kind = Item
    ],
    //
  • Maybe it's something in your css. I just tried it out and all I really needed was adjustTop. Maybe you can post the relevant css?

    Also, the scroller used for VirtualList is BufferedScroller, not Scroller, so the methods aren't exactly the same. BufferedScroller does not have the .scrollTo method that Scroller inherits from BasicScroller, since BufferedScroller inherits directly from DragScroller.
  • Hi rsanchez1, i think most of the css (refer to above code) I used is only for "Item" kind which i guess not affecting the scrolling. Any thought of which CSS would you think may affect scrolling?

    Btw which enyo1 version are you using? And may I know how to check? I am afraid I am not using latest enyo1..
    Thanks
  • What about

    this.$.list.punt();
    this.$.list.reset();
  • hi jlai thanks for you comment.
    I tried below code (to cover all the feedback). It did move up the list but not up to top. Also tried by re-downloading enyo 1.0, and still have the same output.
    	var list = APP.list;
    list.punt();
    list.reset();
    setTimeout('APP.list.$.scroller.top =0;APP.list.$.scroller.adjustTop(0);alert("done");', 5000)
    var scroller = list.$.scroller;
    scroller.top = 0;
    scroller.adjustTop(0);
    list.punt();
    list.reset();
  • How are you filling your list? I usually have mine tied to an array, and use this function to scroll to specific items:

    so call it like:

    this.scrollTo(0, this.$.VListName)
    scrollTo:function(inIndex, vlist){
    var scr = vlist.$.scroller;
    if (inIndex < 0) {inIndex = 0;};
    var scrollSpot=0;
    for (var h in scr.heights) {
    if (h) {
    scrollSpot=scr.heights[h] * inIndex;
    break;
    }
    }
    scr.$.scroll.setScrollPosition(-scrollSpot);
    scr.start();

    },
  • hi Chris, thanks for your geeky suggestion.. i tried that and it moved the list up but not till top.

    but i just realized that all other suggestions above works for iPad browser, although it does not work (perfectly) in Safari browser in Mac...

  • It must be a bug in Mac Safari then. I still think it's probably an issue with CSS. Maybe Mac Safari has problems with the flexible box styles used by Enyo.
  • thanks rsanchez1, i think you're right (from beginning). at the moment i will forget about this, hopefully there is no issue in Enyo 2.0
  • I would higher recommend AGAINST using adjustTop(0) to scroll to the top. adjustTop(0) tells the VirtualList to render the first element, but doesn't adjust the internal scroll coordinates;ie. this.$.virtualList.$.scroller.$.scroll.y

    This can cause scroll and rendering problems. A VirtualList is pretty much driven by that y-coordinate. Changing that y-coordinate cause a setupRow and acquirePage events to fire. this.$.virtualList.$.scroller.$.scroll.setPosition() basically just sets the y-coordinate.
  • The scrollTo function above is ok if you already have all your data and do not need to use the acquirePage event. However, if you have to incrementally load your list data, try this kind instead. I pulled the code from somewhere else and took out some irrelevant parts, so there might be some syntax errors. This also does something a little fancier than just jumping to an item. When the destination item is currently visible, it will trigger an animated scroll. Also you can set a pixel offset from the top that you want the destination item to scroll to.
    enyo.kind({
    name:"CustomVirtualList",
    kind:"VirtualList",
    scrollToIdx:function(idx,offsetAmt){
    return this.scrollToIdxInternal(idx,offsetAmt,true);
    },
    scrollToIdxInternal:function(idx,offsetAmt,firstCall){
    var s = this.$.scroller;
    var offset = (offsetAmt < 0 || offsetAmt == null)? 0:offsetAmt;
    /*
    * Scroll the list one screen at a time until the desired index is between the top and
    * bottom indices. I'm pulling my data from the network, so only I only scroll ten
    * screens before I do a setTimeout to prevent the scrolling from overwhelming the
    * connection.
    */
    if(idx > s.bottom){
    for(var i=0;idx > s.bottom && i<10;i++) {
    s.$.scroll.setScrollPosition(s.$.scroll.y - s.contentHeight);
    s.scroll();
    }
    setTimeout(enyo.bind(this,"scrollToIdxInternal",idx,offset,false),0);
    }
    else if(idx < s.top){
    for (var i = 0; idx < s.top && i < 10; i++) {
    s.$.scroll.setScrollPosition(s.$.scroll.y + s.contentHeight);
    s.scroll();
    }
    setTimeout(enyo.bind(this,"scrollToIdxInternal",idx,offset,false),0);
    }else{
    // The desired index is between the top and bottom, do the final scroll to
    // the exact position + offset

    var n = this.$.list.fetchRowNode(idx);
    var pos = (s.$.scroll.y - (s.pageTop + n.offsetTop)) + offset;
    if (pos > 0)
    pos = 0

    var temp = s.$.scroll.y;
    s.$.scroll.setScrollPosition(pos);
    s.scroll();
    n = this.$.list.fetchRowNode(s.bottom);
    pos = s.pageTop + n.offsetTop + n.offsetHeight;
    if (pos <= s.viewHeight) {
    // Check if we've scroll past the bottom of the list. If so scroll back to
    // the bottom.
    pos = s.$.scroll.y + (s.viewHeight - pos);
    if (pos > 0) {
    // Check if we've scroll past the top of the list. Only happens
    // for lists shorter than the height of the container.
    pos = 0;
    }
    }
    else
    pos = s.$.scroll.y;

    if (firstCall) {
    // Animated scroll
    s.$.scroll.setScrollPosition(temp);
    s.scroll();

    s.$.scroll.kFrictionDamping = 0.75;
    s.$.scroll.y = s.$.scroll.y0 - (-pos + s.$.scroll.y0) * (1 - s.$.scroll.kFrictionDamping);
    s.$.scroll.start();
    }
    else if(pos != s.$.scroll.y){
    // Jump scroll
    s.$.scroll.setScrollPosition(pos);
    s.scroll();
    }
    }
    }
    });
  • oops, forgot a couple of functions. just add these to the kind above.
    create:function(){
    this.inherited(arguments);
    this.$.scroller.scrollStop = enyo.bind(this,"scrollStop");
    },
    scrollStop:function(){
    this.$.scroller.$.scroll.kFrictionDamping = 0.97;
    },
  • thanks waynetam, my issue is observed at Mac Safari.. do you know whether the code above work in Safari Browser?
  • Just a general feedback,
    I have tried rsanchez1suggestion
    var scroller = this.$.virtualList.$.scroller;scroller.adjustTop(0);
    scroller.top = 0;
    this.$.virtualList.punt();
    And it works fine in safari - Windows 7 64 bit.
  • Hi Sandbox, thanks for your input. I am using Mac, not sure this caused different result.
  • Not sure if my code works in mac safari. I've only used it in webOS and Windows chrome.

    this.$.virtualList.punt() isn't really scrolling the list, it's actually resetting and reloading the list, which means you probably won't even need the adjustTop(0)
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Twitter