How to send table data from HTML form submit via ajax call to Spring MVC controller - ajax

Say i have a HTML table in a format similar to this
<form> <table id="a">
<thead>
<th>Name</th>
<th>Series</th>
<th>Value</th>
</thead>
<tbody id="b">
<tr><td>Enhancer</td><td>Enhancement</td><td>50</td></tr>
<tr><td>Plans</td><td>Plan</td><td>50</td></tr>
</tbody>
</table>
<input type="submit" value="Send" action="SomeControllerAction" /></form>
which has two rows under the headings "Name","Series" and "Value" .
I need to send this data via a form submit to a Spring Controller with Ajax where i can get or set the values for each row iteratively in a Model.
I am not sure how to achieve this . That is how to send the data in a table to a spring controller method and get the values .
Help with code segments!
Thanks

Although the previous answer is correct, I would suggest to introduce a class that contains three fields : name, series and value.
This class should have a meaningful name.
Here I named it MyObject because I don't know what you app is about.
MyObject :
public class MyObject {
private String name, series;
private Integer value;
// Getters and setters
}
Controller (the return type might be different)
#PostMapping("/series")
#ResponseBody
public List<MyObject> postSeries(#RequestBody List<MyObject> myObjects) {
myObjects.forEach(System.out::println);
// Handle myObjects
return myObjects;
}
JSP
<table id="tableMyObjects">
<thead id="a">
<tr>
<th>Name</th>
<th>Series</th>
<th>Value</th>
</tr>
</thead>
<tbody id="b">
<tr>
<td><input type="text" name="name" /></td>
<td><input type="text" name="series" /></td>
<td><input type="text" name="value" /></td>
</tr>
<tr>
<td><input type="text" name="name" /></td>
<td><input type="text" name="series" /></td>
<td><input type="text" name="value" /></td>
</tr>
</tbody>
</table>
<button id="postButton">Post myObjects</button>
jQuery
$('#postButton').click(function() {
var myObjects = [];
$('#b tr').each(function(index, item) {
var $item = $(item);
myObjects.push({
name: $item.find("td input[name='name']").val(),
series: $item.find("td input[name='series']").val(),
value: $item.find("td input[name='value']").val(),
});
});
$.ajax({
url: '/series',
method: 'POST',
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(myObjects)
})
.done(function(myObjects) {
// handle success
})
.fail(function() {
// handle fail
});
});

Using javascript/jquery you can do that easily.
Generate a input type hidden text field while iterating the table content like below with the same name.
<tbody id="b">
<tr>
<td>
<input type="hidden" name="Name" value="Enhancer" />
Enhancer
</td>
<td>
<input type="hidden" name="Series" value="Enhancement" />
Enhancement
</td>
<td>
<input type="hidden" name="Value" value="50" />
50
</td>
</tr>
</tbody>
and then get all the hidden fields values by name like below.
$("[name='Name']").val();
$("[name='Series']").val();
$("[name='Value']").val();
and then in controller accept those parameters as an array like below.
#RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(#RequestParam(value = "Name") String[] Name,
#RequestParam(value = "Series") String[] Series,
#RequestParam(value = "Value") String[] Value,
BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest){
//code goes here
}
NOTE : You have to write javascript code to set the hidden field values for multiple rows something like this Call javascript function with if JSTL

Related

Spring MVC: Neither BindingResult nor plain target object for bean name 'marks' available as request attribute. Tried all solutions

I tried all the solutions but I keep getting this error. Moreover if i don't use form:form in jsp file and use a simple HTML, I get the desired output.
Controller Class
#Controller
public class controller_class {
/*
* #RequestMapping(path = "/index", method = RequestMethod.GET) public
* ModelAndView mar() { return new ModelAndView("index","command",new marks());
* }
*/
#RequestMapping("/index")
public ModelAndView showComments() {
return new ModelAndView("marks","command",new marks());
}
#RequestMapping(value = "/addMarks", method = RequestMethod.POST)
public ModelAndView stud(#ModelAttribute("marks") marks m) {
ModelAndView mv = new ModelAndView("result");
int k = m.calculate();
mv.addObject("tot_marks", k);
return mv;
}
}
index.jsp
<form:form method = "POST" modelAttribute="marks" action = "/springmvc_qa3/addMarks">
<table>
<tr>
<td><form:label path = "sci_marks">Name</form:label></td>
<td><form:input path = "sci_marks" /></td>
</tr>
<tr>
<td><form:label path = "maths_marks">Age</form:label></td>
<td><form:input path = "maths_marks" /></td>
</tr>
<tr>
<td><form:label path = "eng_marks">id</form:label></td>
<td><form:input path = "eng_marks" /></td>
</tr>
<tr>
<td colspan = "2">
<input type = "submit" value = "Submit"/>
</td>
</tr>
</table>
</form:form>
</body>
Correct Output if I use this instead
<form method="POST" action="/springmvc_qa3/addMarks" >
<table>
<tr>
<td><label >Science Marks</label></td>
<td><input type="text" name="sci_marks" /></td>
</tr>
<tr>
<td><label >Mathematics Marks</label></td>
<td><input type="text" name="maths_marks" /></td>
</tr>
<tr>
<td><label >English Marks</label></td>
<td><input type="text" name="eng_marks" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
</form>
What is the reason that I can't get the right output using the first method?
add the following to your controller class:
#ModelAttribute("marks")
public Marks nameOfMethodDoesntMatter(){
return new Marks();
}
make sure your Marks class has getters, setters and default constructor.
consider calling your class MarksDTO or something similar to convey its meaning better (DTO = data transfer object).

