PDA

View Full Version : Problem saving state when adding new tabs to a TabPanel



TrotskyIcepick
23 Mar 2010, 6:41 PM
I'm just now learning ExtJS and am playing around with a couple of examples I've found.

I have a window with a TabPanel on the right initially containing 4 tabs, on the left a LinksPanel with 3 links. When I click on a link in the LinksPanel it adds a new tab to the TabPanel.

What I am trying to do is save the state of the TabPanel after new tabs have been added. I can get it to work when the state of the initial 4 tabs changes, but always lose the newly added tabs on a page reload.

The code I am using is as follows:

.
.
.

Ext.state.Manager.setProvider(new Ext.state.CookieProvider());.
.
.

xtype: 'tabpanel',
region: 'center',
activeTab: 0,
stateId: 'tabpanel',
stateEvents: ['tabchange'],
getState: function(){
return {
activeTab: this.items.indexOf(this.getActiveTab())
};
},.
.
.
Any idea if what I'm attempting is even possible? I can't find any examples doing this. Please be gentle, I'm new to programming, not just Ext :-/

Thanks
Andrew

Julio Betta
30 Mar 2010, 8:51 AM
yeah... I have the same question.... :-/:-/:-/:-/

rbastic
30 Mar 2010, 10:17 AM
I'm not 100% sure on how well this will work for you, but what if you stored a cookie (in the client) that had some info about the tabs ? Then you could query the cookie and if it's there, decide how to proceed.

Otherwise, you might have to do some magic using server-side session storage (i.e. 'HttpSession' in Java servlets, etc.)

-Ryan

TrotskyIcepick
30 Mar 2010, 4:10 PM
The code I'm already using stores info on the tab state in a cookie. The problem is storing information about the newly generated tabs....I can't quite figure that out. I think I obviously need to store some kind of state info when tabs are created but I don't know what that info should be :-?

rbastic
31 Mar 2010, 4:41 AM
Ah, I see now.

Okay, I'm no genius when it comes to ExtJS either, haven't specifically done anything with cookies in particular, but what you probably want to do is something like [ go here http://www.extjs.com/deploy/dev/docs/ and search for 'CookieProvider' for the docs ]:



// example, change for your uses
var cp = new Ext.state.CookieProvider({
path: "/cgi-bin/",
expires: new Date(new Date().getTime()+(1000*60*60*24*30)), //30 days

domain: "extjs.com"
});

cp.on("statechange", function(this, key, value) {
// this gets called every time the cookie's state changes
});

Ext.state.Manager.setProvider(cp);



From looking at the docs, there are other methods you would then use, like cp.get(), and cp.set(). You would use these to check other cookie values related to the # of tabs displayed and what links they would be. For instance:

(in your code that adds tabs when links are clicked)



cp.set("yourapp_tabs", cp.encodeValue(something));


and then elsewhere: cp.decodeValue(cp.get("yourapp_tabs")) and then do something with it.

I *think* that's the right track for you. Any gurus want to confirm/assist?

Animal
31 Mar 2010, 4:44 AM
The OP only has half the solution.

You have to implement applyState to DO something with the state you saved. Otherwise, what's to be done with it?

Animal
31 Mar 2010, 4:46 AM
None of rbastic's code is necessary at all.

Just getState and applyState, and a stateId, and setting the CookieProvider.

rbastic
31 Mar 2010, 5:47 AM
I see now. Any chance we can get some documentation or an additional sample in that demonstrates this sort of thing?

The docs weren't immediately clear when I tried to grok them earlier.

Animal
31 Mar 2010, 5:55 AM
http://i131.photobucket.com/albums/p286/TimeTrialAnimal/stateful.jpg

mschwartz
31 Mar 2010, 6:06 AM
Last time I tried using this, it saved state of components by Ext.id() generated IDs. Those change if you change your code, so Ext would try to restore state of who-knows-what from the cookies.

Animal
31 Mar 2010, 6:23 AM
That's what stateId is for.

TrotskyIcepick
1 Apr 2010, 6:33 AM
Sorry about this, I've only started looking into some form of developing in the past week and have chosen Ext because it seems so slick and professional, I am definitely not a programmer. I have looked at everybodies (Animal & rbastic) posts and they do make sense to me. My problem is that I'm not sure where to put the state code into the code I already have (especially since it's Saki's code, and seems a little messy already/:)). I'll paste the code I have into the end of this post. It does save state changes when a new tab is added and becomes the active tab, but since I have not got an applyState specified anywhere the new tabs are forgotten when the page reloads.

