Category Archives: HTML

Create an Ext.tree.TreePanel from an XML document


Hi,

Recently I created menu manager with Ext JS components.
First I loaded tree from XML documents, But then I realize JSON will be very much easy. Still if you think that XML document is perfect for you then here is my work.

On fly I’m just providing html page and xml file, so if you have any doubts or questions then you can place comment bellow.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>
			Manage Menu 
		</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<link href="http://dev.sencha.com/deploy/ext-3.4.0/resources/css/ext-all.css" rel="stylesheet"/>
		<script src="http://dev.sencha.com/deploy/ext-3.4.0/adapter/ext/ext-base.js"></script>
		<script src="http://dev.sencha.com/deploy/ext-3.4.0/ext-all.js"></script>
		<link href="http://dev.sencha.com/deploy/ext-3.4.0/examples/tree/xml-tree-loader.css"/>
		<script src="http://dev.sencha.com/deploy/ext-3.4.0/examples/ux/XmlTreeLoader.js"></script>
		<script>
			//Excellent function that converts tree data into json
			function getJson(treeNode) {
				treeNode.expandChildNodes();
				var json = {};
				var attributes = treeNode.attributes;
				for(var item in attributes){
					if (item == 'src' || item == 'text' || item == 'allowDrop' || item == 'allowDrag') { //get only required attributes
						json[item] = attributes[item];
					}
				}
				json.children = [];
				if(treeNode.childNodes.length > 0){
					for (var i=0; i < treeNode.childNodes.length; i++) {
						json.children.push(getJson(treeNode.childNodes[i]));
					}
					json.leaf = false;
				} else {
					json.leaf = true;
				}
				return json;
			}
			//
			// Extend the XmlTreeLoader to set some custom TreeNode attributes specific to our application:
			//
			Ext.app.CustomTreeLoader = Ext.extend(Ext.ux.tree.XmlTreeLoader, {
				processAttributes : function(attr){
					// Set the node text that will show in the tree since our raw data does not include a text attribute:
					attr.text = attr.title;
					if(attr.src == 'javascript:void(0);'){ // Does the node has child?
						// Override these values for our folder nodes because we are loading all data at once.  If we were
						// loading each node asynchronously (the default) we would not want to do this:
						attr.loaded = true;
						attr.expanded = true;
					}
					else { // is it a leaf node?
						// Tell the tree this is a leaf node.  This could also be passed as an attribute in the original XML,
						// but this example demonstrates that you can control this even when you cannot dictate the format of
						// the incoming source XML:
						attr.leaf = true;
					}
				},
				requestMethod: 'GET'
			});
			Ext.onReady(function(){
				new Ext.Panel({
					title: 'Menu',
					renderTo: 'menuTree',
					layout: 'border',
					width: 500,
					height: 500,
					items: [{
						xtype: 'treepanel',
						id: 'tree-panel',
						region: 'center',
						margins: '2 2 0 2',
						autoScroll: true,
						rootVisible: false,
						enableDD: true,
						viewConfig: {
				            plugins: [{
				                ptype: 'treeviewdragdrop'
				            }]
				        },
						root: new Ext.tree.AsyncTreeNode(),
							loader: new Ext.app.CustomTreeLoader({
								dataUrl:'menu.xml'  //load your xml file
							}),
							listeners: {
								'render': function(tp){
								tp.getSelectionModel().on('selectionchange', function(tree, node){
									var el = Ext.getCmp('details-panel').body;
									tpl.overwrite(el, node.attributes);
								})
							}
						}
					}]
			    });
			});
			function savechanges(){
				var myTree = Ext.getCmp('tree-panel');
				var json = getJson(myTree.getRootNode());
				console.log(Ext.encode(json.children)); //serialize json data into string so we can send back to server
			}
		</script>
	</head>
	<body>
		<div id="menuTree"></div>
	</body>
</html>

Sample XML file…

<?xml version="1.0" encoding="UTF-8"?>
<menu src="root" title="root" id="0">
	<!-- Home -->
	<menu src="/page.htm2" title="Home"></menu>
	<menu title="Clients" src="javascript:void(0);">
		<menu src="/page1.html" title="Bank Management"></menu>
		<menu src="/page2.html" title="Client Management"></menu>
		<menu src="javascript:void(0);" title="Updates">
			<menu src="/page2.html" title="View Updates"></menu>
			<menu src="/page3.html" title="Report Bug"></menu>
		</menu>
	</menu>
	<!--  Ends -->
</menu>

I used third party control, that extends the XMLLoader for processing XML attributes…

In the Next post, I’ll show you how we can use JSON for easy storage and loading into tree. I’ll also post add/edit/delete/drag & drop/restriction etc.

Enable/disable link button in jquery Mobile


Hi,

I am developing mobile application, where I use jquery Mobile.

Buttons can be created by input tag, button tag and even link tag. See examples:


<button>Button1</button>

<input type="button" value="Button2" />

<a href="#" data-role="button">Button3</a>

In docs, I see enable/disable method for button. See.

But using this method, it can only set style, functionally it doesn’t! May be they missed it!

Anyway, I got some trick to make link enable/disable.

HTML5 now has data attribute that user can use it, browser will ignore it while rendering it.

So Disabling a link, I just remove href and onclick value to some data attribute and vice versa.

function test(){
    if ($("#mytest").parent().attr("aria-disabled") == "true") {
      $("#mytest").attr("href", $("#mytest").attr("data-href"));
      $("#mytest").attr("onclick", $("#mytest").attr("data-onclick"));
      $("#mytest").button('enable');
    } else {
      $("#mytest").attr("data-href", $("#mytest").attr("href"));
      $("#mytest").attr("data-onclick", $("#mytest").attr("onclick"));
      $("#mytest").attr("href","#");
      $("#mytest").attr("onclick","return");
      $("#mytest").button('disable');
    }
  }

See live example here.

Source code here.

innerHTML vs appendChild


Hi,

Today I was testing my code, and I found interesting stuff on innerHTML property and appendChild method.

I was trying to add new elements to the div.

First, I was creating element by calling DOM method (document.createElement()) and then I append it to my div by calling appendChild() method of the HTML div element.

But then I changed the logic by using innerHTML property of the HTML div element.

I was doing the same thing by two different way, but what is the difference?

Well try out this page, and notice the difference!

Hold on, think twice if you didn’t get the difference.

Okay! I hope that you are a good tester and found the difference that clicking on ‘Add by DOM’ button, you don’t loose the value of the input box, while clicking on ‘Add by innerHTML’ button you loose the value of input box.

Okay, so changing the innerHTML property will force  recreation of div by browser, and that’s why you loose the value if input box!

So which one is better?

I saw that people are taking lot about the speed of both the technique (check here), but my this post is just to remind the causes of changing the technique!