PDA

View Full Version : Supress TreePanel loading automatically



jpcook01
7 Sep 2011, 3:30 AM
Hello,

I have the following treepanel:



Ext.define('NavBuilder.SitemapList', {
extend: 'Ext.tree.Panel',
alias: 'widget.sitemaplist',

//rootVisible: false,

initComponent: function(){

Ext.apply(this, {
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop'

},
listeners: {
drop: function (node, data, overModel, dropPosition, options ) {
var treePanel = this.ownerCt;
treePanel.down('#saveButton').setDisabled(false);
}
}
},
store: Ext.create('Ext.data.TreeStore', {
model: 'NavBuilder.NavigationNode',
root: {
expanded: true,
text: 'SiteName',
id: 'rootNode'
},
proxy: {
type: 'ajax',
url: 'sitemap/candy-v6/highweb/domestic'
}
}),
dockedItems: [{
itemId: 'toolbar',
xtype: 'toolbar',
items: [{
xtype:'combo',
forceSelection: true,
editable: false,
fieldLabel: 'Sitemap',
labelWidth: 50,
mode: 'local',
width: 270,
name: 'selectsitemapcombo',
itemId: 'selectsitemapcombo',
displayField: 'uri',
valueField: 'uri',
selectOnFocus: true,
store: Ext.create('Ext.data.Store', {
model: 'NavBuilder.SitemapItem',
proxy: {
type: 'ajax',
url: 'sitemap/list'
},
autoLoad: true,
listeners: {
load: function(store, records, successful, operation, eOpts ){
sitemapcombo.setValue(store.getAt(0).get('uri'));
}
}

}),
listeners: {
select: function(combo, records, eOpts){
var uri = records[0].get('uri');
tree.getStore().getProxy().url = 'sitemap/'+uri;
tree.getStore().load();
}
}
}, {
xtype: 'tbseparator'
}, {
itemId: 'expandAll',
text: 'Expand All',
handler: this.onExpand
}, {
xtype: 'tbseparator'
}, {
itemId: 'collapseAll',
text: 'Collapse All',
handler: this.onCollapse
}, {
xtype: 'tbseparator'
}, {
itemId: 'refresh',
text: 'Refresh',
handler: this.onRefresh
}, {
xtype: 'tbseparator'
}, {
itemId: 'saveButton',
text: 'Save',
disabled: true,
handler: this.onSave
}
]
}],
listeners: {
itemcontextmenu: function(view, rec, node, index, e) {
e.stopEvent();
menu.showAt(e.getXY());
return false;
}
}
});
this.callParent();
this.getSelectionModel().on({
scope: this,
select: this.onSelect
});
var menu = Ext.create('NavBuilder.ContextMenu', { tree: this});
var sitemapcombo = this.down('#selectsitemapcombo');
},


You will see that the url for the remote store is hard coded to: 'sitemap/candy-v6/highweb/domestic'

But what I would like to do is set it to the first item which appears in the combo-box which is part of the docked items of the tree panel but this doesn't appear to be possible.

I tried passing a method to the url config option which then called an ajax request but this was all a bit messy.

Is there not an easy way to do this, it seems like an obvious piece of functionality to be able to select an item from a combo and load the data into a tree. This part is actually working, it is just the initial load which is causing problems.

Thanks

skirtle
8 Sep 2011, 2:15 AM
I'm not sure what you mean by the 'initial load'. Do you mean the tree's store is trying to load results before you've set a suitable URL? If so then I'd try setting the root to collapsed rather than expanded.

If you don't like setting the proxy URL in that way then one alternative might be to call setProxy() instead. May feel like overkill but at least it's documented.

jpcook01
9 Sep 2011, 12:46 AM
Perhaps I didn't explain it very well. Sorry. Basically what gets loaded into the tree panel is dependent on what is loaded into the combo drop down from that remote store. So once that combobox has loaded the first url in it should be used to load the treepanel.

However the problem I am having is that you have to load something into a treepanel when it loads as you have to specify a url for the treestore it is using.

One idea i Had was to load the treepanel initially with an empty store and then change the store when the combo populates and an item is selected.

Hope that makes sense.
Jon

skirtle
9 Sep 2011, 1:40 AM
Yes, you could do it with a store switch if you don't mind using undocumented methods. An alternative would be to set the initial root node to be a leaf and then switch it when you're ready to load the data.

jpcook01
9 Sep 2011, 2:12 AM
Thanks, How do you do a store switch?

I did get a bit further. I used the original store with a default proxy and then tried to change the proxy and reload the tree like so:



var tree = this.ownerCt.ownerCt;
tree.getStore().setProxy({
type: 'ajax',
url: 'sitemap/'+newValue
});
tree.getStore().load();


But it calls the new url twice and then tries to load both results into the tree, when the second load occurs you get an error: records[i] is undefined followed by duplicated data in the tree.

Thanks

skirtle
9 Sep 2011, 2:20 AM
I was talking rubbish, you can switch the store using documented methods. Use reconfigure():

http://docs.sencha.com/ext-js/4-0/#!/api/Ext.panel.Table-method-reconfigure

skirtle
9 Sep 2011, 2:22 AM
I'd also advise using a component query rather than this.ownerCt.ownerCt to grab the tree.

jpcook01
9 Sep 2011, 2:40 AM
using reconfigure has the same effect with the url for the store being called twice.

