Spring 3 MVC and ExtJS Forms

In my previous post Beginning Spring MVC 3, I shared a simple tutorial to start developing Spring MVC 3. It covered the tools required and the steps to setup the project. This tutorial will take a step further and walk through how to work with forms – Ext JS form to be specific – for loading of data and submission of data for processing. I will be assuming that you have the tools and project setup.

Step 1. The model. Here I assumed a single bean will represent the form and data model (for data access/persistence). The attributes in the bean are mapped to the form fields.

public class PersonalContact implements Serializable
{
	private static final long serialVersionUID = 1L;
	private Long id;
	private String name;
	private String phone;
	private String email;

	public PersonalContact() {}

	public PersonalContact(Long id, String name, String phone, String email) {
		super();
		this.id = id;
		this.name = name;
		this.phone = phone;
		this.email = email;
	}

	//regenerate the getter & setter using STS.
}

Step 2. The controller. Using the default “HomeController”, I added 2 methods to handle the load and add request. Both methods have simple implementation to illustrate the interaction between the form and Spring MVC. There is no data access/persistence code implemented here.

@Controller
public class HomeController {

	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value="/", method=RequestMethod.GET)
	public String home() {
		logger.info("Welcome home!");
		return "home";
	}

	@RequestMapping(value="/load", method=RequestMethod.POST)
	public @ResponseBody Map<String, ? extends Object> load(PersonalContact input) {
		logger.info("Inside load");
		PersonalContact pc = new PersonalContact(1L, "Wowi", "89281932", "wo.wi@abcxyz.com");
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("success",Boolean.TRUE);
		data.put("data", pc);

		return data;
	}

	@RequestMapping(value="/add", method=RequestMethod.POST)
	public @ResponseBody Map<String, ? extends Object> add(PersonalContact input, HttpSession session) {
		logger.info("Inside add");

		Map<String, Object> data = new HashMap<String, Object>();

		if (input.getName() == null) {
			data.put("success",Boolean.FALSE);
			data.put("errorMessage", "No Name?");
		} else if (session.getAttribute(input.getName()) != null) {
			data.put("success",Boolean.FALSE);
			data.put("errorMessage", "There is an existing data, unable to add. Please enter a different name");
		} else {
			session.setAttribute(input.getName(), input);
			data.put("success",Boolean.TRUE);
		}

		return data;
	}
}

Step 3. The view. Similar to the controller, I built on the default home.jsp. As you can see there isn’t much code in the JSP. The core UI codes are in the JavaScript (spring-mvc-forms.js). By default the response assumed to be in JSON. Do remember to add the Jackson into the pom.xml and set the header to “Accept” application/json.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
	<link href="<c:url value="/resources/lib/ext-3.3.1/resources/css/ext-all.css" />" rel="stylesheet" type="text/css" />
	<script type="text/javascript" src="<c:url value="/resources/lib/ext-3.3.1/adapter/ext/ext-base.js" />"></script>
	<script type="text/javascript" src="<c:url value="/resources/lib/ext-3.3.1/ext-all.js" />"></script>
	<script type="text/javascript">
		if (Ext.BLANK_IMAGE_URL.substr(0, 5) != 'data:') {
			Ext.BLANK_IMAGE_URL = '<c:url value="/resources/lib/ext-3.3.1/resources/images/default/s.gif" />';
		}
		var loadUrl = '<c:url value="/load" />';
		var addUrl = '<c:url value="/add" />';
	</script>
	<script type="text/javascript" src="<c:url value="/resources/js/spring-mvc-forms.js" />"></script>
	<style type="text/css">
		body {
		  	font: normal 12px helvetica,arial,verdana,tahoma,sans-serif;
		}
		.my-form-class {
			margin:  20px 30px;
		}
	</style>
</head>
<body>
</body>
</html>
Ext.onReady(function(){
	Ext.QuickTips.init();

	var mf = new Ext.FormPanel({
			url: addUrl,
			renderTo: Ext.getBody(),
			frame: true,
			cls: 'my-form-class',
			width: 350,
			items: [{
					xtype: 'textfield',
					fieldLabel: 'Name',
					name: 'name'
			},{
					xtype: 'textfield',
					fieldLabel: 'Phone No.',
					name: 'phone'
			},{
					xtype: 'textfield',
					fieldLabel: 'EMail',
					name: 'email'
			}],
			buttons: [{
					id: 'mf.btn.load',
					text: 'Load',
					handler: function() {
						fnLoadForm(mf);
					}
				},{
					id: 'mf.btn.add',
					text: 'Add',
					disabled: true,
					handler: function() {
						fnUpdateForm(mf);
					}
			},{
					id: 'mf.btn.reset',
					text: 'Reset',
					disabled: true,
					handler: function() {
						fnResetForm(mf);
					}
			}]
	});

});

function fnLoadForm(theForm)
{
	//for the purpose of this tutorial, load 1 record.
	theForm.getForm().load({
		url: loadUrl,
		headers: {Accept: 'application/json, text/javascript, */*; q=0.01'},
    waitMsg: 'loading...',
		params : {
			id: 1
		},
		success: function(form, action) {
			Ext.getCmp('mf.btn.add').setDisabled(false);
			Ext.getCmp('mf.btn.reset').setDisabled(false);
			Ext.getCmp('mf.btn.load').setDisabled(true);
		},
		failure: function(form, action) {
			Ext.Msg.alert('Warning', 'Error Unable to Load Form Data.');
		}
	});
} //end fnLoadForm
function fnUpdateForm(theForm)
{
	theForm.getForm().submit({
		success: function(form, action) {
			Ext.Msg.alert('Success', 'Data is stored in session.');
			form.reset();
		},
		failure: function(form, action) {
			Ext.Msg.alert('Warning', action.result.errorMessage);
		}
	});
} //end fnUpdateForm
function fnResetForm(theForm)
{
	theForm.getForm().reset();
	Ext.getCmp('mf.btn.add').setDisabled(true);
	Ext.getCmp('mf.btn.reset').setDisabled(true);
} //end fnResetForm

Now that all the components are ready, launch the example and to begin with click “load” button. The form will be pre-populated with example data. To try the form submission, click “add”. Hope you find the tutorial useful. Happy coding! 🙂

Update: the source project is downloadable at myGit.

Advertisements