Java encoding similiar to JavaScript encodeURIComponent

You may have a REST service that returns an encoded output to a JavaScript client which decodes this output in the client side. Unfortunately, this scenario will not always work because of the mismatch between both the Java java.net.URLEncoder encode() API and the JavaScript encodeURIComponent().

To be able to make the java.net.URLEncoder encode() behavior equivalent to the JavaScript encodeURIComponent(), all what you should do is the following String replacements.

public static String encodeURIComponent(String component)   {     
	String result = null;      
	
	try {       
		result = URLEncoder.encode(component, "UTF-8")   
			   .replaceAll("\\%28", "(")                          
			   .replaceAll("\\%29", ")")   		
			   .replaceAll("\\+", "%20")                          
			   .replaceAll("\\%27", "'")   			   
			   .replaceAll("\\%21", "!")
			   .replaceAll("\\%7E", "~");     
	catch (UnsupportedEncodingException e) {       
		result = component;     
	}      
	
	return result;   
}   

After that you can safely decode the output in the client side using the JavaScript decodeURIComponent().

References:

http://stackoverflow.com/questions/607176/java-equivalent-to-javascripts-encodeuricomponent-that-produces-identical-outpu

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent

http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URLEncoder.html

Refreshing Dijit tree in Dojo (code that works)

Refreshing the Dijit tree in Dojo with a new data store does not have a ready-made API in Dojo (Iam talking about Dojo 1.4). In this post, I will show a technique with example that will illustrate how to refresh the Dijit tree with a new data store.

The solution is about extending the dijit.Tree to support this feature as shown in the refreshModel method.

<script type="text/javascript">// <![CDATA[
	dojo.extend(dijit.Tree, {
		refreshModel: function () {

			// reset the itemNodes Map
			this._itemNodesMap = {};

			// reset the state of the rootNode
			this.rootNode.state = "UNCHECKED";

			// Nullify the tree.model's root-children
			this.model.root.children = null;

			// remove the rootNode
			if (this.rootNode) {
				this.rootNode.destroyRecursive();
			}

			// reload the tree
			this._load();
		}
	});
// ]]></script>

Let’s see now an example of refreshing the tree using this new introduced API.


	

<button id="refreshTreeButton" class="buttonClass" onclick="refreshTreeInformation();" type="button">Refresh Tree</button><script type="text/javascript">// <![CDATA[
	dojo.addOnLoad(function() {	
		var store = new dojo.data.ItemFileWriteStore({
			url: "sampleData.json"
		});				

		var treeModel = new dijit.tree.ForestStoreModel({
			store: store,
			query: {"type": "parent"},
			rootId: "root",
			rootLabel: "Groups",
			childrenAttrs: ["children"]
		});

		var treeObject = new dijit.Tree({
			model: treeModel
		}, "treeDiv");
	});

	function refreshTreeInformation() {		
		var treeObject = dijit.byId("treeDiv");
		var newStore = new dojo.data.ItemFileWriteStore({
			url: "sampleData2.json"
		});						

		treeObject.model.store = newStore;		
		treeObject.model.query = {"type": "parent"};	
		treeObject.rootId = "root";	
		treeObject.rootLabel = "Groups";	
		treeObject.childrenAttrs = ["children"];						

		treeObject.refreshModel();
	}			
// ]]></script>

In the refreshTreeInformation function, the tree object is retrieved, a new store is loaded, and assigned to the tree model object. Finally calling the refreshModel method will make the displayed tree insync with the underlying model. you can download the code from here.

I wish this tip can help.

Getting the Selected Dijit Tree node in Dojo

This post shows you how to get the selected node in a Dijit tree.

Let’s assume we have the following dijit tree data store.

{
"identifier":"id",
"label":"name",
"items":[
{
	"type": "parent",
	"name": "Countries",
	"id": "countries",
	"children":[
		{"type":"Leaf", "name":"Country 1", "id":"country1"},
		{"type":"Leaf", "name":"Country 2", "id":"country2"},
		{"type":"Leaf", "name":"Country 3", "id":"country3"},
		{"type":"Leaf", "name":"Country 4", "id":"country4"},
		{"type":"Leaf", "name":"Country 5", "id":"country5"},
		{"type":"Leaf", "name":"Country 6", "id":"country6"}
	]
}]}

Using the following JavaScript code the tree is loaded with the desired hierarchy.

<script type="text/javascript">// <![CDATA[
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dijit.Tree");
dojo.require("dijit.tree.ForestStoreModel");				

var store = new dojo.data.ItemFileWriteStore({
	url: "sampleData.JSON"
});

var treeModel = new dijit.tree.ForestStoreModel({
	store: store,
	query: {"type": "parent"},
	rootId: "root",
	rootLabel: "Groups",
	childrenAttrs: ["children"]
});

var treeObject = new dijit.Tree({
	model: treeModel
}, "treeDiv");

//...
// ]]></script>

In order to get the selected tree node object you should use the “selectedItem” attribute in the Dijit tree object as follows

dijit.byId("[Tree Node ID]").attr("selectedItem");

In our example to show the id of the selected leaf node when clicking the “Get Selected Node” button, the following code will do the job:

if (dijit.byId("treeDiv").attr("selectedItem") != null) {
	if (dijit.byId("treeDiv").attr("selectedItem").type == "Leaf") {
		document.getElementById("selectedNode").innerHTML =
                "Selected Node is " + dijit.byId("treeDiv").attr("selectedItem").id;
	}
}

This code is tested in Dojo 1.4 environment. download the code from here.

TypeError: this._arrayOfTopLevelItems is undefined

You may find this Dojo error when you are trying to create a JSON store object from a JSON string as follows:

var store = new dojo.data.ItemFileWriteStore({
	data: jsonString
});		

To resolve this issue, all what you should do is to convert the json string to a json object by using the dojo.fromJson as follows:

var store = new dojo.data.ItemFileWriteStore({
	data: dojo.fromJson(jsonString)
});