EDIT:
I want to show a spring-mvc dropdown box out of a object list which is a property from another class.
I did this after searching:
<sf:form action="${pageContext.request.contextPath}/venta/save"
method="post" commandName="venta">
<table>
<tr>
<td>Número de factura</td>
<td><sf:input path="numero_factura" type="text" /></td>
<td><sf:errors path="numero_factura" cssclass="error" /></td>
</tr>
<tr>
<td>Producto:</td>
<td><sf:select path="${producto.nombreProducto}">
<sf:option value="" label="...." />
<sf:options items="${productos}" />
</sf:select></td>
<td><sf:errors path="${producto.nombreProducto}"
cssclass="error" cssStyle="color: #ff0000;" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Guardar cambios"></td>
</tr>
<tr>
</table>
</sf:form>
The class I'm mapping is this:
Venta.class
#Entity
public class Venta implements Serializable {
#Id
#NotNull
#Digits(integer=12, fraction = 0)
private Integer numero_factura;
#LazyCollection(LazyCollectionOption.FALSE)
#ManyToMany
#NotEmpty
private List<Producto> productos = new ArrayList<Producto>();
private Date fechaDeIngreso;
#ManyToOne(cascade = CascadeType.ALL)
private Empleado empleado;
public Venta() {
}
...
}
And this is the controller:
#Controller
public class VentaController {
#Autowired
public IServiceProducto serviceProducto;
#Autowired
public IServiceVenta serviceVenta;
#Autowired
public IServiceEmpleado serviceEmpleado;
#RequestMapping("/venta")
public String showVenta(Model model, HttpSession session) {
// Model es una interfaz que nos permite definir atributos en el modelo
init(model);
return "venta";
}
#RequestMapping(value = "/venta/save", method = RequestMethod.POST)
public String handleVenta(#Valid #ModelAttribute("venta") Venta ventaForm, BindingResult result, Model model,
HttpSession session, RedirectAttributes ra) {
try {
if (result.hasErrors()) {
model.addAttribute("productos", serviceProducto.getAll());
return "venta";
}
Empleado empleado = (Empleado) session.getAttribute("empleado");
empleado.setVenta(ventaForm);
serviceVenta.exist(ventaForm);
serviceEmpleado.addChild(empleado, ventaForm);
ra.addFlashAttribute("resultado", "La venta fué agregada exitosamente");
return "redirect:/venta";
} catch (ServicioException e) {
ra.addFlashAttribute("resultado", e.getMessage());
return "redirect:/venta";
}
}
public void init(Model model){
Venta venta = new Venta();
Producto producto = new Producto();
model.addAttribute("venta", venta);
model.addAttribute("producto", producto);
model.addAttribute("productos", serviceProducto.getAll());
}
}
It gives me the view I was looking for, but this code is doing nothing when it comes to select an item from the dropdown box and hitting the submit button. It gives me no error and stay static in http://localhost:8585/electronicaDonPepe/venta/save
Please please help me, I'm almost there !
OLD VERSION:
I want to show a combobox in jsp from a list. It gives me a dropdownlist which I don't want.
I made a map with the list and it gives me the same result.
Venta.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<sf:form action="${pageContext.request.contextPath}/venta/save"
<td>Producto</td>
<td>
<sf:select path="productos">
<sf:option label="---select---" value="NONE"/>
<sf:options items="${productos}"/>
</sf:select>
</td>
<td><sf:errors path="productos" cssClass="error"/> </td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Guardar cambios"></td>
</tr>
</table>
</sf:form>
<c:out value="${resultado}"></c:out>
</body>
</html>
Necessary VentaController.java code to understand
#Controller
public class VentaController {
#Autowired
public IServiceProducto serviceProducto;
#Autowired
public IServiceVenta serviceVenta;
#Autowired
public IServiceEmpleado serviceEmpleado;
#RequestMapping("/venta")
public String showVenta(Model model, HttpSession session) {
// Model es una interfaz que nos permite definir atributos en el modelo
Venta venta = new Venta();
model.addAttribute("venta", venta);
List<Producto> listaProductos = serviceProducto.getAll();
Map<String, String> mapaProductos = new LinkedHashMap<String, String>();
for (Producto producto : listaProductos) {
mapaProductos.put(producto.getNombreProducto(), producto.getNombreProducto());
}
model.addAttribute("productos", mapaProductos);
return "venta";
}
The result is a list with multiple selections. I'm aware that if I use the property multiple=false the multiple selection will be off but it still work in my case.
DropdownList with multiple selection
Still, I want a combobox function and not a dropdownlist without multiple selection.
This is my idea of what I want:
select with options
I have this approach:
<sf:form action="${pageContext.request.contextPath}/venta/save"
method="post" commandName="ventaDTO">
<table>
<tr>
<td>Número de factura</td>
<td><sf:input path="numero_factura" type="text" />
<td><sf:errors path="numero_factura" cssclass="error" /></td>
</tr>
<tr>
<td>Producto:</td>
<td><sf:select path="nombreProducto">
<sf:option value="" label="...." />
<sf:options items="${productos}" />
</sf:select> <sf:errors path="nombreProducto" cssclass="error"
cssStyle="color: #ff0000;" /></td>
<td>
<td><sf:input path="cantidadProductos" type="text" />
<sf:errors
path="cantidadProductos" cssclass="error"
cssStyle="color: #ff0000;" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Guardar cambios"></td>
</tr>
</table>
</sf:form>
but still can't add another whole table in order to add a particular product in quantities. I was thinking about using angularjs but I'm new to that technology. I'll be very thankful for your help.
Related
This question already has answers here:
How to use css styles in struts2 tags?
(2 answers)
How to validate HTML tag using Struts 2
(3 answers)
Closed 7 years ago.
I am learning form validation in struts2. I have successfully implemented it and it's showing an error message on jsp page when text field is blank. But now I remove <s:textfield> and instead of it I am using <input type="text"> tag. Now this is not working can any one please let me know how to achieve this ?
following is my code
#Namespace("/User")
#ResultPath("/")
#Result(name = "input", location = "pages/registration.jsp")
public class UserAction extends ActionSupport implements ServletRequestAware, ModelDriven<User>
{
/**
*
*/
private static final long serialVersionUID = 1L;
User user = new User();
private HttpServletRequest servletRequest;
List<User> users = new ArrayList<User>();
public User getModel()
{
return user;
}
public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public HttpServletRequest getServletRequest()
{
return servletRequest;
}
public void setServletRequest(HttpServletRequest servletRequest)
{
this.servletRequest = servletRequest;
}
public List<User> getUsers()
{
return users;
}
public void setUsers(List<User> users)
{
this.users = users;
}
#Action(value = "register", results = {#Result(name = "input", location = "pages/registration.jsp"), #Result(name = "success", location = "pages/registration.jsp")})
// #InputConfig(methodName = "registeruser")
public String register()
{
return SUCCESS;
}
#Action(value = "registeruser", results = {#Result(location = "pages/welcome.jsp")})
public String registeruser()
{
UserDao userDao = new UserDaoImpl();
try
{
String uploadFilePath = servletRequest.getSession().getServletContext().getRealPath("/").concat("/User/images");
CommonUtils.uploadFile(user.getFile(), uploadFilePath, user.getFileFileName());
userDao.save(user, uploadFilePath);
}
catch (Exception e)
{
System.out.println(e);
}
return SUCCESS;
}
public void validate()
{
System.out.println("in");
if ("".equals(user.getFirstName()))
{
addFieldError("firstName", "First name should not be blank");
}
if ("".equals(user.getLastName()))
{
addFieldError("lastName", "Last name should not be blank");
}
}
}
Jsp Page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Registration</title>
</head>
<body>
<form action="registeruser" method="post" enctype="multipart/form-data">
<s:actionerror/>
<table>
<tr>
<td>First Name</td>
<td><input type="text" name="firstName" id="firstName"></td>
<%-- <td><s:textfield name="firstName"></s:textfield></td> --%>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="lastName" id="lastName"></td>
</tr>
<tr>
<td>Contact Number</td>
<td><input type="text" name="contactNumber" id="contactNumber"></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" name="email" id="email"></td>
</tr>
<tr>
<td>Address</td>
<td><textarea rows="5" cols="50" name="address" id="address"></textarea></td>
</tr>
<tr>
<td>Gender</td>
<td><input type="radio" name="gender" id="male" value="male">Male<br />
<input type="radio" name="gender" id="female" value="female">Female</td>
</tr>
<tr>
<td>Degree</td>
<td><input type="checkbox" name="degree" id="graduation"
value="graduation">Graduation<br />
<input type="checkbox" name="degree" id="postgraduation"
value="postgraduation">Post Graduation</td>
</tr>
<tr>
<td>Technology</td>
<td><select name="technology" id="technology">
<optgroup label="Java">
<option value="spring">Spring</option>
<option value="hibernate">Hibernate</option>
<option value="struts2">Struts2</option>
</optgroup>
<optgroup label=".Net">
<option value="asp">ASP</option>
<option value="vb.net">VB.NET</option>
</optgroup>
</select></td>
</tr>
<tr>
<td>Upload file</td>
<td><input type="file" name="file" id="file"></td>
</tr>
<tr>
<td><input type="submit" value="Save"></td>
</tr>
</table>
</form>
</body>
</html>
If you remove the <s:textfield /> and use instead a plain HTML <input type="text" />, you need to manually implement the features that otherwise would have been provided by the framework's tag.
Struts2 uses themes to generate HTML, and with the default theme (XHTML), a fieldError is generated automatically. Also remind that with a plain HTML tag, you need to manually set the value. I recommned you to keep using Struts2 tags, but to answer the question, the equivalent of
<s:textfield name="firstName" />
in plain HTML is
<input type="text" name="firstName" value="<s:properry value='firstName'>" />
<s:fielderror fieldName="firstName" />
Currently in my project, addEmployee.jsp show properly when "Add Employee" or "Edit" is clicked, but when I try to hit submit button in "Add Employee" page, page return "Http status 500 Request processing failed; nested exception is java.lang.NullPointerException", or when I try to hit submit button in "Add Employee" page for update employee info, I will get "HTTP Status 405 - Request method 'POST' not supported"
The way I want is when I add a new employee or update the existing employee info, I will still using addEmployee.jsp page. If it is add a new one, all the field will be empty, otherwise, all the field will contain the existing information for update.
Here is the code for employee.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Employee List</title>
</head>
<body>
<div align="center">
<h1 style="background-color: lightgreen; color: darkgreen">Employee
Page</h1>
<table align="center" width="80%" cellspacing="0" cellpadding="5">
<tr>
<td align="center">
<table cellspacing="0" cellpadding="6" border="0" width="100%">
<tr bgcolor="lightblue">
<td align="left"><a
href="${pageContext.request.contextPath}/employee/addEmployee"
style="background-color: lightblue;"> Add Employee </a></td>
</table>
</td>
</tr>
<tr>
<td>
<table cellspacing="0" cellpadding="6" border="1" width="100%">
<tr>
<td colspan="8"
style="background-color: lightblue; color: darkgreen; font-size: 16pt"
align="center">Employee List</td>
</tr>
<tr bgcolor="grey" style="color: white">
<th>No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Job Title</th>
<th>Department</th>
<th>Salary</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<c:forEach var="employee" items="${employeesList}"
varStatus="status">
<tr bgcolor="lightyellow">
<td><b>${status.index + 1}</b></td>
<td>${employee.firstName}</td>
<td>${employee.lastName}</td>
<td>${employee.jobTitle}</td>
<td>${employee.department}</td>
<td>${employee.salary}</td>
<td>Edit</td>
<td>Delete</td>
</tr>
</c:forEach>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
And Here is the code for addEmployee.jsp page
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Add Employee</title>
</head>
<body>
<div align="center">
<h1 style="background-color: lightgreen; color: darkgreen">Add
New Employee Page</h1>
<table width="80%" align="center">
<tr bgcolor="lightblue">
<td align="left"><a href="listEmployees"
style="background-color: lightblue;">List Employee</a></td>
</table>
</div>
<br />
<div align="center">
<table cellspacing="0" cellpadding="6" border="1" width="80%">
<tr>
<td colspan="8"
style="background-color: lightblue; color: darkgreen; font-size: 16pt"
align="center">Employee Information</td>
</tr>
<tr>
<td><form:form method="POST" action="updateEmployee">
<table width="100%">
<tr>
<td><form:label path="firstName">First Name</form:label></td>
<td align="left" width="70%"><form:input path="firstName" /></td>
</tr>
<tr>
<td><form:label path="lastName">Last Name</form:label></td>
<td align="left" width="70%"><form:input path="lastName" /></td>
</tr>
<tr>
<td><form:label path="jobTitle">Job Title</form:label></td>
<td align="left" width="70%"><form:input path="jobTitle" /></td>
</tr>
<tr>
<td><form:label path="department">Department</form:label></td>
<td align="left" width="70%"><form:input path="department" /></td>
</tr>
<tr>
<td><form:label path="salary">Salary</form:label></td>
<td align="left" width="70%"><form:input path="salary" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form></td>
</tr>
</table>
</div>
</body>
</html>
Here is the code for EmployeeController.java
package com.vincent.springmvc.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.vincent.springmvc.model.Employee;
import com.vincent.springmvc.service.EmployeeService;
#Controller
#RequestMapping("/employee")
public class EmployeeController {
//Logger file
private static Logger logger = LoggerFactory.getLogger(EmployeeController.class);
#Autowired
private EmployeeService employeeService;
#RequestMapping(method = RequestMethod.GET)
public String welcomeEmployee(ModelMap model){
model.addAttribute("name", "Hello World!");
model.addAttribute("greetings", "Welcome to Spring MVC");
return "hello";
}
#RequestMapping(value = "/listEmployees", method = RequestMethod.GET)
public String listEmployees(ModelMap model){
model.addAttribute("employeesList", this.employeeService.listEmployee());
return "employee";
}
#RequestMapping(value = "/addEmployee", method = RequestMethod.GET)
public ModelAndView addEmployee(ModelMap model){
return new ModelAndView("addEmployee", "command", new Employee());
}
#RequestMapping(value = "/updateEmployee", method = RequestMethod.POST)
public String updateEmployee(#ModelAttribute("employee") Employee employee, ModelMap model){
if(employee.getId() == 0)
this.employeeService.insertEmployee(employee);
else
this.employeeService.updateEmployee(employee);
model.addAttribute("employeesList", this.employeeService.listEmployee());
return "employee";
}
#RequestMapping(value = "/delete/{empId}", method = RequestMethod.GET)
public String deleteEmployee(#PathVariable("empId") Integer empId, ModelMap model){
this.employeeService.deleteEmployee(empId);
model.addAttribute("employeesList", this.employeeService.listEmployee());
return "employee";
}
#RequestMapping(value = "/edit/{empId}", method=RequestMethod.GET)
public ModelAndView editEmployee(#PathVariable("empId") int id, ModelMap model){
return new ModelAndView("addEmployee", "command", this.employeeService.getEmployeeById(id));
}
}
Here is the project structure
Project Structure
and the rest of the code you can find in https://github.com/zhengye1/SpringMVC
Thank you for the help
Kind of resolve for now.... but seems like not a very good idea, it is time to looking for good advice..
The way I fix is, in my controller class, I change the annotation in updateEmployee with following annotation #RequestMapping(value = {"/updateEmployee", "/edit/updateEmployee"}, method = RequestMethod.POST). This because when I tracing the log, I realize somehow the server try to mapping the page called edit/updateEmployee, originally is not exists, that is why it raising the 504 error for update.
For adding issue is causing by the form, since the form return the null id, therefore when I try to compare the null object with 0, it raise the null pointer exception. The way I fix is, change that line to if (employee.getId() == null), and also in addEmployee.jsp page, I add the this line to my form, <form:hidden path="id" />. That is resolve the issue.
My Spring JSP Form uses 2 classes that I put in a wrapper class. The employee name part works. But now I need to create a drop-down list of Clients to choose from. I'm updating someone else's code, I believe "resultBoard.getFilteredResultsClients()" will return a List of Clients. Any tips or sample code of a Spring JSP Form that uses a drop-down to select from a List?
Java wrapper class with employee and client classes inside:
public class EmployeeFormWrapper {
private NewEmployeeVM employee = new NewEmployeeVM();
private ClientVM client = new ClientVM();
public NewEmployeeVM getEmployee(){
return this.employee;
}
public ClientVM getClient(){
return this.client;
}
}
My Controller class:
#Controller
#SessionAttributes({"resultBoard", "filterBoard"})
public class NewEmployeeController {
#Autowired
NewEmpDAO newEmpDAO;
#RequestMapping(value = "NewEmpInput", method = RequestMethod.GET)
public String promptEmployee(Model model)
{
model.addAttribute("myForm", new EmployeeFormWrapper());
return "NewEmpInput";
}
#RequestMapping(value = "NewEmpInput", method = RequestMethod.POST)
public String newEmployee(#ModelAttribute("myForm") EmployeeFormWrapper myForm)
{
NewEmployeeVM employee = myForm.getEmployee();
ClientVM client = myForm.getClient();
System.out.println("Employee = " + employee.getFirstName() + " " + employee.getLastName());
System.out.println("Client = " + client.getText());
try{newEmpDAO.writeNewEmployee(employee);}
catch (Exception e){
e.printStackTrace();
}
return "ConfirmNewEmp";
}
}
My JSP:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# page session="false"%>
<%# page import="com.model.FilterBoard"%>
<!DOCTYPE html>
<!-- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -->
<html>
<head>
<link rel="stylesheet"
href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
<link rel="stylesheet"
href="<c:url value='/resources/css/mainStyle.css'/>">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<style type="text/css">
body {
color:#000000;
// background-color:#FFFFFF;
background-color:tan;
background-image:url('Background Image');
background-repeat:no-repeat;
}
a { color:#0000FF; }
a:visited { color:#800080; }
a:hover { color:#008000; }
a:active { color:#FF0000; }
</style>
<title>New Employee Proposed To Project</title>
</head>
<body class="NewEmpBody">
<p>New Employee</p>
<form:form commandName="myForm" modelAttribute="myForm">
<table>
<tr>
<td>First Name:</td>
<td><form:input path="employee.firstName" /></td>
<td>Middle Initial:</td>
<td><form:input path="employee.middleInitial" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="employee.lastName" /></td>
</tr>
<tr>
<td>Clients:</td>
<td>
<ul>
<c:forEach items="${resultBoard.getFilteredResultsClients()}"
var="filteredResultsClient">
<li><form:button name="toggleClient" class="btn btn-link"
value='${filteredResultsClient.toJSON()}'>
${filteredResultsClient.getText()}
</form:button></li>
</c:forEach>
</ul>
</td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
</body>
</html>
I got it, I changed my JSP to look like this and it gave me a nice drop-down list:
<body class="NewEmpBody">
<p>New Employee Proposed To Project Before Entered Into OpenAir</p>
<form:form commandName="myForm" modelAttribute="myForm">
<table>
<tr>
<td>First Name:</td>
<td><form:input path="employee.firstName" /></td>
<td>Middle Initial:</td>
<td><form:input path="employee.middleInitial" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="employee.lastName" /></td>
</tr>
<tr>
<td>Client :</td>
<td><form:select path="client.text">
<form:option value="NONE" label="--- Select ---" />
<form:options items="${resultBoard.getFilteredResultsClients()}" />
</form:select>
</td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
</body>
I'm trying to submit selected items from a table and moake some modifications on them but I couldn't get it work.
MyObject.java
public class MyObject{
boolean checkControl = true; //default true
private String name;
private String code;
//getters & setters
}
MyObjectForm.java
public class MyObjectForm {
private List<MyObject> myList;
public List<MyObject> getMyList() {
return myList;
}
public void setMyList(List<MyObject> myList) {
this.myList= myList;
}
}
list-myObjects.jsp
<form:form action="submitList" method="post" modelAttribute="myObjectForm">
<table>
<tbody>
<c:forEach items="${myObjectForm.myList}" var="row" varStatus="status">
<tr>
<td>
<spring:bind path="myList[${status.index}].checkControl">
<input type="checkbox" value="<c:out value="${status.value}"/>" name="isChecked" <c:if test="${row.checkControl}"> checked="checked" </c:if> />
</spring:bind>
</td>
<td>${row.name}</td>
<td>${row.code}</td>
</tr>
</c:forEach>
</tbody>
</table>
<button type="submit">Submit</button>
</form:form>
And the controller
#RequestMapping(value = "/submitList", method = RequestMethod.POST)
public String save(#ModelAttribute("myObjectForm") MyObjectForm myObjectForm, Model model) {
List<MyObject> selectedtList = myObjectForm.getMyList(); //returns null
if (selectedtList == null) {
System.out.println("no objects selected");
}
else {
//Make some computation
}
model.addAttribute("resultArray", selectedtList);
return "display-items";
}
Some users asked me to explain this in more detail by email. So I decided to submit it here, Hope this helps.
I'm using spring annotations, to do the job. here is what I did to process selected checkboxes,
I have a java entity class which includes a boolean value for the checkbox, for example a Person class
// Person.java
class Person {
private Long id;
private String name;
private boolean check;
//here goes getters and setters
}
than I have a form object in java, which contains a list of Person
//PersonForm.java
class PersonForm {
private List<Person> personList;
//getters and setters here
}
in my case, there are two jsp pages, the first one lists items, with checkboxes, and the second one lists selected items.
the first jsp file is list.jsp
//list.jsp
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="datatables" uri="http://github.com/dandelion/datatables"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
....
<body>
<form:form action="sent-list" method="post" modelAttribute="personForm">
<table id="item-list" class="table table-striped table-bordered">
<thead class="dataTableHeader">
<tr>
<th width="10%" style="text-align:center">
CheckBox
</th>
<th>id</th>
<th>name</th>
</tr>
</thead>
<tbody>
<c:forEach items="${personForm.personList}" var="listItem" varStatus="status">
<tr>
<td style="text-align:center">
<form:checkbox path="listItem[${status.index}].check"/>
</td>
<td>${listItem.id} <form:hidden path="listItem[${status.index}].id"/></td>
<td>${listItem.name} <form:hidden path="listItem[${status.index}].name"/></td>
</tr>
</c:forEach>
</tbody>
</table>
<button class="btn btn-large btn-success pull-right" type="submit">POST</button>
</form:form>
</body>
</html>
the second jsp file is as follows
//sent-list.jsp
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="datatables" uri="http://github.com/dandelion/datatables"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
.....
<body>
<form:form action="#" method="post" modelAttribute="personForm">
<table id="item-list" class="table table-striped table-bordered">
<thead class="dataTableHeader">
<tr>
<th>id</th>
<th>name</th>
</tr>
</thead>
<tbody>
<c:forEach items="${resultList}" var="personItem" varStatus="status">
<tr>
<td>${personItem.id}</td>
<td>${personItem.name}</td>
</tr>
</c:forEach>
</tbody>
</table>
</form:form>
</body>
</html>
and finally there is a controller, which makes the computation
//PersonController.java
#Controller
class PersonController {
#RequestMapping(value = "/sent-list", method = RequestMethod.POST)
public String save(#ModelAttribute("personForm") PersonForm personForm, Model model){
for(Person personItem : personForm.getPersonList){
//make some computation here
}
}
}
I hope this helps.
Sounds like a binding issue. Have you tried using Spring's <form:checkbox> tag rather than <spring:bind>? It will automatically generate the checkbox attributes as well as adding a hidden field that Spring uses to determine whether the checkbox is 'on' or 'off'.
<form:form action="submitList" method="post" modelAttribute="myObjectForm">
<table>
<tbody>
<c:forEach items="${myObjectForm.myList}" var="row" varStatus="status">
<tr>
<td>
<form:checkbox path="myList[${status.index}].checkControl"/>
</td>
<td>${row.name}</td>
<td>${row.code}</td>
</tr>
</c:forEach>
</tbody>
</table>
<button type="submit">Submit</button>
</form:form>
I am studying Spring MVC, and I have a problem with understanding how to use my classes in jsp, here is my controller:
#Controller
public class BusinessController {
#Autowired
private BusinessService businessService;
#RequestMapping("/index")
public String listContacts(Map<String, Object> map) {
map.put("business", new Business());
map.put("businessList", businessService.listBusiness());
return "business";
}
#RequestMapping("/find/{businessDate}")
public String listContactsByDate(#PathVariable("businessDate") Map<String, Object> map, String businessDate) {
map.put("businessByDate", new Business());
map.put("businessByDateList", businessService.listBusinessByDate(businessDate));
return "businessByDate";
}
#RequestMapping("/")
public String home() {
return "redirect:/index";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addBusiness(#ModelAttribute("business") Business business, BindingResult result) {
businessService.addBusiness(business);
return "redirect:/index";
}
#RequestMapping("/delete/{businessId}")
public String deleteBusiness(#PathVariable("businessId") Integer businessId) {
businessService.removeBusiness(businessId);
return "redirect:/index";
}
}
And here is my jsp:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title><spring:message code="label.title" /></title>
</head>
<body>
<h2>
<spring:message code="label.title" />
</h2>
<form:form method="post" action="add" commandName="business">
<table>
<tr>
<td><form:label path="businessDate">
<spring:message code="label.date" />
</form:label></td>
<td><form:input path="businessDate" /></td>
</tr>
<tr>
<td><form:label path="description">
<spring:message code="label.description" />
</form:label></td>
<td><form:input path="description" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit"
value="<spring:message code="label.addbusiness"/>" /></td>
</tr>
</table>
</form:form>
<form:form method="post" action="/find/{$businessDate}"
commandName="businessByDate">
<table>
<tr>
<td><form:label path="businessDate">
<spring:message code="label.date" />
</form:label></td>
<td><form:input path="businessDate" /></td>
</tr>
</table>
<c:if test="${!empty businessByDateList}">
<table class="data">
<tr>
<th><spring:message code="label.date" /></th>
<th><spring:message code="label.description" /></th>
<th> </th>
</tr>
<c:forEach items="${businessByDate}" var="business">
<tr>
<td>${businessByDate.businessDate}</td>
<td>${businessByDate.description}</td>
<td><a href="delete/${businessByDate.id}"><spring:message
code="label.delete" /></a></td>
</tr>
</c:forEach>
</table>
</c:if>
</form:form>
<h3>
<spring:message code="label.businesses" />
</h3>
<c:if test="${!empty businessList}">
<table class="data">
<tr>
<th><spring:message code="label.date" /></th>
<th><spring:message code="label.description" /></th>
<th> </th>
</tr>
<c:forEach items="${businessList}" var="business">
<tr>
<td>${business.businessDate}</td>
<td>${business.description}</td>
<td><a href="delete/${business.id}"><spring:message
code="label.delete" /></a></td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>
And, here is my service implementation class:
#Repository
public class BusinessDAOImpl implements BusinessDAO{
#Autowired
private SessionFactory sessionFactory;
public void addBusiness(Business business){
sessionFactory.getCurrentSession().save(business);
}
#SuppressWarnings("unchecked")
public List<Business> listBusinessByDate(String businessDate){
String hql = "from Business B where B.date = :business_date";
Query query = sessionFactory.getCurrentSession().createQuery(hql);
query.setParameter("business_date", businessDate);
return query.list();
}
#SuppressWarnings("unchecked")
public List<Business> listBusiness(){
return sessionFactory.getCurrentSession().createQuery("from Business").list();
}
public void removeBusiness(Integer id){
Business business = (Business) sessionFactory.getCurrentSession().load(
Business.class, id);
if (null != business) {
sessionFactory.getCurrentSession().delete(business);
}
}
}
Without the part of jsp, where I try to list businesses for date everything works fine, I can add a business and it will be immediately listed in a table below, but if I add a part with businessByDate I'll get
Neither BindingResult nor plain target object for bean name 'businessByDate' available as request attribute
How can I solve that? Thank you
enter code here
That's coming out of this form tag:
<form:form method="post" action="/find/{$businessDate}"
commandName="businessByDate">
It looks like you only do:
map.put("businessByDate", new Business());
In the method that is this form's action. You need to add that object to the map in the method that actually loads the page!