Write handler methods for dynamically generated buttons and text boxes

I have this small data on JSP form. I use JSTL to iterate over data. In each row, I have two dynamically generated textboxes and a button. Question is: how do I write a generic handler method for this data, which handles dynamically generated textboxes and buttons. Here is my JSP
<c:forEach items="${menus}" var="menu" >
<tr>
<td align="left" >${menu.getMenuId()}</td>
<td align="right"><input type="text" name="menu_name" value="${menu.getMenuName()}"/></td>
<td align="right"><input type="text" name="menu_price" value="${menu.getMenuPrice()}"/></td>
<td align="right"><c:out value="${menu.getIsAvailable()}" /></td>
<td align="right"><input type="submit" value="Add Item ${menu.getMenuId()}"></td>
</tr>
</c:forEach>
<h4>Add Product</h4>
Name: <input type="text" name="chosen_menu_name" />
Price: <input type="text" name="chosen_menu_price" />
<input type="submit" value="Add to cart">
And here is my controller (though I dont know what to put it there - at the moment I am using two seperate textbox and a button for taking the input)
#RequestMapping(method = RequestMethod.POST)
public ModelAndView AddMenu(#RequestParam("chosen_menu_name") String mymenu, #RequestParam("chosen_menu_price") String menu_price, #ModelAttribute("cart") ArrayList<Menu> mycart, Model model)
{
Menu menu = new Menu();
menu.setMenuId(0);
menu.setMenuName(mymenu);
menu.setMenuPrice(Double.parseDouble(menu_price));
model.addAttribute("menus", GetMenus());
mycart.add(menu);
return new ModelAndView("edit_menu");
//return "show_menu";
}
As one can see from the JSP, I am using two seperate textboxes and a button for taking input and passing it to the controller. How do I write a generic handler method for this data, which handles dynamically generated textboxes and buttons?
I'm assuming that you don't want those other two field and button. You want to add items directly from table.
You have to make each and every row as one form like below :
<c:forEach items="${menus}" var="menu" >
<tr>
<form method="POST" action="controllerName">
<td align="left">
${menu.getMenuId()}
<input type="hidden" name="menu_id" value="${menu.getMenuId()}"/>
</td>
<td align="right">
<input type="text" name="menu_name" value="${menu.getMenuName()}"/>
</td>
<td align="right">
<input type="text" name="menu_price" value="${menu.getMenuPrice()}"/>
</td>
<td align="right">
<c:out value="${menu.getIsAvailable()}"/>
</td>
<td align="right">
<input type="submit" value="Add Item">
</td>
</form>
</tr>
</c:forEach>
And controller like below:
#RequestMapping(method = RequestMethod.POST)
public ModelAndView AddMenu(#RequestParam("menu_id") String menuId, #RequestParam("menu_name") String mymenu, #RequestParam("menu_price") String menu_price, #ModelAttribute("cart") ArrayList<Menu> mycart, Model model)
{
Menu menu = new Menu();
menu.setMenuId(menuId);
menu.setMenuName(mymenu);
menu.setMenuPrice(Double.parseDouble(menu_price));
model.addAttribute("menus", GetMenus());
mycart.add(menu);
return new ModelAndView("edit_menu");
//return "show_menu";
}

Value is not getting pass from view to action method

i am new in mvc. i have design a form and when i am click the submit button then right action method is calling but form field's value are not getting pass.
here is my view code
<div id="mydiv">
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>Name :</td>
<td><input name="name" type="text" /></td>
</tr>
<tr>
<td>Salary :</td>
<td><input name="salary" type="text" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Save" /> </td>
</tr>
</table>
}
</div>
here is my action method
public ActionResult Save(string str1, string str2)
{
return View("Message");
}
when save is getting called the str1 & str2 is being null please help me to pass value and also discuss various trick to pass value from view to action method. thanks
Change you controller
public ActionResult Save(string name, string salary)
{
return View("Message");
}
As you have to use variable name which you have defined in input
<input name="name" type="text" />
<input name="salary" type="text" />
If you want to return partial view.
return PartialView("Message", <<OptionalPartialViewModel>>);
You should start by learning about conventions in ASP.NET MVC. You should use models for communicating between controllers and views.
Create a model type first:
public class SalaryModel
{
public string Name { get; set; }
public string Salary { get; set; }
}
Create your form by using HTML helpers and strongly typing your view:
#model SalaryModel
<div id="mydiv">
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>Name :</td>
<td>#Html.TextBoxFor(item => item.Name)</td>
</tr>
<tr>
<td>Salary :</td>
<td><input name="salary" type="text" /></td>
</tr>
<tr>
<td colspan="2">#Html.TextBoxFor(item => item.Salary)</td>
</tr>
</table>
}
</div>
Then you can get the form values inside the model:
[HttpPost]
public ActionResult Save(SalaryModel model)
{
return View("Message");
}
There's a great tutorial on ASP.NET MVC website that can help you with the basics.
MVC Bind form inputs to Action by their names. You should change your method params as the same of the form. Also, you are missing the HttpPost attribute:
[HttpPost]
public ActionResult Save(string name, string salary)
{
/*Do Stuff here*/
return View("Message");
}

Values for th:field attributes in checkbox

I have table with datas from database (insert dynamically). In one column I insert checkbox. Now I want to select one of them and send to next form (I select one product and send properties to another form. In this form should be displayed properties only the select product). But I don't know what kind of value insert in th:field="*{}". I tried many solutions but doesn't work. My html form with all products table:
<form action="/oferta/zamow" th:action="#{/oferta/zamow}"
th:object="${oferta}" method="post">
<table border="1" id="display-data">
<tr>
<td>#</td>
<td>title</td>
<td>author</td>
<td>rok</td>
<td>cena</td>
<td></td>
</tr>
<tr th:each="produkt, pozycja : ${oferta}">
<td th:text="${pozycja.count}"></td>
<td><span th:text="${produkt.tytul}"></span></td>
<td><span th:text="${produkt.autor}"></span></td>
<td><span th:text="${produkt.rok}"></span></td>
<td><span th:text="${produkt.cena}"></span></td>
<td>
<input type="submit" value="zamow"/>
<!-- <a th:href="#{/zamowienie}">zamow</a> -->
</td>
<td>
<label>zamow</label>
<input type="checkbox" th:field="*{produkt}" th:value="${produkt}"/>
</td>
</tr>
</table>
</form>
Form to display select product:
<form action="/zamowienie/zam" th:action="#{/zamowienie/zam}"
th:object="${zamowienie}" method="post">
<table border="1" id="display-data">
<tr align="center">
<td colspan="2">twoje zamowienie</td>
</tr>
<tr>
<td>tytul</td>
<td><span th:text="${produkt.tytul}"></span></td>
</tr>
<tr>
<td>autor</td>
<td><span th:text="${produkt.autor}"></span></td>
</tr>
<tr>
<td>rok</td>
<td><span th:text="${produkt.rok}"></span></td>
</tr>
<tr>
<td>cena</td>
<td><span th:text="${produkt.cena}"></span></td>
</tr>
<tr>
<td>data zlozenia zamowienia</td>
<td><span th:text="${datazam}"></span></td>
</tr>
</table>
</form>
Thanks for help.
I am not sure if this is the answer you seek, but you can find an example at http://www.thymeleaf.org/doc/html/Thymeleaf-Spring3.html#checkbox-fields.
Here is a simple example to illustrate how to use a checkbox in Thymeleaf with Spring MVC.
Controller:
#RequestMapping(value = "/showForm", method=RequestMethod.GET)
public String showForm(Model model) {
List<String> allItems = new ArrayList<String>();
allItems.add("value1");
allItems.add("value2");
allItems.add("value3");
model.addAttribute("allItems", allItems);
Foo foo = new Foo();
List<String> checkedItems = new ArrayList<String>();
// value1 will be checked by default.
checkedItems.add("value1");
foo.setCheckedItems(checkedItems);
model.addAttribute("foo", foo);
...
}
#RequestMapping(value = "/processForm", method=RequestMethod.POST)
public String processForm(#ModelAttribute(value="foo") Foo foo) {
// Get value of checked item.
List<String> checkedItems = foo.getCheckedItems();
...
}
html:
<form action="#" th:action="#{/processForm}" th:object="${foo}" method="post">
<div th:each="item : ${allItems}">
<input type="checkbox" th:field="*{checkedItems}" th:value="${item}" />
<label th:text="${item}">example</label>
</div>
<input type="submit" />
</form>
Foo.java:
public class Foo {
private List<String> checkedItems;
public List<String> getCheckedItems() {
return checkedItems;
}
public void setCheckedItems(List<String> checkedItems) {
this.checkedItems = checkedItems;
}
}
Hope this helps.
Take a look at the thymeleaf spring integration docs.
All th:field are mapped against the command object. Thats why you need the *{} expression.
One thing the template engine is not able to do (yet) is mapping fields inside a loop directly. So you cannot use the *{} approach to reference the produkt variable from the loop.
What you have to do is use the index of the th:each expression and build a property accessor with a pre-evaluated expression for the index.
<input type="checkbox" th:field="*{produkts[__${index}__].checked" />
You do not need the th:value, th:field is taking care of it. (Except if you want to superseed it)

