Submitting a Form with Angular JS and Spring MVC

José Mendes picture José Mendes · Jun 18, 2015 · Viewed 13.2k times · Source

I am noob with Angular JS and I am having difficulties to submit a simple Form using Angular JS and Spring MVC. I am getting this error:

The requested resource is not available

mock.jsp

<%@taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@taglib prefix="security"uri="http://www.springframework.org/security/tags" %>
<!doctype html>
<html>
<head>
<title>Settings</title>
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/workflow.css">
<link rel="stylesheet" href="css/upload.css">
<link rel="stylesheet" href="css/jquery.qtip.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"> 
<link rel="shortcut icon" href="images/logo-small.png" />

</head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script type="text/javascript">
    var app = angular.module('formSubmit', []);

    app.controller('FormSubmitController',[ '$scope', '$http', function($scope, $http) {

        $scope.list = [];
            $scope.headerText = 'AngularJS Post Form Spring MVC example: Submit below form';
            $scope.submit = function() {

                var formData = {
                        "name1" : $scope.name1,
                        "name2" : $scope.name2,
                        "name3" : $scope.name3,
                };

                var response = $http.post('submitmock', formData);
                response.success(function(data, status, headers, config) {
                    $scope.list.push(data);
                });
                response.error(function(data, status, headers, config) {
                    alert( "Exception details: " + JSON.stringify({data: data}));
                });

                //Empty list data after process
                $scope.list = [];

            };
        }]);
</script>
<style>        
input.ng-invalid {    
    border: 2px red solid;
    }
</style>
<body ng-app="formSubmit">

    <div class="container">
    <div class="col-sm-8 col-sm-offset-2">


        <form  data-ng-submit="submit()" data-ng-controller="FormSubmitController"> <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
            <table border="1">                          
                <tr>
                    <td colspan="2">
                        <label>Name Line 1:</label>
                    </td>
                </tr>               
                <tr>
                    <td colspan="2">
                        <div class="form-group">                            
                            <input type="text" name="name1" class="form-control" ng-model="name1" required ng-Maxlength="40">   
                            <p ng-show="userForm.name1.$error.required"  class="help-block">Name is required.</p>
                            <p ng-show="userForm.name1.$error.maxlength" class="help-block">Maximum 40 characters</p>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <label>Name Line 2:</label>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <div class="form-group">                    
                        <input type="text" name="name2" class="form-control" ng-model="name2" ng-Maxlength="40"> 
                        <p ng-show="userForm.name2.$error.maxlength" class="help-block">Maximum 40 characters</p>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <label>Name Line 3:</label>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <div class="form-group">                        
                        <input type="text" name="name3" class="form-control" ng-model="name3" ng-Maxlength="40"> 
                        <p ng-show="userForm.name3.$error.maxlength" class="help-block">Maximum 40 characters</p>
                        </div>
                    </td>
                </tr>   
                <tr>
                    <td colspan="2">
                        <h4>You submitted below data through post:</h4>
                             <pre>Form data ={{list}}</pre>
                    </td>   
                </tr>               
                <tr>
                    <td colspan="2">
                        <!-- SUBMIT BUTTON -->
                        <button type="submit" class="btn btn-primary" ng-disabled="userForm.$invalid">Submit</button>
                    </td>
                    </tr>
                </table>   

            </form>
    </div>
    </div>

</body>
</html>

mockController.java

package com.opessoftware.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.opessoftware.beans.MockForm;
import com.opessoftware.beans.SettingsForm;

@Controller
public class MockController {

    @RequestMapping("/mock")
    public String getSettingsPage(){
        return "mock";
    }

    @RequestMapping(value = "/angularjs-http-service-ajax-post-code-example", method = RequestMethod.GET)
    public ModelAndView httpServicePostExample( ModelMap model ) {
        return new ModelAndView("httpservice_post");
    }

    @RequestMapping(value = "/submitmock", method = RequestMethod.POST)
    public @ResponseBody MockForm getMock(@RequestBody MockForm mockForm){      
        return mockForm;
    }



}

Please Help.

Spring version = 3.2.0 RELEASE

Answer

Pankaj Parkar picture Pankaj Parkar · Jun 18, 2015

You should have your form structure like below, there would be formData in scope model which will contains name1, name2 & name3, You also missed to add form name which should be name="myForm"

Markup

<form data-ng-submit="submit()" name="myForm" data-ng-controller="FormSubmitController">
    <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
    <table border="1">
        <tr>
            <td colspan="2">
                <label>Name Line 1:</label>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <div class="form-group">
                    <input type="text" name="name1" class="form-control" ng-model="formData.name1" required ng-Maxlength="40">
                    <p ng-show="userForm.name1.$error.required" class="help-block">Name is required.</p>
                    <p ng-show="userForm.name1.$error.maxlength" class="help-block">Maximum 40 characters</p>
                </div>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <label>Name Line 2:</label>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <div class="form-group">
                    <input type="text" name="name2" class="form-control" ng-model="formData.name2" ng-Maxlength="40">
                    <p ng-show="userForm.name2.$error.maxlength" class="help-block">Maximum 40 characters</p>
                </div>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <label>Name Line 3:</label>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <div class="form-group">
                    <input type="text" name="name3" class="form-control" ng-model="formData.name3" ng-Maxlength="40">
                    <p ng-show="userForm.name3.$error.maxlength" class="help-block">Maximum 40 characters</p>
                </div>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <h4>You submitted below data through post:</h4>
                <pre>Form data ={{list}}</pre>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <!-- SUBMIT BUTTON -->
                <button type="submit" class="btn btn-primary" ng-disabled="userForm.$invalid">Submit</button>
            </td>
        </tr>
    </table>
</form>

After making this changes in Markup you need to sort your controller with some code, As you server side method is asking for mockForm parameter, you should pass formData value in it.

Code

$scope.formData = {}; //should set object on init.
$scope.submit = function() {
    var response = $http.post('submitmock',{ mockForm: formData}); //passing mockForm
    response.success(function(data, status, headers, config) {
        $scope.list.push(data);
    });
    response.error(function(data, status, headers, config) {
        alert("Exception details: " + JSON.stringify({
            data: $scope.formData //used formData model here
        }));
    });

    //Empty list data after process
    $scope.list = [];
};