jpcook01
9 Sep 2011, 2:44 AM
So for example:



onChange: function(combo, newValue, oldValue, eOpts) {
var tree = this.ownerCt.ownerCt;

if(newValue!=null){
console.log(newValue);


var tree = this.ownerCt.ownerCt;
//tree.getStore().setProxy({
// type: 'ajax',
// url: 'sitemap/'+newValue
//});

var anotherStore = Ext.create('NavBuilder.TreePanelStore1');
anotherStore.getProxy().url = 'sitemap/'+newValue;
console.log(anotherStore);

var records = anotherStore.load();
//console.log(records.tree.root);

//tree.expandAll();
//tree.show();

//tree.reconfigure(anotherStore);
//tree.getStore().load();
//tree.getStore().load(anotherStore);

//tree.setRootNode(records.tree.root);
//tree.getStore().getRootNode().data.text = newValue;

//console.log(tree.getStore());
}


This line: var records = anotherStore.load(); results in two http calls to the same url which is the problem I think.

It doesn't matter which way I try it. Would it be something to do with it being in the onChange handler?

Jon

skirtle
9 Sep 2011, 2:54 AM
Could you just confirm that no requests get sent when you remove the call to load()?

What about doing a switch on the root node instead?

skirtle
9 Sep 2011, 3:01 AM
I've just had a quick look through the release notes and it seems there was a problem fixed in 4.0.2 with comboboxes firing the change event twice. Are you using 4.0.0 or 4.0.1?

I'm also a little worried by your use of a method called onChange(). Where have you put that method? If it's on the combobox it might be the source of your problems. Combobox already has a method called onChange() and you don't appear to be calling the superclass version. I also wonder whether you're registering this as a listener on the change event?

jpcook01
9 Sep 2011, 3:35 AM
yes when removing load no calls are made. Have to call load before calling trying to reset the root node which I tried.

jpcook01
9 Sep 2011, 3:40 AM
Thanks for your help, this is full combobox: I am just using the build in change listener and calling a function. Below is me playing around. I probably will end up with just change but was playing around with select as well which works fine.



/*
* A combo box for selecting different sitemaps
* @author cookj02
*/
Ext.define('NavBuilder.SitemapComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.sitemapcombo',

initComponent: function(){
Ext.apply(this, {
forceSelection: true,
editable: false,
fieldLabel: 'Sitemap',
labelWidth: 50,
mode: 'local',
width: 270,
name: 'selectsitemapcombo',
itemId: 'selectsitemapcombo',
displayField: 'uri',
valueField: 'uri',
selectOnFocus: true,
store: Ext.create('NavBuilder.SitemapComboStore', { sitemapcombo: this }),
listeners: {
select: this.onSelect
//change: this.onChangeTest
}
});
this.callParent();
},

onChangeTest: function(combo, newValue, oldValue, eOpts) {
var tree = this.ownerCt.ownerCt;

if(newValue!=null){
console.log(newValue);
var tree = this.ownerCt.ownerCt;
//tree.getStore().setProxy({
// type: 'ajax',
// url: 'sitemap/'+newValue
//});

//anotherStore = Ext.create('NavBuilder.TreePanelStore1');
//anotherStore.getProxy().url = 'sitemap/'+newValue;
//console.log(anotherStore);

//var records = anotherStore.load();
//console.log(records.tree.root);

//tree.expandAll();
//tree.show();

//tree.reconfigure(anotherStore);
//tree.getStore().load();
//tree.getStore().load(anotherStore);

//tree.setRootNode(records.tree.root);
//tree.getStore().getRootNode().data.text = newValue;

//console.log(tree.getStore());
}
},

onSelect: function(combo, records, eOpts){
var tree = this.ownerCt.ownerCt;
var uri = records[0].get('uri');
tree.getStore().getProxy().url = 'sitemap/'+uri;
tree.getStore().getRootNode().data.text = uri;
tree.getStore().load();
}
});

jpcook01
9 Sep 2011, 3:43 AM
We are using ext-4.0.2a as far as I can tell. Is there a definitive way to check.

jpcook01
9 Sep 2011, 3:43 AM
definitely in fact: 8,619: Ext.setVersion('extjs', '4.0.2a');

skirtle
9 Sep 2011, 6:42 AM
OK, the following worked for me with 4.0.2.


Ext.define('NavBuilder.SitemapComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.sitemapcombo',

initComponent: function(){
Ext.apply(this, {
...
listeners: {
change: this.onChangeHandler
}
});

this.callParent();
},

onChangeHandler: function(combo) {
var tree = combo.up('treepanel');
var store = tree.getStore();

store.setProxy({
type: 'ajax',
url: 'sitemap/' + combo.getValue()
});

tree.setRootNode({
expanded: true
});
}
});

Ext.create('Ext.tree.Panel', {
height: 300,
renderTo: Ext.getBody(),
rootVisible: false,
width: 300,
root: {
leaf: true,
text: 'Root'
},
tbar: [{
xtype: 'sitemapcombo'
}]
});

jpcook01
9 Sep 2011, 6:48 AM
So you aren't calling load()?

skirtle
9 Sep 2011, 6:52 AM
Nope.

Setting the root to a new expanded node both clears the old tree and kicks off a load.

jpcook01
9 Sep 2011, 6:53 AM
It works! What a legend :) So I guess when you set the proxy it loads the store? Thanks very much for your help and replying.