Page 1 of 3 123 LastLast
Results 1 to 10 of 26

Thread: Child Component Loses Scroll Position When Parent Layout is Updated

    Success! Looks like we've fixed this one. According to our records the fix was applied for EXTJS-7103 in 5.1.3.
  1. #1
    Ext JS Premium Member Gjslick's Avatar
    Join Date
    Feb 2009
    Location
    NJ, USA
    Posts
    129

    Default Child Component Loses Scroll Position When Parent Layout is Updated

    Ext version tested:
    • Ext 4.1 rev 1
    Browser versions tested against:
    • Chrome 21
    • IE8
    • FF14 (firebug 1.10 installed)
    Description:
    • When a layout is updated, a child component that has been scrolled by the user will reset its scroll position back up to the top.
    Steps to reproduce the problem:

    The result that was expected:
    • Panel 1's content should keep its scroll position.
    The result that occurs instead:
    • Panel 1's content loses its scroll position on its child component. The child component's scroll position is reset to the top.

    See this URL for live test case: http://jsfiddle.net/qgNtc/4/

    Additional CSS used:
    • only default ext-all.css
    Operating System:
    • Win 7


    Test case:

    Code:
    Ext.define( 'MyLongView', {
        extend : 'Ext.Component',
        
        autoScroll : true,
        maxHeight  : 100,
        html       : '1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>'
    } );
    
    
    Ext.create( 'Ext.container.Container', {
        renderTo : document.body,
            
        layout : {
            type    : 'accordion',
            animate : false,
            multi   : true,
            fill    : false
        },
        
        items : [
            { 
                title: "Panel 1",
                items : [ 
                    Ext.create( 'MyLongView' )
                ]
            },
            { title: "Panel 2", height: 100, html: "Panel 2 Text" },
            { title: "Panel 3", height: 100, html: "Panel 3 Text" }
        ]
    } );?
    Last edited by mitchellsimoens; 27 Aug 2012 at 8:45 AM. Reason: moved code from jsfiddle to here

  2. #2
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,448

    Default

    Thanks for the report! I have opened a bug in our bug tracker.

  3. #3
    Ext JS Premium Member Gjslick's Avatar
    Join Date
    Feb 2009
    Location
    NJ, USA
    Posts
    129

    Default

    Thanks Mitchell

    I came up with a temporary workaround for now, but it would need to be added wherever this may happen. (Although, I suppose one could write an override to AbstractComponent, but I personally wouldn't risk the possible problems/conflicts that could occur with the library and/or user extensions.)

    This basically stores the scroll values when the element is scrolled, and then restores them when afterComponentLayout() runs.

    Code:
    Ext.define( 'MyLongView', {
        extend : 'Ext.Component',
        
        autoScroll : true,
        maxHeight  : 100,
        html       : '1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>',
        
        // BEGIN SCROLL-SAVING WORKAROUND CODE    
        onRender : function() {
            this.callParent( arguments );
            this.getEl().on( 'scroll', this.saveScroll, this );
        },
        
        afterComponentLayout : function() {
            this.callParent( arguments );
            this.restoreScroll();
        },
        
        saveScroll : function() {
            this.savedScroll = this.getEl().getScroll();
        },
        
        restoreScroll : function() {
            var savedScroll = this.savedScroll || {};
            this.getEl()
                .scrollTo( 'left', savedScroll.left || 0 )
                .scrollTo( 'top', savedScroll.top || 0 );
        }
        // END SCROLL-SAVING WORKAROUND CODE
        
    } );
    
    
    Ext.create( 'Ext.container.Container', {
        renderTo : 'testDiv',
            
        layout : {
            type    : 'accordion',
            animate : false,
            multi   : true,
            fill    : false
        },
        
        items : [
            { 
                title: "Panel 1",
                items : [ 
                    Ext.create( 'MyLongView' )
                ]
            },
            { title: "Panel 2", height: 100, html: "Panel 2 Text" },
            { title: "Panel 3", height: 100, html: "Panel 3 Text" }
        ]
    } );?
    http://jsfiddle.net/gjslick/Q4pqB/4/

    Would you know if the layout system detaches child elements from the DOM at any point, perhaps to take measurements of a parent element without its children being present? Detaching would definitely cause this issue. Just a thought though, haven't had time to dive into it.

    -Greg

  4. #4
    Ext JS Premium Member Gjslick's Avatar
    Join Date
    Feb 2009
    Location
    NJ, USA
    Posts
    129

    Default

    Err, so it seems that my workaround works nicely in Chrome and Firefox, but can cause a flicker of the scrollbar in IE... =/

  5. #5
    Sencha User
    Join Date
    Dec 2011
    Location
    Vancouver, B.C.
    Posts
    20

    Default

    Glad I found this thread. Having the exact same issue and I was going mad trying to come up with a a fix.

    I implemented my own virtual scrolling system as the form could contain 500 - 1000 controls. I create a massive scrolling section then recycle the various components by repositioning them as the user scrolls and create new ones for the pool as needed. When I would add those new controls (i.e. when the pool was exhausted of a certain control type), the scrollTop went back to 0. I narrowed it down to the "layout" by using "suspendLayout=true/false" and calling the doLayout() manually to observe the behavior noted more easily.

    I'm going to try your work around Gjslick as I can live with some flicker in IE for now with the hope this gets fixed soon!

    Update: I tried Gjslick fix and it works except for some reason Chrome loses focus on the scrollbar elevator. As I scroll eventually I need to add a component(s), afterComponentLayout is called and I set scrollTop but the elevator doesn't have focus anymore so I have to re-mouse down on the elevator to continue the drag scrolling. Doesn't happen in Firefox or IE8/9 (only others I tested thus far). Anyway after I set scrollTop to set focus "back" to the scrollbar elevator?

  6. #6
    Ext JS Premium Member Gjslick's Avatar
    Join Date
    Feb 2009
    Location
    NJ, USA
    Posts
    129

    Default

    @hooped Unfortunately there is no way (that I know of, anyway) to re-focus the user's mouse on the scrollbar elevator. My workaround is basically a hack unfortunately, and this needs to be fixed within the layout system so that we never lose the scrollbar position in the first place.

    @mitchellsimoens Any work being done on this? As soon as a component's layout is executed, we lose the scroll position on both that component, and its parent container's. Makes for a pretty awful experience..

  7. #7
    Ext JS Premium Member neongrau's Avatar
    Join Date
    Mar 2007
    Posts
    282

    Default

    I'm having an issue with a container that is autoScroll:true in a tabpanel where i'm rendering search results. When i scroll down and then change the tab in that tabpanel the scroll positon gets reset when i return to the first tab.

    While it sounds the same. This only happens with Internet Explorer. Firefox and Chrome both leave the scroll position unchanged.

  8. #8
    Sencha User
    Join Date
    Dec 2011
    Location
    Vancouver, B.C.
    Posts
    20

    Default

    The only thing I can suggest is look and see if there is a layout call invoked. Pretty much anything that causes a layout and re-calculation of containers will cause the underlying DIVS to be set to scrollTop = 0. It' spossible that you can adjust your code to not cause the layout call in IE (although it's odd the other browsers would be OK).

  9. #9
    Sencha User Animal's Avatar
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,892

    Default

    It's a hideMode thing. Scroll position is lost when an element loses layout (display:none)

    Try this:

    Code:
    Ext.onReady(function() {
        Ext.define( 'MyLongView', {
            extend : 'Ext.Component',
            autoScroll : true,
            html       : '1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>'
        });
    
        Ext.create( 'Ext.container.Viewport', {
            layout : {
                type    : 'accordion',
                animate : true,
                multi   : true
            },
            items : [
                {
                    title: "Panel 1", layout: 'fit',
                    items : Ext.create( 'MyLongView' ),
                    hideMode: 'offsets'
                },
                { title: "Panel 2", height: 100, html: "Panel 2 Text" },
                { title: "Panel 3", height: 100, html: "Panel 3 Text" }
            ]
        });
    });

  10. #10

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •