Populate Dropdown list from Using Spring,Hibernate - spring

Experts,
Class EmployeeEntity
{
id
Fname
Salary
Phone
}
Controller.java
#RequestMapping(value = "/list")
public String listEmployee(ModelAndView map)
{
map.addObject("employee", employeeManager.getEmp());
return "emp";
}
EmployeeDAO.java
#Override
public List<EmployeeEntity> getEmp() {
return this.sessionFactory.getCurrentSession().createQuery("select e.id, e.firstname from EmployeeEntity e").list();
}
emp.jsp
<form:form method="POST">
<form:select path="Fname">
<form:options items="${employee}" />
</form:select>
</form:form>
This are my files. I am not geting values in drropdown.Please help me How to find out problem. I need to populate list with Fname ,and Id as value in list
Error
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)

First thing you have to use map instead of list. You can have a refernce to below code:
#RequestMapping(value = "/list")
public Map listEmployee(ModelAndView map) throws Exception {
Map referenceData = new HashMap();
Map<String,String> country = new LinkedHashMap<String,String>();
country.put("US", "United Stated");
country.put("CHINA", "China");
country.put("SG", "Singapore");
country.put("MY", "Malaysia");
referenceData.put("countryList", country);
}
And iterate over Map on JSP to construct dropdown as below:
<form:select path="country">
<form:option value="NONE" label="--- Select ---"/>
<form:options items="${countryList}" />
</form:select>

Related

How to post a list to controller in Thymeleaf

I am new to Thymeleaf,Maybe this is a simple question.Please help me.Thanks.
Controller code:
#Controller
public class TestController {
#GetMapping(value = "/")
public String testget(Map<String, Object> model) {
TestBean bean = new TestBean();
List<Person> list = new ArrayList<>();
for (int index = 1; index < 5; index++) {
Person p = new Person();
p.setId(index);
p.setName("name" + index);
list.add(p);
}
model.put("allList", "nothing");
bean.setList(list);
model.put("testbean", bean);
return "NewFile";
}
#PostMapping(value = "/")
public String testpost(Map<String, Object> model//
, #ModelAttribute(name = "testbean") TestBean bean) {
List<Person> list = bean.getList();
model.put("bean", bean);
model.put("allList", list.toString());
return "NewFile";
}}
simple mapper and a Person bean:
#Data
public class TestBean {
private List<Person> list;
}
#Data
public class Person {
private int id;
private String name;
}
HTML code :
<form action="#" th:action="#{/}" th:object="${testbean}" method="post">
<p th:text="'ALL : ' + ${allList}"></p>
<table>
<tr th:each="person : ${testbean.list}">
<td>Id:<input type="text" th:value="${person.id}"
/></td>
<td>name: <input type="text" th:value="${person.name}" /></td>
</tr>
</table>
<input type="submit" value="submit" />
</form>
I want put list to page and change properties to refresh.
but i don't know how to add th:field tag, I try to add
**th:field="*{testbean.list[__${index}__].id}"**
but it failed with :
Invalid property 'testbean' of bean class [com.TestBean]
UPDATE1
And i tried
th:field="*{list[__${index}__].id}"
I got a error Where I added th:field
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (NewFile:14)] with root cause
java.lang.NumberFormatException: For input string: "null"
My questions is what i can do something that i can get a List in controller.
Invalid property 'testbean' of bean class [com.TestBean]
Use th:field="*{list[__${index}__].id} pattern without testbean definition. If you use * notation then it will reference to parent object.
java.lang.NumberFormatException: For input string: "null"
Add any variable like "rowStat" to the loop for keeping status index:
th:each="person,rowStat : ${testbean.list}"
and access it like th:field="*{list[__${rowStat.index}__].id}. So index will not be null and no problem converting the string to int.
This is how I do it on page that lists some search results - table with checkboxes. Code itself is stripped only to relevant lines. places.content is a collection of Place objects.
<form th:action="#{selected-places}" method="POST" >
<tr th:each="place,i : ${places.content}">
<td><input name="places" th:value="${place.id}" type="checkbox"></td>
</tr>
</form>
And the controller side
#PostMapping(value = "/selected-places", params = "action=delete")
public String deletePlaces(#RequestParam Place[] places, RedirectAttributesModelMap model) {
....
}
As you can see, despite fact that form is sending only list of IDs, spring will autohydrate model entities. You can always Place[] places to collection of integers and it still will work.

How to proceed with complex object in POST request

Hello SO I had 2 entities
Main entity
#Entity
#Table(name = "Events")
public class Event {
//Some fields ...
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "event_eventtypes" ,
joinColumns = #JoinColumn(name = "event_id"),
inverseJoinColumns = #JoinColumn(name = "event_type_id"))
private Set<EventType> eventTypes;
//Getters and setters...
Now I have a form that is created using spring form-taglib
<form:form modelAttribute="event" method="post" action="/event/registerEvent" commandName="event">
<form:label path="name">Event display name</form:label>
<form:input path="name" type="text" cssClass="form-control" placeholder="Display name"/>
<form:label path="description" >Description</form:label>
<form:textarea path="description" cssClass="form-control"/>
<form:label path="priv" cssClass="">Make private? <span style="font-family:'Open Sans', sans-serif; font-size:11px; color: dodgerblue;">(It will be seen by your friends and people who you send invitation.)</span></form:label>
<form:checkbox path="priv" cssClass="form-check-input"/>
<form:label path="age">Age limit</form:label>
<form:select path="age">
<form:options items="${age}"/>
</form:select>
<form:hidden path="lng" id="formLang" />
<form:hidden path="lat" id="formLat"/>
<%--Question appear here--%>
<form:select path="eventTypes" items="${eventTypes}" multiple="true"/>
<input type="submit" value="Submit">
Controller
#Controller
public class EventController {
private static final Logger logger = LoggerFactory.getLogger(EventController.class);
#Autowired
private EventService eventService;
#Autowired
private UserService userService;
#Autowired
private EventTypeService eventTypeService;
#RequestMapping(path = "/event/create", method = RequestMethod.GET)
public String init(ModelMap modelMap) {
List<String> tags = eventTypeService.listEventTypes().stream().map(EventType::getName).collect(Collectors.toList());
ArrayList<Integer> ageArr = new ArrayList();
ageArr.add(0);
ageArr.add(6);
ageArr.add(12);
ageArr.add(16);
ageArr.add(18);
modelMap.addAttribute("event", new Event());
modelMap.addAttribute("age", ageArr);
modelMap.addAttribute("eventTypes", tags);
return "/event/create";
}
#RequestMapping(path = "/event/registerEvent", method = RequestMethod.POST)
public String createEvent(#ModelAttribute("event") Event event, #ModelAttribute("eventTypes1") List<String> eventTypes){
event.setDate(new Date());
event.setUser(userService.getUserByUsername(
AuthenticationService.getLoggedInUser())
);
eventService.addEvent(event);
return "redirect:/";
}
When complete form with values, click submit, get error
400 The request sent by the client was syntactically incorrect.
It's because eventTypes property is of String type. How can I send that list as another parameter in controller or what should I do it?
Maybe you need a DTO to include event and eventType list both.
When I have done this I send a DTO with a list of IDs/Strings for event types to the form and then create a new event from the DTO.
For the select statements loop round each option returned in the DTO and use a service findById to retrieve each eventType and then add this to the event model.
for (String tag : eventDTO.getEventTags()) {
EventType eventTag = eventTypeService.findById(Long.valueOf(tag));
if (eventTag != null) {
event.getEventTypes().add(eventTag );
}
}
Found soulution.
Just implement jsp-based form as :
<form:form modelAttribute="event" method="post" action="/event/registerEvent" commandName="event">
...
<%--There I'm not using more jsp tabs.--%>
<select multiple name="et" id="tags">
<c:forEach items="${eventTypes}" var="e">
<option value=${e}>${e}</option>
</c:forEach>
</select>
<input type="submit" value="Submit">
</form:form>
In Controller I get parameters as request.getParameterValues("et")) - that return String[] from HttpServletRequest

Spring MVC bind multi select with view model on post method

How to bind a multi select to a view model on post method?
This is the view model:
public class AssignEvaluationViewModel {
private String evaluationType;
private String milestone;
private List<AssigneesViewModel> optionsList;
//getters and setters
}
public class AssigneesViewModel {
private int evaluatorId;
private int evaluatedId;
private String evaluatorName;
private String evalueatedName;
}
Controller
#RequestMapping(value="addAssignment", method = RequestMethod.GET)
public String addAssignment(Model model){
// load the list of evaluation type
List<DropDownListItem> items = new ArrayList<DropDownListItem>();
items.add(new DropDownListItem("1", "Peer evaluation"));
items.add(new DropDownListItem("2", "Team member evaluation"));
items.add(new DropDownListItem("3", "Team evaluation"));
model.addAttribute("items", items);
// load the list of milestones
List<DropDownListItem> milestones = new ArrayList<DropDownListItem>();
List<MilestoneDTO> dtos = milestoneService.getAll();
for (MilestoneDTO m : dtos) {
milestones.add(new DropDownListItem(String.valueOf(m.getId()), m
.getMilestoneName()));
}
model.addAttribute("milestones", milestones);
model.addAttribute("addAssignment", new AssignEvaluationViewModel());
return "addAssignment";
}
#RequestMapping(value="addAssignment", method = RequestMethod.POST)
public String addAssignmentPOST(#ModelAttribute("addAssignment") AssignEvaluationViewModel viewModel){
//save the assignment
return "redirect:assignEvaluationForms";
}
The problem is in the jsp.
<form:form commandName="" modelAttribute="addAssignment" id="addAssignment">
//..................
<div class="selectAssignees">
<p>Assignees:</p>
<form:select multiple="multiple" class="assigneesOptions" path="optionsList" id="assignees">
</form:select>
</div>
//..............
</form:form>
How do i bind the options added by the user in the select with optionsList from the AssignEvaluationViewModel?
If you want to show options in Spring you can use form:options
<form:form commandName="" modelAttribute="addAssignment" id="addAssignment">
<div class="selectAssignees">
<p>Assignees:</p>
<form:select multiple="multiple" class="assigneesOptions" path="optionsList" id="assignees">
<form:option value="NONE" label="--- Select ---"/>
<form:options items="${optionsList}" />
</form:select>
</div>
</form:form>

Spring framework bind form array property

// my form
public class myForm {
private double[] myField;
public double[] getMyField(){
return myField;
}
public void setMyField(double[] myField){
this.myField = myField;
}
}
// my jsp
...
...
<c:set var="i" value="0"/>
<c:forEach items="${myList}" var="data">
<form:input path="myField[${$i}]"/>
<c:set var="i">${i + 1}</c:set>
</c:forEach>
...
...
After spring render jsp generate this code ;
<input type="text" value="0.0" name="myField0" id="myField0"/>
<input type="text" value="0.0" name="myField1" id="myField1"/>
<input type="text" value="0.0" name="myField2" id="myField2"/>
...
...
Spring cant bind my form on controller , because form names not valid (myField0, myField1..) . If i change names with firebug (as myField[0], myField[1] etc.) initBinder works and i catch my form data on controller. How can i solve this?
Thanks.
Use a Collection in your form instead of an array :
public class myForm {
private Collection<Double> myField;
public Collection<Double> getMyField(){
return myField;
}
public void setMyField(Collection<Double> myField){
this.myField = myField;
}
}

How do I set the selected value in a Spring MVC form:select from the controller?

In my controller:
#Controller
public class UserController {
#RequestMapping(value="/admin/user/id/{id}/update", method=RequestMethod.GET)
public ModelAndView updateUserHandler(#ModelAttribute("userForm") UserForm userForm, #PathVariable String id) {
Map<String, Object> model = new HashMap<String, Object>();
userForm.setCompanyName("The Selected Company");
model.put("userForm", userForm);
List<String> companyNames = new ArrayList<String>();
companyNames.add("First Company Name");
companyNames.add("The Selected Company");
companyNames.add("Last Company Name");
model.put("companyNames", companyNames);
Map<String, Map<String, Object>> modelForView = new HashMap<String, Map<String, Object>>();
modelForView.put("vars", model);
return new ModelAndView("/admin/user/update", modelForView);
}
}
The select form field in my view:
<form:form method="post" action="/admin/user/update.html" modelAttribute="userForm">
<form:select path="companyName" id="companyName" items="${vars.companyNames}" itemValue="id" itemLabel="companyName" />
</form:form>
It was my understanding that the form backing bean would be mapped based upon the modelAttribute attribute in the form. I'm obviously missing something here.
It appears the issue was not related to my setup. The problem was that the itemValue was set to the company id property, while the comparison was being done to the company name property on my form backing bean. So the two were not equal, and therefore, no item was set to selected.
The above code works just fine, and setting the value in the userForm for a particular property will set that value as selected in select form fields so long as the value of one of the items in the items collection is equal to the form value. I changed my form field to look like this, which pulls the companyName instead of the id.
<form:form method="post" action="/admin/user/update.html" modelAttribute="userForm">
<form:select path="companyName" id="companyName" items="${vars.companyNames}" itemValue="companyName" itemLabel="companyName" />
</form:form>
The easiest solution is to override the toString() method in the model class.
In this case just change the class UserForm by overriding toString() like below:
#Override
public String toString() {
return this.getCompanyName();
}
Spring then will automatically select the correct value in form:option
I was struggling some time on the same issue.
This is the select field I had
<form:select path="origin" items="${origins}" itemValue="idOrigin" itemLabel="name" />
Since I had a PropertyEditor in place for my entity I couldn't write something like
<form:select path="origin.idOrigin" items="${origins}" itemValue="idOrigin" itemLabel="name" />
that worked fine, but was not parsed by the PropertyEditor.
So, thinking about the Spring's need to determine equality between entities, I came out implementing equals and hashcode in my Origin entity using only the idOrigin property, and it worked!
You can also try like this
<form:select id="selectCategoryId" path="categoryId"
class="selectList adminInput admin-align-input" multiple="">
<option value="0">-- Select --</option>
<c:forEach items="${categories}" var="category">
<option <c:if test="${category.key eq workflowDTO.categoryId}">selected="selected"</c:if> value="${category.key}">${category.value} </option>
</c:forEach>
</form:select>
it is not so complicated. You need 2 beans: a form backing bean and a select model in your domain model.
Here is my model, a list of strings, for :
/* in controller: my select model is a list of strings. However, it can be more complicated, then you had to use PropertyEditors for String <-> Bean conversions */
List<String> mySelectValues = new ArrayList<String>();
mySelectValues.add("M");
mySelectValues.add("F");
modelMap.addAttribute("mySelectValues", mySelectValues);
Here is your form, basically :
<form:form command="user">
<form:select path="gender">
<form:options items="${mySelectValues}"></form:options>
</form:select>
</form:form>
und here is my backing object:
public class User {
private String gender;
/* accessors */
}
Spring framework selects automaticaly using value of "gender" field.

Resources