Success! Looks like we've fixed this one. According to our records the fix was applied for EXTJS-7460 in a recent build.
  1. #1
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    905
    Vote Rating
    40
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      1  

    Default [4.1.x] LoadMask always in front when owner has a parent container

    [4.1.x] LoadMask always in front when owner has a parent container


    REQUIRED INFORMATION


    Ext version tested:
    • Ext 4.1.0
    • Ext 4.1.2a

    Browser versions tested against:
    • Firefox 15
    • Chrome
    • IE9

    DOCTYPE tested against:
    • Default

    Description:
    • Been trying to track down why, in our application, load masks appear from grids and trees, say, appear in front of open windows.
    • Can't remember when the issue started, but I think has been around for at least a few versions of Ext 4, possibly all.
    • First tried to reproduce with a simple test case, and couldn't. After much debugging, logging and trying different overrides I think I have something.

    Steps to reproduce the problem:
    • Put a grid inside a container.
    • Show a window, and put it over the grid.
    • Load the store on the grid.

    The result that was expected:
    • The load mask on the grid should appear behind the open window.

    The result that occurs instead:
    • The load mask, and mask message div, appear in front of the open window.

    Test Case:


    Code:
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Ext Testing</title>
    
    
    
    
        <!-- Ext includes -->
        <script type="text/javascript" src="/ext4.1.2/ext-all-debug.js"></script>
        <!-- <script type="text/javascript" src="/Altus/app/FrameworkFixes.js"></script> -->
    
    
        <!-- CSS -->
        <link rel="stylesheet" href="/ext4.1.0/resources/css/ext-all.css" type="text/css">
    
    
    
    
        <script type="text/javascript">
            Ext.require([
                'Ext.grid.*',
                'Ext.data.*',
                'Ext.util.*',
                'Ext.state.*'
            ]);
    
    
            Ext.require('Ext.LoadMask',
                function() {
                    Ext.override(Ext.LoadMask, {
                        onShow: function() {
                            if (Ext.global.console) {
                                Ext.global.console.log('Ext.LoadMask.onShow', Ext.WindowManager.zIndexStack);
                            }
    
    
                            // Uncomment this to see the desired behaviour
                            // Note: Not sure this is a valid fix, since not sure when preventBringToFront should be falsey.
                            // this.preventBringToFront = true;
    
    
                            this.callParent(arguments);
                        }
                    });
                }
            );
    
    
            // Define Company entity
            // Null out built in convert functions for performance *because the raw data is known to be valid*
            // Specifying defaultValue as undefined will also save code. *As long as there will always be values in the data, or the app tolerates undefined field values*
            Ext.define('Company', {
                extend: 'Ext.data.Model',
                fields: [
                   {name: 'company'},
                   {name: 'price',      type: 'float', convert: null,     defaultValue: undefined},
                   {name: 'change',     type: 'float', convert: null,     defaultValue: undefined},
                   {name: 'pctChange',  type: 'float', convert: null,     defaultValue: undefined},
                   {name: 'lastChange', type: 'date',  dateFormat: 'n/j h:ia', defaultValue: undefined}
                ],
                idProperty: 'company'
            });
    
    
            Ext.onReady(function() {
                Ext.QuickTips.init();
    
    
                // sample static data for the store
                var myData = [
                    ['3m Co',                               71.72, 0.02,  0.03,  '9/1 12:00am'],
                    ['Alcoa Inc',                           29.01, 0.42,  1.47,  '9/1 12:00am'],
                    ['Altria Group Inc',                    83.81, 0.28,  0.34,  '9/1 12:00am'],
                    ['American Express Company',            52.55, 0.01,  0.02,  '9/1 12:00am'],
                    ['American International Group, Inc.',  64.13, 0.31,  0.49,  '9/1 12:00am'],
                    ['AT&T Inc.',                           31.61, -0.48, -1.54, '9/1 12:00am'],
                    ['Boeing Co.',                          75.43, 0.53,  0.71,  '9/1 12:00am'],
                    ['Caterpillar Inc.',                    67.27, 0.92,  1.39,  '9/1 12:00am'],
                    ['Citigroup, Inc.',                     49.37, 0.02,  0.04,  '9/1 12:00am'],
                    ['E.I. du Pont de Nemours and Company', 40.48, 0.51,  1.28,  '9/1 12:00am'],
                    ['Exxon Mobil Corp',                    68.1,  -0.43, -0.64, '9/1 12:00am'],
                    ['General Electric Company',            34.14, -0.08, -0.23, '9/1 12:00am'],
                    ['General Motors Corporation',          30.27, 1.09,  3.74,  '9/1 12:00am'],
                    ['Hewlett-Packard Co.',                 36.53, -0.03, -0.08, '9/1 12:00am'],
                    ['Honeywell Intl Inc',                  38.77, 0.05,  0.13,  '9/1 12:00am'],
                    ['Intel Corporation',                   19.88, 0.31,  1.58,  '9/1 12:00am'],
                    ['International Business Machines',     81.41, 0.44,  0.54,  '9/1 12:00am'],
                    ['Johnson & Johnson',                   64.72, 0.06,  0.09,  '9/1 12:00am'],
                    ['JP Morgan & Chase & Co',              45.73, 0.07,  0.15,  '9/1 12:00am'],
                    ['McDonald\'s Corporation',             36.76, 0.86,  2.40,  '9/1 12:00am'],
                    ['Merck & Co., Inc.',                   40.96, 0.41,  1.01,  '9/1 12:00am'],
                    ['Microsoft Corporation',               25.84, 0.14,  0.54,  '9/1 12:00am'],
                    ['Pfizer Inc',                          27.96, 0.4,   1.45,  '9/1 12:00am'],
                    ['The Coca-Cola Company',               45.07, 0.26,  0.58,  '9/1 12:00am'],
                    ['The Home Depot, Inc.',                34.64, 0.35,  1.02,  '9/1 12:00am'],
                    ['The Procter & Gamble Company',        61.91, 0.01,  0.02,  '9/1 12:00am'],
                    ['United Technologies Corporation',     63.26, 0.55,  0.88,  '9/1 12:00am'],
                    ['Verizon Communications',              35.57, 0.39,  1.11,  '9/1 12:00am'],
                    ['Wal-Mart Stores, Inc.',               45.45, 0.73,  1.63,  '9/1 12:00am']
                ];
    
    
                /**
                 * Custom function used for column renderer
                 * @param {Object} val
                 */
                function change(val) {
                    if (val > 0) {
                        return '<span style="color:green;">' + val + '</span>';
                    } else if (val < 0) {
                        return '<span style="color:red;">' + val + '</span>';
                    }
                    return val;
                }
    
    
                /**
                 * Custom function used for column renderer
                 * @param {Object} val
                 */
                function pctChange(val) {
                    if (val > 0) {
                        return '<span style="color:green;">' + val + '%</span>';
                    } else if (val < 0) {
                        return '<span style="color:red;">' + val + '%</span>';
                    }
                    return val;
                }
    
    
                // create the data store
                var store = Ext.create('Ext.data.ArrayStore', {
                    model: 'Company',
                    data: myData
                });
    
    
                // create the Grid
                var grid = Ext.create('Ext.grid.Panel', {
                    store: store,
                    stateful: true,
                    collapsible: true,
                    multiSelect: true,
                    stateId: 'stateGrid',
                    columns: [
                        {
                            text     : 'Company',
                            flex     : 1,
                            sortable : false,
                            dataIndex: 'company'
                        },
                        {
                            text     : 'Price',
                            width    : 75,
                            sortable : true,
                            renderer : 'usMoney',
                            dataIndex: 'price'
                        },
                        {
                            text     : 'Change',
                            width    : 75,
                            sortable : true,
                            renderer : change,
                            dataIndex: 'change'
                        },
                        {
                            text     : '% Change',
                            width    : 75,
                            sortable : true,
                            renderer : pctChange,
                            dataIndex: 'pctChange'
                        },
                        {
                            text     : 'Last Updated',
                            width    : 85,
                            sortable : true,
                            renderer : Ext.util.Format.dateRenderer('m/d/Y'),
                            dataIndex: 'lastChange'
                        }
                    ],
                    height: 350,
                    width: 600,
                    title: 'Array Grid',
                    renderTo: Ext.getBody(),
                    viewConfig: {
                        stripeRows: true,
                        enableTextSelection: true
                    },
                    bbar: [
                        {
                            xtype: 'button',
                            text: 'Open Window',
                            handler: function() {
                                Ext.create('Ext.window.Window', {
                                    html: 'Some content',
                                    width: 600,
                                    height: 300,
                                    buttons: [
                                        {
                                            xtype: 'button',
                                            text: 'Set loading(true)',
                                            handler: function(button) {
                                                grid.setLoading(true);
                                            }
                                        },
                                        {
                                            xtype: 'button',
                                            text: 'Set loading(false)',
                                            handler: function(button) {
                                                grid.setLoading(false);
                                            }
                                        }
                                    ]
                                }).show();
                            }
                        }
                    ]
                });
    
    
                // Comment this out to see behaviour when not in an owner container
                Ext.create('Ext.container.Viewport', {
                    renderTo: Ext.getBody(),
                    items: [
                        grid
                    ]
                });
            });
        </script>
    
    
    </head>
    <body>
    </body>
    </html>

    HELPFUL INFORMATION


    Screenshot or Video:
    • None.

    Debugging already done:
    • Enough to produce this report!

    Possible fix:
    • Don't think my fix is the one, but could be.
    • Can uncomment an override of onShow in my example to see the effect.
    • How about, in Ext.LoadMask:
      Code:
          bindComponent: function(comp){
              var me = this,
                  listeners = {
                      scope: this,
                      resize: me.sizeMask,
                      added: me.onComponentAdded,
                      removed: me.onComponentRemoved
                  },
                  hierarchyEventSource = Ext.container.Container.hierarchyEventSource;
                  
              if (comp.floating) {
                  listeners.move = me.sizeMask;
                  me.activeOwner = comp;
              } else if (comp.ownerCt) {
                  me.onComponentAdded(comp.ownerCt);
      // <WestyFix>
      //        } else {
      //            // if the target comp is non-floating and under a floating comp don't bring the load mask to the front of the stack
      //            me.preventBringToFront = true;
              }
      
      
              me.preventBringToFront = !comp.floating;
      // </WestyFix>
      
      
              me.mon(comp, listeners);
              
              // subscribe to the observer that manages the hierarchy
              me.mon(hierarchyEventSource, {
                  show: me.onContainerShow,
                  hide: me.onContainerHide,
                  expand: me.onContainerExpand,
                  collapse: me.onContainerCollapse,
                  scope: me
              });
          },
    • It's something like this anyway; needs someone with knowledge of what the original intention was to look at it (/stares at Nige).

    Operating System:
    • Windows 7 Professional x64
    Product Architect
    Altus Ltd.

  2. #2
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,502
    Vote Rating
    47
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


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

  3. #3
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,502
    Vote Rating
    47
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    The fix is

    Code:
    Ext.override(Ext.LoadMask, {
        onComponentAdded: function(owner){
            var me = this;
            delete me.activeOwner;
            me.floatParent = owner;
            if (!owner.floating) {
                owner = owner.up('[floating]');
            }
            if (owner) {
                me.activeOwner = owner;
                me.mon(owner, 'move', me.sizeMask, me);
            } else {
                me.preventBringToFront = true;
            }
            owner = me.floatParent.ownerCt;
            if (me.rendered && me.isVisible() && owner) {
                me.floatOwner = owner;
                me.mon(owner, 'afterlayout', me.sizeMask, me, {single: true});
            }
        }
    });

  4. #4
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    905
    Vote Rating
    40
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    Nice one, thanks!
    Product Architect
    Altus Ltd.

Thread Participants: 1

Tags for this Thread