PDA

View Full Version : Format JSON for TreeLoader



robw
22 Oct 2007, 6:51 AM
Hi,

I am trying to use Jayrock to provide JSON to the TreeLoader object. Unfortunately the JSON is in the format:

{"id":-1,"result":"[{id : 'n1', text : 'Node 1', leaf : false}]"}The JSON is as the TreeLoader expects, except it is nested in the result object..

Is there a way to configure the TreeLoader to accept JSON in this format? Do I need to override something somewhere?!

cheers
Rob

PS I forgot to ask - is it possible to populate a tree from a data store? (this would solve my problem :) )

robw
22 Oct 2007, 8:14 AM
ok - I have fixed it, but would appreciate comments on my solution, it's probably not done in the right way... :-?

I created a new class that overrides the processResponse method to check for the offending string and remove it before parsing:
(only change is new line - see comment)


JayrockTreeLoader = function(config) {
JayrockTreeLoader.superclass.constructor.call(this, config);
}
Ext.extend(JayrockTreeLoader, Ext.tree.TreeLoader, {
processResponse : function(response, node, callback){
var json = response.responseText;

/*added to remove result wrapper from JSON*/
if (json.indexOf('{"id":-1') == 0) json = json.substring(19, json.length-2);

try {
var o = eval("("+json+")");
node.beginUpdate();
for(var i = 0, len = o.length; i < len; i++){
var n = this.createNode(o[i]);
if(n){
node.appendChild(n);
}
}
node.endUpdate();
if(typeof callback == "function"){
callback(this, node);
}
}catch(e){
this.handleFailure(response);
}
}
});Any comments?
Rob

Animal
22 Oct 2007, 10:51 AM
YECH! String manipulation before you eval it?

Just eval it into an object, and poke that into the correct shape!

robw
23 Oct 2007, 1:38 AM
haha I knew someone would object to that :)

I did it because otherwise I'd need to do 2 evals which seemed a bit wasteful. The initial one on the whole string and then a 2nd on the result string (whether my way is quicker i'm not sure..).

Alternatively, if you find the substring just too offensive:


var o = eval("("+json+")");
if (o.result != null) o = eval(o.result);

jefe
27 Nov 2007, 5:59 PM
JayrockTreeLoader.js



Ext.tree.JayrockTreeLoader = function(config){
this.nextId = 0;
this.methodName = null;
Ext.tree.JayrockTreeLoader.superclass.constructor.call(this, config);
}
Ext.extend(Ext.tree.JayrockTreeLoader, Ext.tree.TreeLoader, {
getParams: function(node){
var params = { node: node.id };
Ext.apply(params, this.baseParams);
var buf = {
id: ++this.nextId,
method: this.methodName,
params: params
}
return Ext.util.JSON.encode(buf);
},
processResponse : function(response, node, callback){
var json = response.responseText;
try {
var o = eval("("+json+")");
if(o.error)
throw o.error.message;
o = o.result;
node.beginUpdate();
for(var i = 0, len = o.length; i < len; i++){
var n = this.createNode(o[i]);
if(n){
node.appendChild(n);
}
}
node.endUpdate();
if(typeof callback == "function"){
callback(this, node);
}
}catch(e){
this.handleFailure(response);
}
}
});

TreeService.ashx



using System;
using System.Collections;

using Jayrock.Json;
using Jayrock.JsonRpc;
using Jayrock.JsonRpc.Web;

namespace Test
{
public class TreeNode
{
public int id;
public string text;

public TreeNode() { }

public TreeNode(int id, string text)
{
this.id = id;
this.text = text;
}
}

[JsonRpcMethod("getTreeNodes", Idempotent=true)]
public List<TreeNode> GetTreeNodes(int node)
{
List<TreeNode> nodeList = new List<TreeNode>();
nodeList.Add(new TreeNode(5, 'Test'));

return nodeList;
}
}

Test.js


var treeLoader = new Ext.tree.JayrockTreeLoader({
dataUrl:'TreeService.ashx',
methodName: 'getTreeNodes'
});

rebecchi
11 Mar 2008, 6:30 AM
Dear jefe,

Your example code was very useful, but I had to modify the TreeService.ashx as follows in order to make it running in Ext JS 2.0.

Many thanks again for your example




using System;
using System.Collections;

using Jayrock.Json;
using Jayrock.JsonRpc;
using Jayrock.JsonRpc.Web;

namespace Test
{
public class TreeNode
{
public string id;
public string text;

public TreeNode() { }

public TreeNode(string id, string text)
{
this.id = id;
this.text = text;
}
}

[JsonRpcMethod("getTreeNodes", Idempotent=true)]
public List<TreeNode> GetTreeNodes(string node)
{
List<TreeNode> nodeList = new List<TreeNode>();
nodeList.Add(new TreeNode(node, 'Test'));

return nodeList;
}
}

rathinaganesh
20 Apr 2010, 9:53 AM
Greetings,

Thanks for the solution. I was able to extend the tree loader to read my Json object.
It works fine until then. However, the problem is, when I try to expand any parent object, it loads the tree again and data gets duplicated.

20024

Here is my code for slaTreeLoader.js, this extends the TreeLoader as mentioned in this thread previously.



Ext.tree.SlaTreeLoader = function(config){
this.nextId = 0;
this.methodName = null;
Ext.tree.SlaTreeLoader.superclass.constructor.call(this, config);
}
Ext.extend(Ext.tree.SlaTreeLoader, Ext.tree.TreeLoader, {
getParams: function(node){
var params = { node: node.id };
Ext.apply(params, this.baseParams);
var buf = {
id: ++this.nextId,
method: this.methodName,
params: params
}
return Ext.util.JSON.encode(buf);
},
processResponse : function(response, node, callback){
var json = response.responseText;
try {
var o = eval("("+json+")");
o=o.data;
if(o.error)
throw o.error.message;

node.beginUpdate();
for(var i = 0, len = o.length; i < len; i++){
var n = this.createNode(o[i]);
if(n){
node.appendChild(n);
}
}
node.endUpdate();
if(typeof callback == "function"){
callback(this, node);
}
}catch(e){
this.handleFailure(response);
}
}
});



Here is my treegrid code that loads the json data in to tree grid.


com.company.sla.slaManager.slatree = new Ext.ux.tree.X3TreeGrid({
//title: 'SLA Listings',
width:1180,
//collapsible:true,
height:480,
plain:true,
renderTo: Ext.getBody(),
enableDD: true,
columns:[{
header: 'SLA Name',
dataIndex: 'slaName',
sortable: true,
width: 230
},{
header: 'SLA Description',
dataIndex: 'slaDescription',
sortable: true,
width: 350
}],
loader: new Ext.tree.SlaTreeLoader({
dataUrl:'secure/getSlas.action',
clearOnLoad:true,
preloadChildren:true
})

});


Here is my Json data object


{"data":[{"iconCls":"task-folder","leaf":false,"parentId":1,"slaDescription":"Some Desc1","slaId":1,"slaName":"Sla1",
"updateTsFormattedAsString":"03/12/2010 16:25:20 PDT"},
{"iconCls":"task","leaf":true,"parentId":1,"slaDescription":"Some Desc1","slaId":2,"slaName":"Sla2",
"updateTsFormattedAsString":"03/12/2010 16:25:20 PDT"},
{"iconCls":"task-folder","leaf":false,"parentId":0,"slaDescription":"Some Desc1","slaId":3,"slaName":"Sla3",
"updateTsFormattedAsString":"03/12/2010 16:25:20 PDT"},
{"iconCls":"task","leaf":true,"parentId":3,"slaDescription":"Some Desc1","slaId":4,"slaName":"Sla4",
"updateTsFormattedAsString":"03/12/2010 16:25:20 PDT"}]}


Can anyone help me, why this is happening ? Thanks in advance.

Regards,
Ganesh.

rathinaganesh
20 Apr 2010, 1:43 PM
Never mind. I figured out the issue. The json data, I am sending from server side is not correct. The tree expects data to have children element embedded.
After I edited this. The tree is rendering fine.