You found a bug! We've classified it as EXTJS-6966 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Ext JS Premium Member lukerahl's Avatar
    Join Date
    Nov 2007
    Location
    New Mexico, USA
    Posts
    23
    Vote Rating
    1
    lukerahl is on a distinguished road

      0  

    Exclamation loadMask does not scroll with components when parent container is scrolled

    loadMask does not scroll with components when parent container is scrolled


    REQUIRED INFORMATION


    Ext version tested:
    • Ext 4.1.1

    Browser versions tested against:
    • IE10
    • IE9
    • IE8
    • FF13.0.1
    • FF12
    • Chrome 21

    Description:
    • When masking an element using mask() everything seems to work great (except IE10 where the mask does not show at all). When using setLoading(), which is used by grids and other components tied to stores, the load mask does not scroll with any parent container scrolling. Please run the test provided to see the issue.

    Test Case:
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    		<title>LoadMask inside scrolling container issue</title>
    		<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    		<link rel="stylesheet" type="text/css" href="../shared/example.css" />
    		<script type="text/javascript" src="../../ext-all.js"></script>
    		<script type="text/javascript" src="LoadMaskBug.js"></script>
    	</head>
    	<body style="overflow:hidden;">
    		<h1>Using element.mask works:</h1>
    		<div id="grid-example1" style="width:800px;height:200px;overflow:auto;margin:0px 25px 25px;"></div>
    		<h1>Using element.setLoading does NOT work:</h1>
    		<div id="grid-example2" style="width:800px;height:200px;overflow:auto;margin:0px 25px;"></div>
    	</body>
    </html>
    And
    Code:
    Ext.require([
        'Ext.grid.*',
        'Ext.data.*'
    ]);
    
    Ext.define('Company', {
        extend: 'Ext.data.Model',
        fields: [
           {name: 'company'}
        ],
        idProperty: 'company'
    });
    
    var myData = [
    	['3m Co'],
    	['Alcoa Inc'],
    	['Altria Group Inc'],
    	['American Express Company'],
    	['American International Group, Inc.'],
    	['AT&T Inc.'],
    	['Boeing Co.'],
    	['Caterpillar Inc.'],
    	['Citigroup, Inc.'],
    	['E.I. du Pont de Nemours and Company'],
    	['Exxon Mobil Corp'],
    	['General Electric Company'],
    	['General Motors Corporation'],
    	['Hewlett-Packard Co.'],
    	['Honeywell Intl Inc'],
    	['Intel Corporation'],
    	['International Business Machines'],
    	['Johnson & Johnson'],
    	['JP Morgan & Chase & Co'],
    	['McDonald\'s Corporation'],
    	['Merck & Co., Inc.'],
    	['Microsoft Corporation'],
    	['Pfizer Inc'],
    	['The Coca-Cola Company'],
    	['The Home Depot, Inc.'],
    	['The Procter & Gamble Company'],
    	['United Technologies Corporation'],
    	['Verizon Communications'],
    	['Wal-Mart Stores, Inc.']
    ];
    
    // create the data store
    var store = Ext.create('Ext.data.ArrayStore', {
    	model: 'Company',
    	data: myData
    });
    
    // Define grid
    Ext.define('mygrid',
    {
    	extend:'Ext.grid.Panel',
    	store: store,
    	margin:25,
    	collapsible: true,
    	multiSelect: true,
    	columns: [
    		{
    			text     : 'Company',
    			flex     : 1,
    			sortable : false,
    			dataIndex: 'company'
    		}
    	],
    	height: 350,
    	width: 600,
    	viewConfig: {
    		stripeRows: true,
    		enableTextSelection: true
    	}  
    });
    
    Ext.onReady(function(){
    	Ext.create('mygrid',
    	{
    		title:'mask works',
    		listeners:
    		{
    			render: function(p)
    			{
    				this.body.mask('Loading...','x-mask-loading');
    			},
    			delay: 25
    		},
    		renderTo:'grid-example1'
    	});
    	Ext.create('mygrid',
    	{
    		title:'setLoading does NOT work',
    		listeners: 
    		{
    			render: function(p)
    			{
    				this.setLoading('Loading...', true);
    			},
    			delay: 25
    		},
    		renderTo:'grid-example2'
    	});
    });

    HELPFUL INFORMATION


    Debugging already done:
    • Seems to be an issue where the loadMask is added to the DOM outside of the parent container

    Possible fix:
    • not provided

    Additional CSS used:
    • default ext-all.css
    • example.css

    Operating System:
    • Windows 8 64-bit
    • Windows 7 64-bit

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,397
    Vote Rating
    849
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Thanks for the report.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Ext JS Premium Member lukerahl's Avatar
    Join Date
    Nov 2007
    Location
    New Mexico, USA
    Posts
    23
    Vote Rating
    1
    lukerahl is on a distinguished road

      1  

    Lightbulb Possible solution...not tested much though.

    Possible solution...not tested much though.


    The following seems to work for me with VERY limited testing:
    Code:
    Ext.override(Ext.Component,
    {
        setLoading : function(load, targetEl) {
            var me = this,
                config;
    
            if (me.rendered) {
                Ext.destroy(me.loadMask);
                me.loadMask = null;
    
                if (load !== false && !me.collapsed) {
                    if (Ext.isObject(load)) {
                        config = Ext.apply({}, load);
                    } else if (Ext.isString(load)) {
                        config = {msg: load};
                    } else {
                        config = {};
                    }
    				
                    if (targetEl) 
    			me.loadMask = new Ext.LoadMask(me.getTargetEl(), config);
                    else
    			me.loadMask = new Ext.LoadMask(me.el, config);
    
    		me.loadMask.show();
                }
            }
            return me.loadMask;
        }
    });

  4. #4
    Ext JS Premium Member lukerahl's Avatar
    Join Date
    Nov 2007
    Location
    New Mexico, USA
    Posts
    23
    Vote Rating
    1
    lukerahl is on a distinguished road

      0  

    Default


    The previous post does fix the setLoading function call, but it does not fix the masking of grid panels or views.

  5. #5
    Sencha User
    Join Date
    Oct 2012
    Posts
    16
    Vote Rating
    0
    corneadoug is on a distinguished road

      0  

    Default


    Thank you for the fix, doesn't work perfectly for me though
    I tried to make some modification but couldn't fix it:
    - The x-mask-msg is sometimes not centered (usually happen when we create the component at the same time, so it may be because the setLoading should be in a afterRender function) (was working without the fix)
    - With the fix, the loadMask doesn't resize with the component anymore.

    maybe both issues are related

    But thanks to your fix, we can move the component, or scroll around and the loadMask will follow it

  6. #6
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    1
    bocong is on a distinguished road

      1  

    Default


    I think this bug is still not fixed in 4.2.0?

    The reason that the mask stays at the initial position is because the LoadMask will render dom in the body level, while the Element.mask is rendered directly in the element.
    So I wrote a grid plugin to fix the mask issue during store loading.
    https://github.com/twinssbc/extjs-GridMaskBinder

  7. #7
    Sencha User
    Join Date
    Jul 2009
    Posts
    24
    Vote Rating
    0
    bbg is on a distinguished road

      0  

    Default


    v 4.2.2 - still not fixed

  8. #8
    Sencha User
    Join Date
    Dec 2007
    Location
    Stockholm, Sweden
    Posts
    12
    Vote Rating
    1
    Phantom is on a distinguished road

      0  

    Default


    Hi, I've had the same problem, so i had to create the following override that fixes the problem:

    Code:
    Ext.define('overrides.AbstractView', {
        override : 'Ext.view.AbstractView',
    
        // Force load mask target to be an inner DOM Element of a owner panel instead of current view
        // in order to fix load mask positioning when scrolling
        onRender : function() {
            var me = this, targetEl, cfg, mask = me.loadMask, owner = me.ownerCt;
    
            if ((mask) && (owner)) {
                targetEl = owner.getEl();
                targetEl.componentLayoutCounter = 1;
                targetEl.rendered = true;
    
                cfg = {
                    target : targetEl
                };
    
                me.loadMask = (Ext.isObject(mask)) ? Ext.applyIf(me.loadMask, cfg) : cfg;
            }
    
            me.callParent(arguments);
        }
    });
    Hope it will be helpful to someone.

  9. #9
    Sencha Premium Member
    Join Date
    Dec 2011
    Posts
    236
    Vote Rating
    3
    ypandey is on a distinguished road

      0  

    Default fixed with scroll but loadmask not centered

    fixed with scroll but loadmask not centered


    Hi, Even I tried same approach. But if i apply mask on el instead.
    The mask message stays at top-left of the component.
    Anyway to keep it on center?

  10. #10
    Sencha User
    Join Date
    Dec 2007
    Location
    Stockholm, Sweden
    Posts
    12
    Vote Rating
    1
    Phantom is on a distinguished road

      0  

    Default


    Quote Originally Posted by rpoddar View Post
    Hi, Even I tried same approach. But if i apply mask on el instead.
    The mask message stays at top-left of the component.
    Anyway to keep it on center?
    Hi,
    that's strange, because with the override from above i have no problems with scrolling nor with positioning, i.e. loadMask is centered to the owner components box just as it should be. And I am pretty sure that I didn't do any other fixes than that one.

    P.S. I use ExtJS 4.2.2.1144 currently, but that fix used to work well even with 4.2.0.663 and 4.2.1.883