PDA

View Full Version : TreeStoreLoader



DiMarcello
8 Jul 2008, 8:26 AM
I like stores... its a great thing in ext!
But i missed one thingy... Why the heck does a tree not support a store???

So, again i made my own extension....
Needs a little fixing off course, but it works.

What needs fixing?: the update handling.
for some reason i cant get the replaceChild working, but it has no priority, since i'm still developing the rest of the app.

also look at my store extension (http://www.extjs.com/forum/showthread.php?p=192298#post192298)


/*
* @author DiMarcello
*/
Ext.namespace("Ext.ux.tree");

Ext.ux.tree.TreeStoreLoader = function(config) {

this.baseParams = {};
this.test='testing';
this.requestMethod = "POST";
this.storeLoaded = false;
Ext.apply(this, config);
if(!this.dataFields)
this.dataFields = ['id', 'text', 'children'];
for (var i = 0, l = this.dataFields.length; i < l; i++) {
if (typeof this.dataFields[i] == "string") {
this.dataFields[i] = {
name: this.dataFields[i]
};
}
}
this.addEvents(
"beforeload",
"load",
"loadexception",
"update"
);
Ext.ux.tree.TreeStoreLoader.superclass.constructor.call(this);
};

Ext.extend(Ext.ux.tree.TreeStoreLoader, Ext.tree.TreeLoader, {
addChildren: function(parent) {
this.store.each(function(rec) {
parent.appendChild(this.createChild(rec));
},this);
if(parent.attributes.expanded === true)
parent.expand();
},

createChild: function(rec){
var attr = {};
if(this.baseAttrs) Ext.applyIf(attr, this.baseAttrs);
if(this.applyLoader !== false) attr.loader = this;
for(var i = 0, f = this.dataFields; i < f.length; i++){
if (f[i].mapping !== undefined && f[i].mapping !== null) {
if (typeof f[i].mapping == 'function') {
attr[f[i].name] = f[i].mapping(rec);
} else {
attr[f[i].name] = rec.get(f[i].mapping);
}
} else {
attr[f[i].name] = rec.get(f[i].name);
}
}
return new Ext.tree.TreeNode(attr);
},

load : function(node, callback){
if(!!this.storeLoaded) {
if(this.clearOnLoad){
while(node.firstChild){
node.removeChild(node.firstChild);
}
}
this.addChildren(node);
if(typeof callback == "function") callback();
}else{
this.bindStore(this.store, node, callback, true);
}
},

bindStore: function(store, node, callback, initial){
if (this.store && !initial && this.fireEvent("beforeload", this, node, callback) !== false) {
this.store.un('load', this.handleResponse.createDelegate(this, [node, callback], 0));
this.store.un('update', this.handleUpdate.createDelegate(this, [node], 0));
this.store.un('loadexception', this.handleFailure.createDelegate(this, [node, callback], 0));
if (!store) {
this.store = null;
}
this.storeLoaded = false;
}

if(!store && initial){
this.store = new Ext.data.JsonStore({
url: this.dataUrl,
root: this.dataRoot,
fields: ['text']
});
}
if (store) {
this.store = Ext.StoreMgr.lookup(store);
this.store.on('load', this.handleResponse.createDelegate(this, [node, callback], 0));
this.store.on('update', this.handleUpdate.createDelegate(this, [node], 0));
this.store.on('loadexception', this.handleFailure.createDelegate(this, [node, callback], 0));
this.storeLoaded = this.store.loaded;
}
if(!this.storeLoaded){
this.store.load();
this.storeLoaded = true;
}else{
this.load.call(this, node, callback);
}
},

processResponse : function(node, callback){
try {
this.load.call(this, node, callback);
}catch(e){
this.handleFailure(node, callback);
}
},

handleUpdate: function(node, s, r, operation){
if(operation == Ext.data.Record.COMMIT){
this.transId = false;
/*TODO var old = node.findChild('id', r.get('id'));
if(old){
var nn = this.createChild(r);
node.replaceChild(nn, old);
nn.highlight();

} */
this.processResponse(node, null);
this.fireEvent("update", this, node);
}
},

handleResponse : function(node, callback){
this.transId = false;
this.processResponse(node, callback);
this.fireEvent("load", this, node);
},

handleFailure : function(node, callback){
this.transId = false;
this.fireEvent("loadexception", this, node);
if(typeof callback == "function") callback(this, node);
}

});

tof
8 Jul 2008, 11:00 PM
Good idea.

888juank888
24 Jul 2008, 9:16 AM
Hi DiMarcello...
Can you post an example to use this...
Sorry my english :(

kimmking
24 Jul 2008, 2:38 PM
Hi DiMarcello...
Can you post an example to use this...
Sorry my english :(



<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="./ext/resources/css/ext-all.css">
<script type="text/javascript" src="./ext/adapter/ext/ext-base.js">
</script>
<script type="text/javascript" src="./ext/ext-all-debug.js">
</script>
<script type="text/javascript" src="./TreeStoreLoader.js">
</script>
</head>
<body>
<script type="text/javascript">

Ext.onReady(function(){
// shorthand
var Tree = Ext.tree;

var myData = [['id', 'text', []]];

var ds = new Ext.data.SimpleStore({
fields: [{
name: 'id'
}, {
name: 'text'
}, {
name: 'children'
}]
});
ds.loadData(myData);

var myloader = new Ext.ux.tree.TreeStoreLoader({storeLoaded : true, store : ds });

var tree = new Tree.TreePanel({
el: 'tree-div',
useArrows: true,
autoScroll: true,
animate: true,
enableDD: true,
height: 500,
width: 200,
containerScroll: true
});

// set the root node
var root = new Tree.TreeNode({
text: 'Ext JS',
draggable: false,
id: 'source'
});
var node1 = new Tree.AsyncTreeNode({
text: 'Ext JS1111',
draggable: false,
id: 'source1',
loader: myloader
});
tree.setRootNode(root);
root.appendChild(node1);
// render the tree
tree.render();
root.expand();
});

</script>
<div id="tree-div">
</div>
</body>
</html>

888juank888
29 Jul 2008, 1:58 PM
Great job!!!
I has some problems with the record fields in reader of store... but can fix it adding this line...
<code>
Ext.apply(this, config);
this.dataFields = this.store.reader.recordType.prototype.fields.keys; //-- here
</code>

works OK :)

PHaroZ
3 Aug 2008, 10:56 PM
thx for your job DiMarcello.

However, i had some trouble with your extension : i need to work with AyncTreeNode at each level and it doesn't seem to work.

So i write my own extension based on yours. Thx for your job and I hope that it's not a problem for you.

My Version of the extension :

Ext.namespace("Ext.ux.tree");

Ext.ux.tree.TreeStoreLoader = function(config) {

/**
* name of the parameter in the HTTP request (QueryString or POST data)
*/
this.nodeParamName = "node";

// required to be set to "true" (or non empty string) by the parent class to work properly
this.dataUrl = true;

Ext.apply(this, config);

if (!this.dataFields) {
this.dataFields = ['id', 'text', 'children'];
}
for (var i = 0, l = this.dataFields.length; i < l; i++) {
if (typeof this.dataFields[i] == "string") {
this.dataFields[i] = {
name : this.dataFields[i]
};
}
}

if (!this.store) {
this.store = new Ext.data.JsonStore({
url : this.dataUrl,
root : this.dataRoot,
fields : ['text']
});
}

Ext.ux.tree.TreeStoreLoader.superclass.constructor.call(this);
};

Ext.extend(Ext.ux.tree.TreeStoreLoader, Ext.tree.TreeLoader, {

requestData : function(node, callback) {
if (this.fireEvent("beforeload", this, node, callback) !== false) {
this.store.purgeListeners();
this.store.on('load', this.handleResponse.createDelegate(this, [node, callback], 0));
this.store.on('loadexception', this.handleFailure.createDelegate(this, [node, callback], 0));
this.store.load({
params : this.getParams(node),
callback : callback
});
} else {
if (typeof callback == "function") {
callback();
}
}
},

getParams : function(node) {
var params = {};
var bp = this.baseParams;
for (var key in bp) {
if (typeof bp[key] != "function") {
params[key] = bp[key];
}
}
params[this.nodeParamName] = node.id;
return params;
},

processResponse : function(node, callback) {
try {
this.addChildren(node);
if (typeof callback == "function")
callback();
} catch (e) {
this.handleFailure(node, callback);
}
},

handleResponse : function(node, callback) {
this.transId = false;
this.processResponse(node, callback);
this.fireEvent("load", this, node);
},

handleFailure : function(node, callback) {
this.transId = false;
this.fireEvent("loadexception", this, node);
if (typeof callback == "function") {
callback(this, node);
}
},

addChildren : function(parent) {
this.store.each(function(rec) {
parent.appendChild(this.createChild(rec));
}, this);
if (parent.attributes.expanded === true) {
parent.expand();
}
},

createChild : function(rec) {
var attr = {};
for (var i = 0, f = this.dataFields; i < f.length; i++) {
attr[f[i].name] = Ext.isEmpty(f[i].mapping) ? rec.get(f[i].name) : ((typeof f[i].mapping == 'function')
? f[i].mapping(rec)
: rec.get(f[i].mapping));
}
return this.createNode(attr);
}

});


Example :

var rootOptions = {id:1, text:'blabla'};
rootOptions = Ext.applyIf(rootOptions || {}, {
loader : new Ext.ux.tree.TreeStoreLoader({
store : new Ext.data.Store({
proxy : new Ext.data.HttpProxy({
method : "POST",
url : G.serverSideURI("org/orgNodeListByParent")
}),
reader : new Ext.data.JsonReader({
root : 'data.records',
totalProperty : 'data.total',
id : 'id'
}, Ext.data.Record.create([{
name : 'id'
}, {
name : 'text',
mapping : 'orgUnit.name'
}, {
name : 'orgUnitId',
mapping : 'orgUnit.id'
}, {
name : 'order'
}])),
sortInfo : {
field : 'order',
direction : 'ASC'
}
}),
dataFields : ['id', 'text', 'orgUnitId', 'order'],
nodeParamName : "parent"
})
});
var root = new Ext.tree.AsyncTreeNode(rootOptions);

Corresponding data :

{
success : true,
data : {
total : 2,
records : [{
id : 3,
active : true,
orgUnit : {
id : 4,
name : "Empire vagrian"
},
order : 0
}

, {
id : 4,
active : true,
orgUnit : {
id : 6,
name : "plaines Sentranes"
},
order : 20
}]
}
}

JustSane
23 Sep 2008, 8:31 AM
Please let know an example usage of TreeStoreLoader.

Regards
JustSane