PDA

View Full Version : TabPanel showing wrong dynamic Panels at switch [STILL UNSOLVED]



feyyaz
16 Dec 2010, 2:21 AM
Hi,

right now i am working very hard to get this running, but no luck so far, maybe someone can point me in the right direction.

I am adding dynamically created Panels to a TabPanel, since I remove, add or change position of additional panels frequently. I always remove all panels and add them updated again. But after the the first removal the display behavior is absolutly off.

To reproduce this, just replace the js code in extjs/examples/tabs/tabs-adv.js with following code (don't forget do backup the original source):

Or use this link (only for a short time available) http://www.gallery-print.de/extjs_sample/examples/tabs/tabs-adv.html



/*!
* Ext JS Library 3.3.0
* Copyright(c) 2006-2010 Ext JS, Inc.
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){
var mc = new Ext.util.MixedCollection();

var gStore = new Ext.data.ArrayStore({
fields: ['fullname', 'first'],
idIndex: 0 // id for each record will be the first element
});

var tabs = new Ext.TabPanel({
renderTo:'tabs',
resizeTabs:true, // turn on tab resizing
minTabWidth: 60,
tabWidth:60,
enableTabScroll:true,
width:600,
height:250,
defaults: {autoScroll:true}
});

// tab generation code
var index = 0;
function addTab() {
for(var i=0;i<3;i++)
mc.add(new Ext.Panel({
title: 'Tab ' + (++index),
layout: 'hbox',margins: '5 0 0 0',flex: 5,layoutConfig: {align: 'stretch'},
items: [{xtype: 'container',flex: 1,layout: 'vbox',layoutConfig: {align: 'stretch'},
items: [{xtype: 'grid',id:'-dst-grid'+index,store: gStore,flex: 1,
sm: new Ext.grid.RowSelectionModel(),
columns: [{xtype: 'gridcolumn',header: 'Tab Grid I ('+index+')'}]}]}]
}));

var active = tabs.getActiveTab();
if(!Ext.isObject(active)) active=0;

tabs.removeAll(false); // false, to prevent the destruction of the Panels
tabs.add(mc.getRange());

tabs.setActiveTab(active);
}

new Ext.Button({
text: 'Add Tab',
handler: addTab,
iconCls:'new-tab'
}).render(document.body, 'tabs');
});
If you just press the "Add tabs" button twice, you get 6 tabs (2 x 3 tabs, on the second click the first three tabs get deleted and are added again with the 3 new one) , now press on tab 4-5-6 and see what is happening, it always shows tab 2, if you press tab 2 and then on tab 4-5-6 he shows tab 3. but after pressing on tab 3 all tabs working as they should from the begining.


I use Ext.ux.MixedCollection to store the panels, because there i can simply implement sorting.

I hope that there is a soulution for this. But the fact that i have to remove all first ist mandatory, because i need ordering the tabs, and i don't see how to change the positions over the TabPanel class.

Thanks

Seana
16 Dec 2010, 2:02 PM
you are getting 6 tabs because while you are removing the tabs from your tabpanel you are never "clearing" them from your mixed collection. so every time you run "addTab()" you are adding 3 more tabs to the already existing MixedCollection. So every call of addTab() really just adds 3 more tabs to all the tabs you already had.

When dealing with the reordering of Tabs I quickly realized that the TabPanel doesn't "care" about order. I had the requirement of only ever moving 1 tab and "sliding" the others...

As long as that works for you the code (which I admittedly don't have available at the moment) went something like the following, granted there were safety checks that I'm not adding just to demonstrate the concept...

moveTab() takes an array of tab id's (strings)


moveTab: function(tabOrder){
var t1 = tabPanel.getComponent(tabOrder[0]);
var t2 = tabPanel.getComponent(tabOrder[1]);
var i2 = tabPanel.items.indexOf(t2);

tabPanel.remove(t1, false);
tabPanel.insert(i2, t1);
}


I believe I also would "cache" the active tab... Not sure if this is exactly what you want

feyyaz
16 Dec 2010, 3:23 PM
hi seana,

that i am getting 6 tabs is by design. that is so to demonstrate the dynamic insertion of additional tabs. and there is the problem. the direct problem is that after adding the second set of tabs, that tab 4-5-6 are not shown, when selected (if you don't select tab2 and tab3 before)

i will try your approch tonight removing and adding one by one.

second try will be a overwritten TabPanel class so i can work directly on the MixedCollection used in it.

i will post my results later on.

still then additional suggestions are welcome.

PS: in my example i already preserving the active tab :)

darthwes
16 Dec 2010, 4:22 PM
function addTab() {
for (var i = 0; i < 3; i++) {
mc.add(new Ext.Panel({
title: 'Tab ' + (++index),
layout: 'hbox',
margins: '5 0 0 0',
flex: 5,
layoutConfig: {
align: 'stretch'
},
items: [{
xtype: 'container',
flex: 1,
layout: 'vbox',
layoutConfig: {
align: 'stretch'
},
items: [{
xtype: 'grid',
id: '-dst-grid' + index,
store: gStore,
flex: 1,
sm: new Ext.grid.RowSelectionModel(),
columns: [{
xtype: 'gridcolumn',
header: 'Tab Grid I (' + index + ')'
}]
}]
}]
}));


/*var active = tabs.getActiveTab();
if (!Ext.isObject(active)) active = 0;

tabs.removeAll(false); // false, to prevent the destruction of the Panels
tabs.add(mc.getRange());

tabs.setActiveTab(active);*/

tabs.add(mc.get(mc.length - 1));
}
tabs.doLayout();
}

feyyaz
16 Dec 2010, 4:44 PM
hi darthwes,

your version is working and all tabs get shown like expected. but one crucial point is missing - sorting. in my example i left that part out to minimize the code. but lets say every panel has a position attribute and with every tab addition it gets shuffelt. than i would write following code (read comments in the code example)



// lets expect every panel has position attribute (panel.position)
var active = tabs.getActiveTab();
if(!Ext.isObject(active)) active=0;

// now order the MixedCollection
// 'a' and 'b' are two compared panels
mc.sort('ASC', function(a,b) {
return a.position-b.position;
});

// now i don't know where every panel is (for example the previous
// 'first panel' could be at the end now). that's the reason why i can't
// just add the new panels. I remove all panels and afterwards add them
// out of the collection in there new order.
tabs.removeAll(false); // false, to prevent the destruction of the Panels
tabs.add(mc.getRange());

tabs.setActiveTab(active);

darthwes
16 Dec 2010, 6:02 PM
function addTab() {
for (var i = 0; i < 3; i++) {
var pos = Math.floor(Math.random() * 1024 + 1);
mc.add(mc.length - 1, new Ext.Panel({
title: 'T' + (++index) + ' ' + pos,
position: pos,
layout: 'hbox',
margins: '5 0 0 0',
//flex: 5,
layoutConfig: {
align: 'stretch'
},
items: [{
xtype: 'container',
flex: 1,
layout: 'vbox',
layoutConfig: {
align: 'stretch'
},
items: [{
xtype: 'grid',
id: '-dst-grid' + index,
store: gStore,
flex: 1,
sm: new Ext.grid.RowSelectionModel(),
columns: [{
xtype: 'gridcolumn',
header: 'Tab Grid I (' + index + ')'
}]
}]
}]
}));
tabs.add(mc.get(mc.length - 1));
}

mc.sort('ASC', function (a, b) {
return a.position - b.position;
});
tabs.removeAll(false);
tabs.add(mc.getRange());
tabs.doLayout();
}

works for me. Is that not what you're trying?

feyyaz
16 Dec 2010, 7:17 PM
yes... perfect! thank you very much.

To point out the difference from your solution to mine:

You add every new panel one by one in the "wrong direction" to the TabPanel, than delete all panels, sort them, and add them again.

I on the other side create new Panels, deleted the old ones, sort them and THEN add them to the TabPanel.

I think that my version is more intuitiv, but all that matters is that it works.

Thanks again!

feyyaz
17 Dec 2010, 1:02 PM
Argh, didn't see the same error as before, since no tab was activated by default.

Now darthwes, take your code version and start it, do following:

1. Press Add Tab
2. Activate one of the created Tabs
3. Press Add Tab again
4. Activate Tab T4, T5 or T6
5. What do you see? In my case it is never T4, T5 or T6.

so, back to the scratchboard.