Skip to content

Ext JS XTemplate – function call

An Ext JS XTemplate calling an outside function. And a goofy HTML table generator. (Don’t ask…)

function extjsTest() {
	var person = {
		firstName : "john",
		middleName : null,
		lastName : "smith",
		city : "kansas city",
		state : "kansas",
		country : "usa",
		email : "john@ks.gov",
		phoneNumber : "123-456-7890"
	};

	Ext.get("myTable").update(myTpl.apply(person));
}

function tr(x) {
	return wrap("tr", x);
}

function td(x) {
	return wrap("td", x);
}

function wrap(tag, x) {
	return "<" + tag + ">" + x + "</" + tag + ">";
}

// myMap - map of label/value pairs,
// cols - number of columns to render
function renderTable(myMap, cols) {
	var result = "<table border='1'>";
	var index = 0;

	for (key in myMap) {
		// skip nulls
		if (myMap[key]) {
			if (cols == 1) {
				result += tr( td(key) + td(myMap[key]) );
			}
			else {
				if (index % cols == 0) result += "<tr>";
				result += ( td(key) + td(myMap[key] );
				if (index % cols == (cols-1)) result += "</tr>";
				index++;
			}
		}
	}

	result += "</table>";
	return result;
}

var myTpl = new Ext.XTemplate(
	'<tpl for=".">',
		'{[renderTable({',
			'"First Name" : values.firstName,',
			'"Middle Name" : values.middleName,',
			'"Last Name" : values.lastName,',
			'"City" : values.city,',
			'"State" : values.state,',
			'"Country" : values.country,',
			'"E-Mail" : values.email,',
			'"Phone Number" : values.phoneNumber,',
		'}, 2)]}',	// render into 2 columns
	'</tpl>'
);

Synchronous Ajax call with jQuery

Just wanted to see if the synchronous ajax call would delay the asynchronous call. It did.

<html>
	<head>
		<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
		<script type="text/javascript">
		 $(document).ready(function(){

			 console.log('start time: ' + new Date());
			 jQuery.ajax({
				 url:    'http://localhost:8080/ExtJS1/spring/sleep?time=5000',
				 success: function(result) {
							console.log('synchronous: ' + new Date());
						  },
				 async:   false
			});
			 
			 jQuery.ajax({
				 url:    'http://localhost:8080/ExtJS1/spring/sleep?time=5000',
				 success: function(result) {
							console.log('asynchronous: ' + new Date());
						  },
				 async:   true
			});

		 });
		 
		</script>
	</head>

	<body>
	</body>
</html>

Ext JS: TreePanel

Getting a basic Ext JS TreePanel to populate with JSON streamed from a Spring MVC controller…

The JSON. (Library-themed of course!)

[
	{ text: 'Books',
		children: [
			{
				text: 'Book 1',
				leaf: true,
				itemType: 'book',
				itemId: 1,
				patronId: 5
			},
			{
				text: 'Book 2',
				leaf: true,
				itemType: 'book',
				itemId: 2,
				patronId: 5
			}
		]
	},
	{ text: 'DVDs',
		children: [
			{
				text: 'DVD 1',
				leaf: true,
				itemType: 'dvd',
				itemId: 1,
				patronId: 5
			},
			{
				text: 'DVD 2',
				leaf: true,
				itemType: 'dvd',
				itemId: 2,
				patronId: 5
			}		 
		]
	}
]

treeTest.html

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

		<!-- hide the tree icons...just my preference in this case -->
		<style type="text/css">
			.x-tree-node-icon {display:none}
		</style>
		<script><!--
			Ext.onReady(function(){

				var treeLoader = new Ext.tree.TreeLoader({
					dataUrl: 'http://localhost:8080/ExtJS1/spring/tree'
				});

				// this must be an AsyncTreeNode or it won't hit the controller
				var rootNode = new Ext.tree.AsyncTreeNode({
					text: 'Root'
				});
				
      			var treePanel = new Ext.tree.TreePanel({
      		    	renderTo: Ext.getBody(),
      		    	loader: treeLoader,
      		    	root: rootNode,
      		    	// don't want the root displayed
      		    	rootVisible: false,
      		    	listeners: {
	      	            click: function(n) {
	                    	// display some extra data we hid in the JSON
	                    	alert(n.attributes.itemType + ' ' + 
	    	                    	n.attributes.itemId + 
	    	                    	' checked out to patron ' + 
	    	                    	n.attributes.patronId);
	                	}
	                }
				});

				// fully expand the tree
				treePanel.expandAll();
   	      	});
         	   
       	  --></script>
    </head>
    <body>
    </body>
</html>

TreeController.java


package controllers;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TreeController {

    @RequestMapping("/tree")
    public void jsonTree(HttpServletRequest request, HttpServletResponse response) {
	
		// hardcoded JSON for testing, you'll probably want to
		// use Jackson or XStream to generate real data!
		
    	String json = "[ { text: 'Books', children: [ { text: 'Book 1', leaf: true, itemType: 'book', itemId: 1, patronId: 5 }, { text: 'Book 2', leaf: true, itemType: 'book', itemId: 2, patronId: 5 } ] }, { text: 'DVDs', divId: 'dvd-div', children: [ { text: 'DVD 1', leaf: true, itemType: 'dvd', itemId: 1, patronId: 5 }, { text: 'DVD 2', leaf: true, itemType: 'dvd', itemId: 2, patronId: 5 } ] } ]";
    	try {
    		response.getWriter().write(json);
    	}
    	catch (IOException e) {
			System.out.println(e);
		}
    }
}

Tiles 2 Quickstart

Here’s how I got Tiles 2 working with Spring MVC.  From the bottom up…

/WEB-INF/jsp/views/myPage.jsp

<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<tiles:insertDefinition name="myTemplate">
    <tiles:putAttribute name="content">
        The content.  Header/footer are specified in myTemplate.jsp.
    </tiles:putAttribute>
</tiles:insertDefinition>

/WEB-INF/jsp/templates/myTemplate.jsp

<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>My Template</title>
</head>
<body>
	<tiles:insertAttribute name="header" />
	<tiles:insertAttribute name="content" />
	<tiles:insertAttribute name="footer" />	
</body>
</html>

/WEB-INF/jsp/views/tiles.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC 
	"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
  	"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
 
<tiles-definitions>
 
  <definition name="myTemplate" template="/WEB-INF/jsp/templates/myTemplate.jsp">
  	<put-attribute name="header" value="/WEB-INF/jsp/templates/header.jsp"/>
  	<put-attribute name="footer" value="/WEB-INF/jsp/templates/footer.jsp"/>
  </definition>
 
</tiles-definitions>

/WEB-INF/jsp/templates/header.jsp

<br/>MY HEADER<br/>

/WEB-INF/jsp/templates/footer.jsp

<br/>MY FOOTER<br/>

/WEB-INF/spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc
    	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
 	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
 		<property name="order" value="1"/>
 		<property name="defaultHandler">
 			<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
 		</property>
 	</bean>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    	<property name="definitions">
    		<list>
    			<value>/WEB-INF/jsp/**/tiles.xml</value>
    		</list>
    	</property>
    </bean>
</beans>

/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
	id="WebApp_ID" version="2.5">
 
  <display-name>tiles</display-name>
  
  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/spring/*</url-pattern>
  </servlet-mapping>
  
</web-app>

Almost forgot the jars! (some may not be necessary)

commons-beanutils-1.8.3.jar
commons-digester-2.1.jar
commons-logging-1.1.1.jar
org.springframework.aop-3.0.5.RELEASE.jar
org.springframework.asm-3.0.5.RELEASE.jar
org.springframework.beans-3.0.5.RELEASE.jar
org.springframework.binding-2.2.1.RELEASE.jar
org.springframework.context-3.0.5.RELEASE.jar
org.springframework.context.support-3.0.5.RELEASE.jar
org.springframework.core-3.0.5.RELEASE.jar
org.springframework.expression-3.0.5.RELEASE.jar
org.springframework.faces-2.2.1.RELEASE.jar
org.springframework.js-2.2.1.RELEASE.jar
org.springframework.js.resources-2.2.1.RELEASE.jar
org.springframework.test-3.0.5.RELEASE.jar
org.springframework.web-3.0.5.RELEASE.jar
org.springframework.web.servlet-3.0.5.RELEASE.jar
org.springframework.webflow-2.2.1.RELEASE.jar
slf4j-api-1.6.1.jar
slf4j-simple-1.6.1.jar
tiles-api-2.2.2.jar
tiles-core-2.2.2.jar
tiles-jsp-2.2.2.jar
tiles-servlet-2.2.2.jar
tiles-template-2.2.2.jar