Search code examples
javaspringjspspring-mvcspring-form

Spring form select a enum from a object


I'm making a form to edit users, each user has multiples roles (based on Spring Security). The problem is that the select option is not preselected with the correspondents roles of the users.

User

public class User implements UserDetails {
   ...
   private Set<UserRole> userRoles = new HashSet<>(0);
   ...
}

Roles

public class UserRole implements GrantedAuthority {
   ...
   private Role role; //enum {ROLE_ADMIN, ROLE_USER,...}
   ...
}

Form

<form:fomr commandName="user">
   <form:input path="username" />
   ...
   <form:select multiple="true" path="userRoles" itemValue="role">
      <form:options items="${roles}"/>
   </form:select>
   ...
</form:form>

I'm sure that the problem come from "userRoles", it is a Set of a different type that "roles". There is an another way to make the form?

PS:items=${roles} == Roles.values()

edited:

User user = getUserById(id);
model.addAttribute("newUser", user);

@Transactional
public User getUserById(int id) {
    Session session = sessionFactory.getCurrentSession();
    User user = (User) session.get(User.class, id);
    if (user != null) {
        user.getUserRoles().size();
    }
    return user;
}

Solution

  • I have this "solution", but I was looking for some thing that spring do automatically

            ...
            <form:select multiple="true" path="userRoles" itemValue="role">
                <c:forEach items="${roles}" var="role">
                    <c:set var="selected" value="false" />
                    <c:forEach items="${newUser.userRoles}" var="userRole">
                        <c:if test="${fn:containsIgnoreCase(userRole, role)}">
                            <form:option value="${role}" selected="true"/>
                            <c:set var="selected" value="true" />
                        </c:if>
                    </c:forEach>
                    <c:if test="${selected eq false}">
                        <form:option value="${role}"/>
                    </c:if>
                </c:forEach>
            </form:select>
            ...