How are Spring MVC Controllers being bound to JSP pages?

Hi I am new to spring and I am trying to develop a simple portlet that accepts users first and last name and saves it to db using hibernate.
Basically I cannot figure out how the jsps and controllers communicate; I am missing some chunk here.
This is my first controller that needs to be called (where do I mention so?)
package codes.controller;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value="SimpleUserController")
#RequestMapping(value = "VIEW")
public class SimpleUserController {
// -- auto-wiring of service dependency
#Autowired
#Qualifier("userService")
private UserService userService;
// --maps the incoming portlet request to this method
#RenderMapping
public String showUsers(RenderResponse response) {
return "home";
}
#ExceptionHandler({ Exception.class })
public String handleException() {
return "errorPage";
}
// -- #ModelAttribute here works as the referenceData method
#ModelAttribute(value="user")
public User getCommandObject() {
return new User();
}
}
Initially I am displaying a home.jsp that will display the form with two input boxes and a submit button.
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<form:form name="home" commandName="user" method="post"
action="${addUserActionUrl}">
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" value="SUBMIT" /></td>
</tr>
</table>
</table>
</form:form>
This JSP should call the action method in the AddUserController.java:
package codes.controller;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value = "AddUserController")
#RequestMapping(value = "VIEW")
public class AddUserController {
#Autowired
#Qualifier("userService")
private UserService userService;
#RenderMapping(params = "myaction=addUser")
public String showRegisterPage(Model model) {
model.addAttribute("user", new User());
model.addAttribute("users", getUsers());
return "addUser";
}
public List<User> getUsers() {
return userService.getAllUsers();
}
#ActionMapping(params = "myaction=addUser")
public void addBook(#ModelAttribute(value = "user") User user,
BindingResult bindingResult, ActionResponse response,
SessionStatus sessionStatus) {
if (!bindingResult.hasErrors()) {
userService.addUser(user);
response.setRenderParameter("myaction", "users");
sessionStatus.setComplete();
} else {
response.setRenderParameter("myaction", "addUser");
}
}
}
This time this firstname+last name should be saved in the db AND the screen should refresh to show a new form that will have a dropdown with the current users' names in the database and another first name and last name form fields. If you select a username from the dropdown the form fields are populated and you can edit these values and click on UPdate button to save the values in DB. Otherwise you can add a new user to the database using submit button.
addUser.jsp:
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<portlet:renderURL var="homeUrl">
<portlet:param name="myaction" value="Users" />
</portlet:renderURL>
<script type="text/javascript" src="js/userRelated.js"></script>
<form:form name="addUser" commandName="user" method="post"
action="${addUserActionUrl}">
<form:select path="model">
<form:option value="NONE" label="--- Select ---" id="userList" onchange="showHide()"/>
<form:options items="${users}" />
</form:select>
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" id="submit" value="SUBMIT" />SUBMIT</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="update" value="SUBMIT" />UPDATE</td>
</tr>
</table>
</table>
</form:form>
I am hiding and unhiding the SUBMIT/UPDATE button using onchange of dropdown. How do I call different functions in the addUsercontroller depending on the button available?
by updating the action attribute of form element with javascript

Resources