ExtJS : Simple Form with Servlet

In the previous post we saw how to structure an app. Lets create a simple registration form and send data to backend service. As done previously, we will have a registration.html pointing to registrationApp.js which will be the entry point to our app. registration.html :


<!DOCTYPE html>
<html>
<head>
<title>Registration</title>
 
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
<script type="text/javascript" src="extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="registrationApp.js"></script>
</head>
<body></body>
</html>

registrationApp.js:


Ext.application({
 requires : [ 'Ext.container.Viewport' ],
 name : 'Register',
 appFolder : 'registrationApp',
 controllers: ['RegistrationController'],
 launch : function() {
 console.log('Registration App launch');
 Ext.create('Ext.container.Viewport', {
 layout : 'fit',
 items : [
 {
 xtype : 'regForm'
 }
 ]
 });
 }
});

RegistrationController.js:


Ext.define('Register.controller.RegistrationController', {

extend : 'Ext.app.Controller',
 views : [ 'RegistrationView' ],
 init : function() {
 console.log('Controller InIt');
 }

});

RegistrationView.js:


Ext.define('Register.view.RegistrationView', {

extend : 'Ext.panel.Panel',
 alias : 'widget.regForm',
 title : 'Registration',
 padding : '10,0,0,10',// Top, right, bottom, left
 items : [ {
 xtype : 'textfield',
 name : 'fname',
 fieldLabel : 'First Name',
 padding : '5,0,0,10',// Top, right, bottom, left
 allowBlank : false,
 vtype : 'alpha'
 }, {
 xtype : 'textfield',
 name : 'lname',
 fieldLabel : 'Last Name',
 padding : '5,0,0,10',
 allowBlank : false,
 vtype : 'alpha'
 }, {
 xtype : 'textfield',
 name : 'email',
 fieldLabel : 'Email',
 padding : '5,0,0,10',
 allowBlank : false,
 vtype : 'email'
 }, {
 xtype : 'datefield',
 fieldLabel : 'DOB',
 allowBlank : false,
 padding : '5,0,0,10',
 editable : false
 }, {
 xtype : 'button',
 margin : '5,0,0,100',
 text : 'Submit'
 } ]
});

Running registration.html

RegistrationResult0

So far so good, the entry point registrationApp.js has controller mapped to it, the controller has the view details it needs to listen. Notice appFolder : ‘registrationApp‘, so extjs will search this folder for views/controllers folders etc. Also, since name : ‘Register‘, everything neds to be define using this (Ext.define(‘Register.view.RegistrationView etc.).
define is for declaring a class. Ext.define(‘Foo’, { extend: ‘Bar’ });
create is for creating an instance: var o = Ext.create(‘Foo’); // Can also have var o = new Foo();

ExtJS has a special container class called Ext.container.Viewport. This container is special because it automatically renders itself to the document body. It is quite greedy, eating up all of the available viewable space in the browser’s viewport. In addition to this, the Viewport is self-aware of its surroundings, so it will automatically resize itself with the browser window. Notice in the registrationApp.js, we are creating the viewport in the launch function. and then putting items into it. Sometimes its best to have creation part elsewhere which will lead to better maintainabilty. You can also create different regions in viewport to separate different sections of the application view like header, left bar, right bar, center area and footer area. If you set autoCreateViewport: true in Ext.application, then it will automatically launch viewport.js from the view folder. Creating Viewport.js inside view folder:


Ext.define('Register.view.Viewport', {
extend : 'Ext.container.Viewport',
layout: {
type: 'border'
},
items : [ {
region: 'north',
margins: '0 0 5 0',
title:'Header (north region)',
height: 50,
html:'Header information goes here'
}, {
region: 'west',
title: 'Left bar (west region)',
width: 150,
html:'Navigation goes here'
},{
region: 'center',
xtype : 'regForm'

},{
region: 'south',
title: 'Footer (south region)',
html: 'Footer Information goes here',
height: 50

} ]
});

Changing registrationApp.js


Ext.application({
requires : [ 'Ext.container.Viewport' ],
name : 'Register',
appFolder : 'registrationApp',
controllers: ['RegistrationController'],
autoCreateViewport: true,
launch : function() {
console.log('Registration App launch');
}
});

Running registration.html

RegistrationResult1

Lets create backend service to . Creating a model class that maps to the form – RegistrationModel.java


package mynotes.model;

public class RegistrationModel {

String fname = null;
String lname = null;
String email = null;
String dateOfBirth = null;
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}

}

Creating a Servlet – RegistrationServlet.java


package mynotes.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

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

import mynotes.model.RegistrationModel;

import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class RegistrationServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}

