I'm trying to create a dojo Tree, for the time being with test data. The bean always returns the same. When I put the data in a file inside the nsf Resources, it works. Using the bean, it fails. It displays only the word Continent, and I cannot open and descend the node.
Can someone help me out? I'd appreciate it enormously!
My code, where store2 works, store1 errors out and store0 only shows Continent:
<xe:restService id="restService1" pathInfo="treeData">
<xe:this.service>
<xe:customRestService serviceBean="com.sefip.TreeData" requestContentType="application/json" requestVar="tree"></xe:customRestService>
</xe:this.service>
</xe:restService>
<!--
xp:text disableTheme="true" value="#{javascript:getBoxValue(compositeData.boxName)}" styleClass="readonly" style="margin-top:2px">
<xp:this.rendered><![CDATA[#{javascript:getBoxValue(compositeData.boxName)}]]></xp:this.rendered> </xp:text> <xp:div id="boxTree"
dojoType="dijit.Tree"></xp:div
-->
<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[
dojo.require("dojox.data.JsonRestStore");
dojo.require("dojo.store.JsonRest");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.tree.ForestStoreModel");
dojo.require("dijit.Tree");
dojo.addOnLoad(function() {
// Create a data store to retrieve data from
var store0 = new dojox.data.JsonRestStore({
//url: "countries.json"
target: "aCRM2.xsp/treeData/",
labelAttribute: "name"
});
var store1 = new dojo.store.JsonRest({
target: "aCRM2.xsp/treeData/",
labelAttribute: "name"
});
var store2 = new dojo.data.ItemFileReadStore({
url: "countries.json"
});
// secondly we create a treeModel.
var treeModel = new dijit.tree.ForestStoreModel({
store: store0,
query: {type: "continent"},
rootId: "root",
rootLabel: "Continents",
childrenAttrs: ["children"]
});
// Last but not least we create a new instance of our tree.
var tree= new dijit.Tree({
model: treeModel
},
"#{id:treeOne}");
});
]]></xp:this.value>
</xp:scriptBlock>
<!-- The domnode we will use to render the tree -->
<xp:div id="treeOne" />
</xp:div>
The countries.json contains:
{
"items" : [{
"id" : "EU",
"children" : [{
"_reference" : "NL"
}
],
"type" : "continent",
"name" : "Europe"
}, {
"id" : "NL",
"type" : "country",
"name" : "Netherlands"
}
],
"label" : "name",
"identifier" : "id"
}
The bean generates exactly the same, but for completeness' sake I'll add the code here:
package com.sefip;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonGenerator;
import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.jscript.InterpretException;
import com.ibm.jscript.JSContext;
import com.ibm.jscript.json.JsonJavaScriptFactory;
import com.ibm.jscript.std.ArrayObject;
import com.ibm.jscript.std.ObjectObject;
import com.ibm.jscript.types.FBSUtility;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;
import com.ibm.xsp.util.JavaScriptUtil;
public class TreeData extends CustomServiceBean {
@Override
public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
HttpServletRequest request = engine.getHttpRequest();
HttpServletResponse response = engine.getHttpResponse();
String method = request.getMethod();
response.setHeader("Content-Type", "application/json; charset=UTF-8");
if (method.equals("GET")) {
this.get(engine);
} else if (method.equals("POST")) {
this.post(engine, request);
} else {
this.other(engine);
}
}
public void get(RestServiceEngine engine) {
HttpServletResponse response = engine.getHttpResponse();
try {
JSContext jsContext = JavaScriptUtil.getJSContext();
JsonJavaScriptFactory factory = new JsonJavaScriptFactory(jsContext);
String json = null;
ObjectObject returnJSON = new ObjectObject();
returnJSON.put("identifier", FBSUtility.wrap("id"));
returnJSON.put("label", FBSUtility.wrap("name"));
ArrayObject countries = new ArrayObject();
ObjectObject continent = new ObjectObject();
continent.put("id", FBSUtility.wrap("EU"));
continent.put("name", FBSUtility.wrap("Europe"));
continent.put("type", FBSUtility.wrap("continent"));
ArrayObject children = new ArrayObject();
ObjectObject child = new ObjectObject();
child.put("_reference", FBSUtility.wrap("NL"));
children.addArrayValue(child);
continent.put("children", children);
countries.addArrayValue(continent);
ObjectObject country = new ObjectObject();
country.put("id", FBSUtility.wrap("NL"));
country.put("name", FBSUtility.wrap("Netherlands"));
country.put("type", FBSUtility.wrap("country"));
countries.addArrayValue(country);
returnJSON.put("items", countries);
UserData.get().addLog("call generator");
json = JsonGenerator.toJson(factory, returnJSON);
UserData.get().addLog(json);
response.getWriter().write(json);
response.getWriter().close();
return;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterpretException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void post(RestServiceEngine engine, HttpServletRequest request) {
HttpServletResponse response = engine.getHttpResponse();
Map parameters = request.getParameterMap();
try {
response.getWriter().write("post()");
response.getWriter().write(request.getParameter("form"));
String[] form = (String[]) parameters.get("form");
String val = form[0];
response.getWriter().write(val);
response.getWriter().close();
} catch (Exception e) {
// TODO: handle exception
}
}
public void other(RestServiceEngine engine) {
HttpServletResponse response = engine.getHttpResponse();
try {
response.getWriter().write("other()");
response.getWriter().close();
return;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
All this is largely based on the work done by Jeroen Somhorst and others, see http://www.jeroensomhorst.eu/uncategorized/viewpanel-vs-dijit-tree-part-1/ and part-2.
PS Dank je, Jeroen, maar waar is part-3?? ;-)
Finally found a solution.
It turns out that the structure for a JsonRestStore should be a nested array with objects and children, like this:
[{
"id" : "EU",
"children" : [{
"id" : "NL",
"type" : "country",
"name" : "Netherlands"
}],
"type" : "continent",
"name" : "Europe"
}]
Plain and simple...
Thanks Jeroen, for the link, the comments in there showed me this way.