I have a treepanel inside my form. The code is
{
xtype:'treepanel',
rootVisible:false,
hidden:true,
autoload:false,
store:{autoload:false,proxy:{type:'ajax',url:'../json/objectList.php?id='+id},root:{text:'Objects',id:'src',expanded:true}},
listeners:{
show:function(){
this.store.load();
}
}
}
The problem is, I want to prevent loading before the tree is shown. But setting autoload to false does not have any effect. I still see a server request, even if the tree is hidden.
The autoLoad property does not work for tree stores as the load is based on the expansion of the node as you are doing for root. This is what I do to overcome it.
In your store confing
root:{
text:'Objects',
id:'src',
expanded:true,
children:[]
}
Setting an empty children object will prevent the store load. Then all you need to do is set up a listener on the tree view to load the store as you have done. You will need to modify the server code to return the data without the children property...so just the array.
Related
I'm building a tree which will be loading its data on demand, so, it will be loading the first level of data, then if I click the + it should load that node children, if node is not leaf.
I've tried with itemclick, itemdblclick, select, but none of these events is fired when click the +.
Maybe a naive question, how can I capture the click on the + or -?
You can get those events using the itemexpand and itemcollapse listeners
listeners: {
itemexpand: function(nodeinterface,eOpts){
console.log('item expanded');
},
itemcollapse:function(nodeinterface,eOpts){
console.log('item collapsed');
}
},
I found a solution myself, and here is what I did:
in the view:
I needed to add: displayField: 'text' in the treepanel config and then point all the data to be displayed to that config.
I'm new to extjs and I'm trying to work on a Tree view.
I am building an "API Explorer" and there are simply too many nodes to send as a single json object (a few million nodes). What I wanted to do instead was send the first layer of categories as json initially, then on expand do an ajax request to get all of that category's children.
I'm not sure how to do this or if it's possible. Can anyone lead me in the right direction?
Actually that is the "normal" way as suggested by the documentation. Have a look at any of the Tree examples.
You basically set up an Ext.data.TreeStore with a Proxy, e.g. an Ext.data.proxy.Ajax:
xtype: 'treepanel',
loadMask: {msg: 'Loading...'},
store: Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: 'get-nodes.php'
}
})
Each time the user expands one of the nodes, the URL will be hit with the parameter node set to the id of the expanded node and should return an array of the children of this node. These children must not have a children property theirselves, otherwise they would be considered already loaded and would not be loaded on expansion.
I have a Tree Panel which I expand programmatically.
When I expand a node, I would like to "jump to" this node, I mean to scroll to it.
How to scroll a tree panel to a specific node ?
UPDATE:
I use Ext 4.1
Try using selectPath() http://docs.sencha.com/ext-js/4-0/#!/api/Ext.tree.Panel-method-selectPath
In extjs 3.x you can try calling focus() on the TreeNodeUI (myNode.ui.focus())
The tree is asynchronously loading every node, and you need to call to focus only after all the nodes have been loaded. What you are going to need to do is to set autoLoad to false on your root node, then later in the code manually load the root node for the first time using:
rootNode.expand(true, function(){
myTreePanel.getView().focusRow(nodeyouwanttofocus);
});
doing it this way allows you to use the first parameter of the expand function that makes the expand fully recursive and also assures that the second parameter that is a function only executes after all the nodes are loaded, guarenteeing that the view is the correct height and that the node exists visually.
Another option that allows more flexability is to hook into the expand event:
var myTreeStore = Ext.create("Ext.data.TreeStore", {
listeners: {
expand: function(theParentNode){
theParentNode.eachChild(function(node){
if(nodeIWantSelected == node)
myTreePanel.getView().focusRow(node);
}
}
}
});
and you can use the .select of the selection model to hook in to select the node (and I think it may focus the node too).
I haven't tried 'selectPath' as suggested by Sha before, which seems a lot easier to use, but you can hook in the focusRow function as the callback and I think that would work too.
You can use tree.getView().focusRow(), like it:
tree.expandPath(
'/root/1/2/3',
'id',
'/',
function() {
tree.getView().focusRow(tree.getStore().getNodeById('3'));
}
});
But, if your tree use animate: true and load every node asynchronously and any node in the path not loaded yet this approach doesnt work (tree is not scrolled to the selected node because of multiple layout updates).
As workaround you can:
set animate: false for tree;
add 'afterlayout' listener, like this:
tree.on('afterlayout', function() {
tree.getView().focusRow(tree.getSelectionModel().getSelection()[0]);
}
I guess you can add this handler when needed and remove it when everything is done.
I wonder why ExtJS developers decide to remove reload() method in ExtJS 4 Store API. I think it's a bad decision.
Here is my problem. I'm using the following code to initialize a grid's store:
store.load({
params: {
paramName: dynamicParameter
}
});
NOTICE the dynamicParameter variable in the code above.
Then, if I delete some records from the grid, I need to reload the store.
The problem is: the code segment which reload the store should not know the dynamicParameter value.
The code to delete records is like this:
function deleteGridItems(grid, deleteUrl){
// get selected rows
var records = grid.getSelectionModel().getSelection();
// ...... (codes to send request for deletion is ignored) ......
if(success){
grid.getStore().reload();
}
}
Unfortunately, the grid.getStore().reload() above will be an error because in ExtJS 4, reload() function doesn't exist anymore.
So how to reload the store with the same parameter??
Thank you.
If I'm not mistaken load() function now does exactly the same as reload() before. Try it.
you need to set proxy extra params instead specifying it each time on load():
see this http://www.sencha.com/forum/showthread.php?127673-Reload-Store-in-EXT-JS-4
Also note that Ext JS doesn't appear to check before loading whether the store is already loading data. I'm not sure why this is, but it can be fixed by overriding the load() method in a Store or TreeStore.
load: function(options) {
// Loading quickly will cause data in the panel to break
if (!this.isLoading()) {
this.callParent(arguments);
}
},
I haven't experienced issues with grids, but with trees if you press the refresh button very quickly you sometimes get an error and the tree structure breaks:
Uncaught TypeError: Cannot read property 'internalId' of undefined
I would like to create a Treepanel, which is updated once a second.
So I took a store with a proxy for data acquistion:
store = new Ext.data.TreeStore({
model: 'TaskState',
proxy: {
type: 'ajax',
url : '/getTaskList'
},
root: {
expanded: true
}});
The store seems to work, the data is displayed in my TreePanel.
I tried to update the Treepanel with this function:
function refresh(){
store.load();
window.setTimeout("refresh()", 1000);
}
The update seems to work as well. Unfortunately the update causes some kind of "blinking" effekt on every update, because the whole tree is reloaded. I'm searching for a way to only refresh the nodes, which have changed.
Is there some way to do this?
greetings
There is one way:
You can load your nodes to some temp store and change your main tree's store node by node
If you want to add any new node and do not want to reload the whole store then you can add like this
//overModel is Ext.data.Model
overModel.appendChild({
id: responseJson.data['id'],
text:responseJson.data['text'],
children:responseJson.data['children'],//array of childern
parent_id:responseJson.data['parent_id']
});
overModel.expand();
and if you want to load the whole store the you can do something like this
Ext.data.StoreManager.lookup('StoreName').load({ params: {"p1": p1}});
to load the store.
To update the store periodically you can use DelatedTask Class.
check out the Documentation API of EXTJS will give you more details.
Store is bind Treepanel like grid and store ,so you can get Store from tree panel with
var store=treepanel.getStore()
and you can reload the store with branch that you need update with
store.load({node:selectedNode})
You could use TaskManager for that:
Ext.TaskManager.start({
run: reloadStoreFunction,
interval: 1000
});
This would execute reloadStoreFunction every second.