@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String loginData = request.getParameter("registrationData");
Gson gson = new Gson();
RegistrationModel registrationModel = gson.fromJson(loginData,
RegistrationModel.class);
System.out.println("Fname=>" + registrationModel.getFname());
System.out.println("lname=>" + registrationModel.getLname());
System.out.println("email=>" + registrationModel.getEmail());

String dateString = registrationModel.getDateOfBirth();
System.out.println("dateString=>" + registrationModel.getDateOfBirth());
DateFormat formatter = new SimpleDateFormat("MM/DD/yyyy");
boolean isEligible = false;
final Calendar c = Calendar.getInstance();
try {
c.setTime(formatter.parse(dateString));
System.out.println(c.get(Calendar.YEAR));
if (c.get(Calendar.YEAR) <= 2000) {
isEligible = true;
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("isEligible=>"+isEligible);
PrintWriter out = response.getWriter();
response.setContentType("text/html");
response.setHeader("Cache-control", "no-cache, no-store");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "-1");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,GET");
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
response.setHeader("Access-Control-Max-Age", "86400");
JsonObject myObj = new JsonObject();
if (isEligible) {
myObj.addProperty("success", true);
myObj.addProperty("message", "Cograts registration success!");
} else {
myObj.addProperty("success", false);
myObj.addProperty("message", "Sorry!, Not Eligible");
}

out.println(myObj.toString());
out.close();

}

}

For JSON conversion I am using gson-2.2.4.jar. Keep this in your classpath. The buniness logic is quite simple, if the person is born before 2000, registration will return true. Adding the servlet mapping in 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" 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>MyNotes_ExtJS</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>register</servlet-name>
<servlet-class>mynotes.servlets.RegistrationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>register</servlet-name>
<url-pattern>/register</url-pattern>
</servlet-mapping>
</web-app>

Now lets get back to the front end. Changing the view – RegistrationView.js


Ext.define('Register.view.RegistrationView', {

extend : 'Ext.form.Panel',
alias : 'widget.regForm',
title : 'Registration',
padding : '10,0,0,10',// Top, right, bottom, left
items : [ {
xtype : 'textfield',
name : 'fname',
fieldLabel : 'First Name',
padding : '5,0,0,10',// Top, right, bottom, left
allowBlank : false,
vtype : 'alpha'
}, {
xtype : 'textfield',
name : 'lname',
fieldLabel : 'Last Name',
padding : '5,0,0,10',
allowBlank : false,
vtype : 'alpha'
}, {
xtype : 'textfield',
name : 'email',
fieldLabel : 'Email',
padding : '5,0,0,10',
allowBlank : false,
vtype : 'email'
}, {
xtype : 'datefield',
fieldLabel : 'DOB',
name : 'dateOfBirth',
allowBlank : false,
padding : '5,0,0,10',
editable : false
} ],
buttons : [ {
text : 'Submit',
action : 'register'
}, {
text : 'Reset',
handler : function() {
this.up('form').getForm().reset();
}
} ]
});

Notice the buttons action and hadler attributes. Chaging the controller to hadle events – RegistrationController.js


Ext.define('Register.controller.RegistrationController',
{

extend : 'Ext.app.Controller',
views : [ 'RegistrationView' ],
init : function() {
console.log('Controller InIt');
this.control({

//when the viewport is rendered
'viewport > panel' : {
render : this.onPanelRendered
},
//when you click Submit button
'regForm button[action=register]' : {
click : this.onRegisterClick
}
});
},
onPanelRendered : function() {
//just a console log to show when the panel is rendered
console.log('The panel was rendered');
},

onRegisterClick : function(button) {
//just a console log to show when the Login Ajax request starts
console.log('onRegisterClick Ajax Request in progress');

var form = button.up('form').getForm();
if (form.isValid()) {
//create an AJAX request
Ext.Ajax.request({
url : 'register',
method : 'POST',
params : {
registrationData: Ext.encode(form.getValues())
},
scope : this,
//method to call when the request is successful
success : this.onRegisterSuccess,
//method to call when the request is a failure
failure : this.onRegisterFailure
});
}
},

onRegisterFailure : function(err) {
//Alert the user about communication error
Ext.MessageBox.alert('Error occured during registration',
'Please try again!');
},

onRegisterSuccess : function(response, opts) {
//Received response from the server
response = Ext.decode(response.responseText);
if (response.success) {
Ext.MessageBox.alert('Successful Registration', response.message);
} else {
Ext.MessageBox.alert('Registration failed', response.message);
}
}

});

Notice the control events. Whenever in the regForm (alias of out registration form),  has an action called ‘register’, onRegisterClick function will be called. This fuction will check if the form is valid or not before making any ajax request. url is the address where the request is to be made with POST. ‘params’ contains the ‘registrationData’ which will have form values. Note that this the the key which you will be getting in servlet as getParameter. If the response is success, response message will be alerted.

RegistrationResult2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: