tags:

views:

355

answers:

3

been struggling with an issue now for a day or two. I have an Ext.Window that contains 2 combo-boxes. on the first load everything works fine, both stores are populated and the combo's work as they should.

However, if I .show() the window a second time, the combo boxes do not "drop down" to display the lists. I have checked Firebug and there are no entries being added to the combo boxes although the stores are being populated.

Here is the code of the Window:

uTransferWindow = new Ext.Window({
                id              : 'windowUserLicenseTransfer',
                title           : 'Title',
                width           : 405,
                autoScroll      : true,
                closeAction     : 'hide',
                closable        : false,
                modal           : true,
                bodyStyle       : 'background-color:#FFF',
                buttonAlign     : 'center',
                items           : new Ext.form.FormPanel({
                    labelAlign      : 'left',
                    labelWidth      : 140,
                    bodyStyle       : 'padding:10px 10px 0 10px',
                    border          : false,
                    defaults: {
                        xtype: 'ComboBox',
                        anchor: '100%',
                        tpl: '<tpl for="."><div class="x-combo-list-item"><div style="position:absolute;left:4px;">{initials}</div><div style="position:relative;left:50px;">{username}</div></div></tpl>',
                        displayField: 'username',
                        valueField: 'userid',
                        typeAhead: true,
                        mode: 'local',
                        triggerAction: 'all'
                    },
                    items: [{
                        hiddenName: 'fromuserid',
                        fieldLabel: 'From User',
                        id          : 'drop1',
                        store: userswithlicenses
                    }, {
                        hiddenName: 'touserid',
                        fieldLabel: 'To User',
                        id          : 'drop2',
                        store: userswithoutlicenses
                    }]
                }),
                buttons     : [{
                    text        : 'Transfer License',
                    handler     : function() {
                        //do stuff
                    }
                }, {
                    text: 'Cancel',
                    handler: function() { uTransferWindow.hide(); }
                }]
            }),

I have not been able to find anyone else with a similar problem on the forums, any help would be appreciated.

UPDATE: found something small though: When the Window is shown the second time around the z-index has indeed increased. Why would the z-index increase each time the window is shown?

A: 

You'd better not show/hide the window but create a new one and close it when needed. This can be achieved by using Ext.extend, like

TransferWindow = Ext.extend(Ext.Window, {
/*Lots of code*/
});

// some time later.

var uTransferWindow = new TransferWindow();
uTransferWindow.show();

I'm sure that this approach will help to solve the problem you're experiencing and will preserve html code from keeping hidden windows.

P.S. You may also consider using namespaces (Ext.namespace).

Li0liQ
Hmm. Don't agree that you should always close and recreate windows. Just need to make sure that you manage state appropriately. Also, I'm not sure what Ext.extend has to do with creating and closing windows... ? That's simply a pattern for reusing a common configuration multiple times.
bmoeskau
@bmoeskau It seems that there is some flaw in hiding and showing the window that can be seen in this particular question. Also the hidden window will still remain rendered in the page whereas the destroyed(closed) won't.
Li0liQ
I know how windows work. I don't know what that has to do with Ext.extend.
bmoeskau
@bmoeskau Ext.extend has nothing to do with Ext.Window.show or similar unless you want it to do:). My only concern is that using Ext.extend will help you write neater code while instantiating a new window.
Li0liQ
+1  A: 

Make sure you aren't calling new Ext.Window multiple times - since you are hiding the window instead of destroying if you call new on it with the same config the id's of the combo boxes will conflict and have the behavior you are describing.

sdavids
will check that out, if I recall correctly, there are 2 or 3 windows on that page! thanks.
FailBoy
although they didn't have the same configs, but destroying and recreating the window when needed has solved this issue.
FailBoy
A: 

I had this same issue and it is a z-index issue (firebug shows this to be the case). The list for the combo is not contained within the window's div, and therefore the window's z-index changes do not cascade to the list view. Regardless, I didn't notice the window updating its z-index everytime I showed it, but subsequent windows that were opened would receive a higher z-index. This is when I received the problem, opening multiple windows.

In my case I have extended Ext.Window and used that extension everywhere, so I simply placed a "beforeshow" listener on my extension inside its initComponent, like so:

    initComponent: function(){
   ... // I put the listener as the last line
   this.on("beforeshow", this.fixComboDropdowns, this);

},
/**
 * When opening multiple windows within an application, combo box list values' zIndex
 * can become out-of-sync and cause the list to not show its values.  This
 * method is to help prevent that from occurring.
 */
fixComboDropdowns: function(win){
    try{
        var zIndex = parseInt(win.getEl().getStyle("z-index"));
        // retrieve the combo boxes contained in this window.
        // call each combo boxes' getListParent() method, and set the list parent's zindex.
        var combos = win.findByType("combo");
        if(combos && combos.length > 0){
            if(WINDOW_ZINDEX === 0 || WINDOW_ZINDEX < zIndex){
                WINDOW_ZINDEX = zIndex + 100;
            }
            else{
                WINDOW_ZINDEX = WINDOW_ZINDEX + 100;
            }

            for(var index = 0; index < combos.length; index = index + 1){
                // set each combo's z-index style:
                var combo = combos[index];
                var listEl = combos[index].getListParent();
                if(listEl && listEl.style){
                    listEl.style.zIndex = WINDOW_ZINDEX + 10; // make sure the combo's list will display.
                }
            }
        }
    }catch(ex){
        if(console){
            console.error(ex);
        }
    }
    return true;
}

Oh, don't forget to define the global WINDOW_ZINDEX variable like so: var WINDOW_ZINDEX = 0;

I'm sure the above code can be refined, but you get the general idea. Some items I haven't been able to verify: 1). What if the popup window is setting focus on a field? Does the above remove that focus?

If you don't have an override for Ext.Window, then consider using the factory pattern, where you can create the Ext.Window, and then place the "beforeshow" listener on it before returning it back to the caller.

If the factory pattern is not an option, then consider placing an interceptor on the Ext.Window's beforeShow method, or override it.

extjs-guy
Also, in lieu of the above suggsted fix, try lazyInit: false in the combo's configuration if you can. That should resolve the issue. With lazyInit being false, you will want to check the performance of the window opening.
extjs-guy