How to send form data to Spring controller using ajax / How to Submit Form using ajax

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:

form

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() or doPost()) 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

  1. HTML form may also be created using Spring form tag library in which name attribute will be replaced with path.
  2. 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.
  3. The value of “url” option in ajax request should match the “action” attribute of the form which is to be submitted.
  4. The value of “type” option in ajax request should match the “type” attribute of the form which is to be submitted.
  5. form.attr('action') retrieves the value of “action” attribute of the form element. It utilizes the attr() method of jQuery to get a value of an element attribute.
  6. 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.
  7. Instead of referring form attributes with form.attr(attributeName), we may also use $(this).attr(attribteName) inside the submit method as form object itself has generated the submit event.

2 Comments

  1. Hi.

    im trying to follow this guide but y get a erro form.attr() is not a function.

    Any idea what can be the problme?

    Thank you.

    1. Author

      Did you assign a real form object to the form variable as given in the post(var form = this; where this is the form object). The error states that you are calling attr() function on an object which is not a form. Post the entire code so that further help can be provided.

Leave a Reply