Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: loadMask does not scroll with components when parent container is scrolled

    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
    27
    Vote Rating
    6
      0  

    Exclamation 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 - Sr Software Engineer mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    39,556
    Vote Rating
    1272
      0  

    Default

    Thanks for the report.
    Mitchell Simoens @LikelyMitch
    Sencha Inc, Senior Software Engineer
    ________________
    Learn BBCode and use it! Checkout the CODE tag!

    Check out my GitHub, lots of nice things for Ext JS and Sencha Touch
    https://github.com/mitchellsimoens

  3. #3
    Ext JS Premium Member lukerahl's Avatar
    Join Date
    Nov 2007
    Location
    New Mexico, USA
    Posts
    27
    Vote Rating
    6
      1  

    Lightbulb 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
    27
    Vote Rating
    6
      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
      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
      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
    25
    Vote Rating
    0
      0  

    Default

    v 4.2.2 - still not fixed

  8. #8
    Sencha User
    Join Date
    Dec 2007
    Location
    Stockholm, Sweden
    Posts
    13
    Vote Rating
    1
      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 User
    Join Date
    Dec 2011
    Posts
    242
    Vote Rating
    6
      0  

    Default 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
    13
    Vote Rating
    1
      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

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

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