There are scenarios where you want to silently post a form to server or submit a form without a page refresh. Typical example is a Facebook page where you comment on a post. When you comment, the page is not refreshed but the comment is saved somewhere on the server which means that a save request is sent without entire page submit.
This involves the use of ajax. As soon as we decide to use ajax, a question arises as to how we would send form data from jsp to server without page submit and there would be a big hassle involved in form data transmission. Well!!! After reading this post, you won’t feel the same.
Let’s say we have an html form as shown below:
HTML code for this form will be:
Note : Styling and css classes have been removed from this code to keep it simple.
The entity or dto to which these form elements are mapped should be:
public class SysUserDto {
private String name;
/* Class fields */
private String address;
private String phone;
private Integer zipCode;
/* Getter and Setter methods */
public String getName() {
return name;
}
public void setName(String username) {
this.name = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getZipCode() {
return zipCode;
}
public void setZipCode(Integer zipCode) {
this.zipCode = zipCode;
}
}
Spring controller code will be:
@RequestMapping(value = "saveUser", method = RequestMethod.POST)
public void saveUser(@RequestBody User user) {
//code to save user object
}
And now comes the client side code to collect form data and send it to the server. We are using jQuery to send ajax request:
$('#submitForm').submit(function(e) {
// reference to form object
var form = this;
// for stopping the default action of element
e.preventDefault();
// mapthat will hold form data
var formData = {}
//iterate over form elements
$.each(this, function(i, v){
var input = $(v);
// populate form data as key-value pairs
// with the name of input as key and its value as value
formData[input.attr("name")] = input.val();
});
$.ajax({
type: form.attr('method'), // method attribute of form
url: form.attr('action'), // action attribute of form
dataType : 'json',
// convert form data to json format
data : JSON.stringify(formData),
});
});
Here “submitForm” is the id of element (button or a link) on whose click we want to post the form data. We need to call preventDefault()
method to stop the element from performing its default action (such as submit page of submit button).
Next, we iterate over the form elements and store their values in a map where the key of the map is the name attribute of the element (and it should match with the corresponding field of entity on the server). This map is then sent to the server as a part of the request. stringify()
method of JSON
class converts the map’s key-value pairs into json format and hence it matches with the value of dataType
attribute of ajax
method.
At the controller side, all the fields of the entity which match with the name attribute of the form elements are automatically populated. Don’t forget to annotate the controller method argument with @RequestBody
. This annotation tells the container that this parameter will receive its value from the body of the request.
Various parameters of $.ajax used in this request are explained below :
- type : Specifies the HTTP request type (GET or POST). Its value should match with the
method
attribute of@RequestMapping
annotation on Spring controller or with the type of method(doGet()
ordoPost()
) created to handle the url of this request on a servlet. - url : The url at which this request will be sent. Its value should match with the
value
attribute of@RequestMapping
annotation on Spring controller or with the url-mapping of servlet created to handle this request in web.xml file. - dataType : The format in which this request will send its parameters (or form data).
- data : Parameters sent with this request. Typical value of this attribute is of the form data:”name=codippa&address=India”. Multiple parameters are identified with their names and separated by “&”. Since the parameter on the server is annotated with
@RequestBody
annotation, there is no need to provide a name to the request parameter since they are sent in the body of the request.
Let’s tweak in
- HTML form may also be created using Spring form tag library in which name attribute will be replaced with path.
- The value of name attribute in form input elements should exactly match the field names of entity/dto used in controller for value mapping to take place.
- The value of “url” option in ajax request should match the “action” attribute of the form which is to be submitted.
- The value of “type” option in ajax request should match the “type” attribute of the form which is to be submitted.
form.attr('action')
retrieves the value of “action” attribute of the form element. It utilizes theattr()
method of jQuery to get a value of an element attribute.- The value of “url” and “action” attributes may be a direct value such as “saveUser” and “Post” respectively.
form.attr(attributeName)
just replaces the value of corresponding attribute and minimizes the number of modifications to be done if the value of action or url of the form change. - Instead of referring form attributes with
form.attr(attributeName)
, we may also use $(this).attr(attribteName) inside thesubmit
method as form object itself has generated the submit event.