TBH, I'm just jumping straight in, I have Jesus Garcia's book ExtJS In Action, and Animal, if you tell me to go back and read it before attempting any more....I will do so:)

Here goes, what I have already:


Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

Ext.ns('Example');

Example.LinksPanel = Ext.extend(Ext.Panel, {

border: false,
cls: 'link-panel',
links: [{
text: 'Link 1',
href: '#'
}, {
text: 'Link 2',
href: '#'
}, {
text: 'Link 3',
href: '#'
}],
layout: 'fit',
tpl: new Ext.XTemplate('<tpl for="links"><a class="examplelink" href="{href}">{text}</a></tpl>'),
afterRender: function(){


Example.LinksPanel.superclass.afterRender.apply(this, arguments);

this.tpl.overwrite(this.body, {
links: this.links
});

}

});

Ext.reg('linkspanel', Example.LinksPanel);

Example.Window = Ext.extend(Ext.Window, {

layout: 'border',
initComponent: function(){

var config = {
items: [{
xtype: 'linkspanel',
region: 'west',
width: 200,
collapsible: true,
collapseMode: 'mini',
split: true
}, {
xtype: 'tabpanel',
region: 'center',
activeTab: 0,
stateId: 'tabpanel',
stateEvents: ['tabchange'],
getState: function(){
return {
activeTab: this.items.indexOf(this.getActiveTab())
};
},
defaults: {
layout: 'fit',
border: false,
bodyStyle: 'padding:8px'
},
items: [{
title: 'First',
html: 'First'
}, {
title: 'Second',
html: 'Second'
}, {
title: 'Third',
html: 'Third'
}, {
title: 'Fourth',
html: 'Fourth'
}]
}]
};


Ext.apply(this, Ext.apply(this.initialConfig, config));

Example.Window.superclass.initComponent.apply(this, arguments);

this.linksPanel = this.items.itemAt(0);
this.tabPanel = this.items.itemAt(1);
this.linksPanel2 = this.items.itemAt(2);

this.linksPanel.on({
scope: this,
render: function(){
this.linksPanel.body.on({
scope: this,
click: this.onLinkClick,
delegate: 'a.examplelink',
stopEvent: true
});
}
});
},
onLinkClick: function(e, t){
var title = t.innerHTML;
var tab = this.tabPanel.items.find(function(i){
return i.title === title;
});
if (!tab) {
tab = this.tabPanel.add({
title: title,
layout: 'fit',
});
}
this.tabPanel.setActiveTab(tab);

}

});
Ext.reg('examplewindow', Example.Window);

Ext.onReady(function(){

Ext.QuickTips.init();


var win = new Example.Window({
width: 600,
height: 400,
closable: true,
stateId: 'window',
title: Ext.fly('page-title').dom.innerHTML
});
win.show();

});I think this is messy, what do you think?

Animal
1 Apr 2010, 7:04 AM
I am definitely not a programmer

Than what are you doing?

I'm not a plumber and so I don't saw my water pipes up and try to add a radiator, and then go to plumbingforums.com for instructions.

rbastic
1 Apr 2010, 7:07 AM
He is a programmer. Just a newbie programmer.
He just doesn't realize it yet.

Besides, anyone can do their own plumbing! That's what plumbingforums.com is for!:D

TrotskyIcepick
1 Apr 2010, 8:09 AM
Thanks rbastic, (I do realize it, I'm just over eager:)), I think Animal is being pretty arrogant since he's obviously a 'programming god'.

Everybody has to start somewhere (you did), I've been in IT as support of some sort or other for a while and have always fancied development, hence trying javascript and Ext (and not jumping in at the deep end with something like C++ or Java).

Animal, instead of the arrogance, just tell me to go away and read my book (ie. learn to walk before I try running), before asking complicated questions on forums;).

I'm only here already because I have a project in mind (something I use on Linux, that I think could be better).

Thanks