Spring Form:Select selected value - spring

I know this has been asked before but the solutions provided doesn't seem to work on my end.
I'm currently developing a web application and I'm currently working on the user profile page. What I'm doing is that when the user visits his/her profile, he/she will be able to manage his/her profile.
I have a spring form:select box which populates a List of RolesObject and a List of GroupsObject passed from the controller. The object consists of an id and name fields. What I want is when the form:select loads, it will select the present role id and group id of the user from the list.
controller
public ModelAndView viewProfile(parameters) {
ModelAndView mav = new ModelAndView();
mav.setViewName("viewProfile");
...
List<RolesObject> roles = rolesService.getRolesList();
List<GroupsObject> groups = groupsService.getGroupsList();
Map<String, List> map = new HashMap<String, List>();
map.put("roles", roles);
map.put("groups", groups);
mav.addObject("map", map);
return mav;
view
<form:select path="role_id" id="role_id" cssClass="form-control" cssStyle="width: 100%;" value="${current.getRole_id()}" required="required">
<c:forEach var="role" items="${map.roles}">
<form:option value="${role.getId()}" label="${role.getName()}" />
</c:forEach>
</form:select>
<form:select path="group_id" id="group_id" cssClass="form-control" cssStyle="width: 100%;" value="${current.getGroup_id()}" required="required">
<c:forEach var="group" items="${map.groups}">
<form:option value="${group.getId()}" label="${group.getName()}" />
</c:forEach>
</form:select>
My problem is the list populates but it does not select a default value.
Let's say my role values are
value=1, label=role_1
value=2, label=role_2
and the user's current role is role_2 which has an id of 2, when the select form loads, it does not automatically load role_2 but instead still shows role_1 as the selected value

For preselection of the option you need to set the role_id and group_id in the controller and set it as the modelattribute of the form object on page.

Related

Why do I lose information after submit a form with Spring MVC?

As I say int the title I loose information in the object that comes back from JSP to Controller.
From my Controller I pass a ModelAndView with an object of class Historic.
In the JSP page I have access to all of the values of this object, but when I submit I just get part of this information, some looses on the way on.
Controller:
#GetMapping("/tt")
public ModelAndView index(Model model) {
HistoricBO historic = new HistoricBO();
// ... I fulfill this object ...
return new ModelAndView("tt", "historic", historic);
}
In JSP I have access to all the information that I passed.
I use the values in two different ways. The first one (information that later I won't be able to recover) is:
<form:form method="POST" action="/addInput" modelAttribute="historic">
....
<form:label path="userHistoric[0].user.name" />
<form:input path="userHistoric[0].user.name" disabled="true" />
Being userHistoric a list inside HistoricBO object.
And the other way that I use the object values is daoing loop to the registers and show them. I can have these values after submit:
c:forEach items="${historic.userHistoric[0].periods[0].registers}" var="reg" varStatus="rog">
...
<td class="tab-odd">
<form:input path="userHistoric[0].periods[0].registers[${rog.index}].hours[0]" class="monin" type="number" />
</td>
The method that catch the submit is as follows:
#PostMapping("/addInput")
public String savePeriod(
#ModelAttribute("historic") HistoricBO inputs,
BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "error";
}
...
And here the object inputs only has setted the hours values, the rest of the object is empty.
Can you please why is the info loosing and how to solve it?
Thanks
Remove disabled="true" and use readonly="true" or readonly="readonly" instead like below.
<form:input path="userHistoric[0].user.name" readonly="readonly" />
Disabled values will not be submitted with the form.
See this values-of-disabled-inputs-will-not-be-submitted and demo here.

Spring MVC form not backed by a model object

I am pretty new to Spring MVC so please be easy on me.
I am having difficulties to understand how to achieve the following requirements in Spring MVC:
JSP list form, to list users from the database (service, repository thing are working properly).
Form is not backed by a model attribute object. This is a list/find form!
I need to list users matching some criteria taken from several "filter" fields like:
Region (dropdown list)
Is user archived? (yes/no dropdown list)
userList.jsp
<spring:url value="strFormAction" var="/rest/security/user/list" />
<form:form id="userListForm" method="GET" action="${strFormAction}" modelAttribute="user">
<form:select id="strRegionId" path="${strRegionId}" cssClass="form-control" onchange="updateUsersList('1');">
<spring:message var="strSelectRegionLabel" code="select.region" />
<form:option value="0" label="${strSelectRegionLabel}" />
<form:options items="${regions}" itemValue="intId" itemLabel="strNameFr" />
</form:select>
<form:select id="strArchived" path="${strArchived}" cssClass="form-control">
<spring:message var="strYesLabel" code="yes" />
<form:option value="true" label="${strYesLabel}"/>
<spring:message var="strNoLabel" code="no" />
<form:option value="false" label="${strNoLabel}"/>
</form:select>
<table>
...
<c:forEach items="${users}" var="user">
...rows generated here...
</c:forEach>
...
</table>
</form:form>
UserController.java
#RequestMapping(value = "/list", method = RequestMethod.GET)
public String processUserList( #ModelAttribute("user") User user,
#RequestParam(value = "strRegionId", required = false) String strRegionId,
#RequestParam(value = "strArchived", required = false) String strArchived,
#RequestParam(value = "strSortBy", required = false) String strSortBy,
Model model) {
int intRegionId = strRegionId != null && strRegionId.equals("0") == false ? Integer.valueOf(strRegionId) : 0;
boolean booArchived = strArchived != null && strArchived.length() > 0 ? Boolean.valueOf(strArchived) : false;
int intSortBy = strSortBy != null && strSortBy.length() > 0 ? Integer.valueOf(strSortBy) : 1;
List<Region> regions = this.locationService.lstRegions();
model.addAttribute("strRegionId", String.valueOf(intRegionId));
model.addAttribute("strArchived", String.valueOf(booArchived));
model.addAttribute("strSortBy", String.valueOf(intSortBy));
List<User> users = this.securityService.listUsersByRegionAndArchiveState(intRegionId, booArchived, intSortBy);
model.addAttribute("user", new User());
model.addAttribute("users", users);
model.addAttribute("regions", regions);
return "user/userList";
}
It seems like I can't use the Spring form taglib at all without providing a modelAttribute in the form. I have then placed a dummy modelAttribute from my controller, but now I get:
javax.servlet.ServletException: javax.servlet.jsp.JspException: org.springframework.beans.NotReadablePropertyException: Invalid property '0' of bean class [spring4base.model.security.User]: Bean property '0' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
As I said earlier, that page is not meant to be backed by any specific POJO. This is a search page, that must return a list of users (User entity bean) based on filters selected previously (region, archived state). Form must submit on itself every time a dropdown is changed (user chooses a region, submit is done on the same mapping, and then the users list reloads with only users from that specific region).
I'm coming from Struts 1 in which we needed to create ActionForm for every single page. From what I read from the documentation, forms are not necessary these days so I am really looking forward into fixing that issue.
Any help would be greatly appreciated.
I would just create helper class containing your search criteria, for instance:
public class UserSearchCriteria {
private String regionId;
private Boolean archived;
private String sortBy;
// Getters and setters
}
Then I would modify your controller method like so (some code is missing, but this should give you the idea).
#RequestMapping(value = "/list", method = RequestMethod.GET)
public String processUserList(#ModelAttribute("searchCriteria") UserSearchCriteria userSearchCriteria, Model model) {
// Retrieve users and perform filtering based on search criteria
List<User> users = this.securityService.listUsers(searchCriteria);
model.addAttribute("users", users);
model.addAttribute("regions", regions);
return "user/userList";
}
And then you would use your filtering form like this:
<spring:url value="/rest/security/user/list" var="formAction" />
<form:form id="userListForm" method="GET" action="${formAction}" modelAttribute="searchCriteria">
<form:select path="regionId" cssClass="form-control" onchange="updateUsersList('1');">
<spring:message var="strSelectRegionLabel" code="select.region" />
<form:option value="0" label="${strSelectRegionLabel}" />
<form:options items="${regions}" itemValue="intId" itemLabel="strNameFr" />
</form:select>
<form:select path="archived" cssClass="form-control">
<spring:message var="strYesLabel" code="yes" />
<form:option value="true" label="${strYesLabel}"/>
<spring:message var="strNoLabel" code="no" />
<form:option value="false" label="${strNoLabel}"/>
</form:select>
You had several errors in the form in your snippet. For example the path attribute takes String containing name (or path) of the property to bind to, you were passing it some variable. Also you had value and var switched in your <spring:url> I think.
Try it, it's not complete solution but hopefully it will give you some directions on how to implement this. If you run into any problems, leave a comment and I'll update the answer.

Path attribute in form:select - spring 2.5 JSP

I've been put on the task of learning spring (2.5), and I've got into a problem using the attribute where, when the form is loaded, I wont get any pre-selected values. So the situation is as follows:
In my system I have Companies, Customers and Users. Customer extends Company, and a Company can have a List of Users (the getMethod is public so hence Customer also have a List of Users).
So this is how the form select looks in my .JSP:
<form:select multiple="true" id="selectAccountManager" path="${customer.users}" cssClass="input select_img" >
<c:forEach items="${customerUsers}" var="user" >
<form:option value="${user.id}
<c:out value="${user.displayName}" />
</form:option
</c:forEach>
</form:select>
Right now, I get an error on the path="${customer.users}". If I use path="users" my system works, but then I wont get any of the values within the form as "pre-selected" when the page loads. I've tried with path="customer.users" but when I do this I get a referenceError in js-console.
The .JSP is mapped to an EditCustomerController where customerUsers is put into a map by
map.put("customerUsers", UserControlHelper.getAllUsers());
So I guess this is where the problem lies as I always get all users from the system?
TL;DR: How do I set selected values on a form where I load the items from one class, and want the select-filter to come from another?
(First of all, Spring 2.5 is old and I suggest you to use 3.2.x or even 4.0.x)
To pre-select option you should set appropriate field on the model and Spring will pre-select it automagically. Like that:
<form:form method="post" modelAttribute="myForm">
<form:select multiple="true" path="users">
<form:options items="${customerUsers}" itemLabel="displayName" itemValue="id" />
</form:select>
</form:form>
And in the controller:
User defaultUser = new User(1, "DEFAULT");
MyForm myForm = new myForm();
myForm.getUsers().add(defaultUser);
model.addAttribute("myForm", myForm);
So I found out what the problem was.
When I created my map I only put the users in there. What the User-object actually was mapped upon was the id of the user (something I retrieved through ${user.id} as can be seen in the originalpost. What I had to do was to create the path in a correct way as such:
Controller - java:
Map<Int,String> users = new HashMap<Int,String>();
for(User user: UserControlHelper.getAllUsers()){
users.add(user.getId(), user.getDisplayName())
}
model.put("customerUsers", users);
and my jsp:
<form:select path="users" items="${customerUsers}"></form:select>

how to bind select option value in spring mvc

I want to add value in database by select box option.and all is working good.but when i select value from the select box.selected value is added into database with new ID and skillCategory.
i never want to add it with new Id. so can someone tell me .what should i do
my jsp code :
<form:select id="skillCat" path="skillcategory.skillName">
<c:forEach var="cate" items="${catagory}">
<form:option value="${cate.skillcategoryId}">${cate.skillName}</form:option>
</c:forEach>
</form:select>
my controller code for skillCategory :
private void prepareDataForWalkin(ModelMap map) {
map.addAttribute("catagory", skillService.getSkillList());
}
You are indeed passing ${cate.skillcategoryId} to skillcategory.skillName by doing
<form:option value="${cate.skillcategoryId}">${cate.skillName}</form:option>
If you want some other value instead of id to be passed, put that into to <form:option>'s "value" attribute instead.
For example
<form:option value="${cate.skillName}">${cate.skillName}</form:option>
passes value of ${cate.skillName} to your command variable skillcategory.skillName.

Simple JSP-Spring 3 dropdown list not working

I know this should be pretty easy but I'm stuck after trying several things.
I'm only trying to display in my jsp a basic dropdown list. Spring version is 3 so I want everything to work with annotations.
JSP form with dropdown list:
<form:form method="post" commandName="countryForm">
<table>
<tr>
<td>Country :</td>
<td><form:select path="country">
<form:option value="Select" label="Select" />
</form:select>
</td>
<tr>
<td colspan="3"><input type="submit" /></td>
</tr>
</table>
</form:form>
CountryForm.java is a plain object with a single String attribute "country", with its getters and setters.
Controller who deals with the GET request is the following:
#Controller
public class CountryFormController {
#RequestMapping(value = "MainView", method = RequestMethod.GET)
public String showForm(Map model) {
CountryForm cform = new CountryForm();
model.put("countryForm", cform);
return "MainView";
}
}
However, when I redirect to the JSP "MainView" I get the typical error:
org.apache.jasper.JasperException: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'countryForm' available as request attribute
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:502)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:424)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
What am I doing wrong?
The select tag in the Spring TagLib needs to be provided with a collection, map or array of options. I'm not sure what you would like these to be so I will make some assumptions.
You need to include a collection, map or array of objects in your controller. Ideally you would have a Country class and create new instances for a set of countries. For the example to work with your code, I just created a static list of countries. Add the list to your model and then modify the select tag, setting the options to ${countries}. Assuming country is a field of type String on CountryForm with appropriate get/set methods, the country should data-bind to field when the form is submitted.
Controller
#Controller
public class CountryFormController {
#RequestMapping(value = "MainView", method = RequestMethod.GET)
public String showForm(Map model) {
List<CountryForm> cfs = new ArrayList<CountryForm>();
cfs.add("United States");
cfs.add("Canada");
model.put("countries", cfs);
model.put("countryForm", cform);
return "MainView";
}
}
JSP
<form:select path="countryForm.country" options="${countries}"/>
I have sample code at GitHub, try it an let me know. Look at landing.jsp and UserController
<form:select path="users[${status.index}].type" >
<form:option value="NONE" label="--- Select ---"/>
<form:options itemValue="name" itemLabel="description" />
</form:select>
HTH

Resources