java - Input in array Thymeleaf -
i need choose values 1 array , assign other array. using spring thymeleaf. no idea how retrieve these choosed values. classes:
@entity public class collaborator { @id @generatedvalue(strategy = generationtype.identity) private long id; @notnull @size (min=3, max=32) private string name; @notnull @manytoone (cascade = cascadetype.all) private role role; public collaborator() {}... @entity public class role { @id @generatedvalue(strategy = generationtype.identity) private long id; @notnull @size(min = 3, max = 99) private string name; public role() {}....
my controllers:
@requestmapping("/project_collaborators/{projectid}") public string projectcollaborators(@pathvariable long projectid, model model) { project project = mprojectservice.findbyid(projectid); list<collaborator> allcollaborators = mcollaboratorservice.findall(); list<collaborator> assignments = new arraylist<>(); if (project.getrolesneeded()!=null) { (int i=0;i<project.getrolesneeded().size();i++) { assignments.add(new collaborator("unassigned", project.getrolesneeded().get(i))); assignments.get(i).setid((long) 0); } } model.addattribute("assignments", assignments); model.addattribute("allcollaborators", allcollaborators); model.addattribute("project", project); return "project_collaborators"; } @requestmapping(value = "/project_collaborators/{projectid}", method = requestmethod.post) public string projectcollaboratorspost(@modelattribute project project, @pathvariable long projectid, model model) { project p = mprojectservice.findbyid(projectid); //mprojectservice.save(project); return "redirect:/project_detail/{projectid}"; }
and template:
<form th:action="@{'/project_collaborators/' + ${project.id}}" method="post" th:object="${project}"> <label th:text="'edit collaborators: ' + ${project.name}">edit collaborators: website project</label> <ul class="checkbox-list"> <li th:each="a : ${assignments}"> <span th:text="${a.role.name}" class="primary">developer</span> <div class="custom-select"> <span class="dropdown-arrow"></span> <select th:field="${a.id}"> <option th:each="collaborator : ${allcollaborators}" th:value="${collaborator.id}" th:text="${collaborator.name}">michael pemulis</option> </select> </div> </li> </ul> <div class="actions"> <input type="submit" value="save" class="button"/> <a href="#" class="button button-secondary">cancel</a> </div> </form>
as can see want let user choose each role (roleneeded) collaborator (allcollaborators) , keep assigns in list (assignments).
and error message:
ava.lang.illegalstateexception: neither bindingresult nor plain target object bean name 'a' available request attribute
so question is: how solve it, assign values 1 array in template , retrieve values in controller.
the cause of exception
the illegalstateexception getting because th:field="${a.id}" in select element must related form th:object="${project}" element; th:field attribute must refer actual field in project instance (also need write th:field="*{fieldname}"). should fix exception getting, not solve entire problem second part of related how make values controller, explain next.
sending values controller
to values controller need make few changes. don't know code of project class, change few things able figure out how adapt simple example particular case.
first, understand want make relation following in form:
- role1 => collaboratora
- role2 => collaboratorb
your controller needs receive list , in order receive information need 2 classes:
the class storing individual element data, mapping role id collaborator id:
public class rolecollaborator { private long roleid; private long collaboratorid; public long getroleid() { return roleid; } public void setroleid(long roleid) { this.roleid = roleid; } public long getcollaboratorid() { return collaboratorid; } public void setcollaboratorid(long collaboratorid) { this.collaboratorid = collaboratorid; } }
a wrapper class store list of individual mappings:
public class rolescollaborators { private list<rolecollaborator> rolescollaborators; public list<rolecollaborator> getrolescollaborators() { return rolescollaborators; } public void setrolescollaborators(list<rolecollaborator> rolescollaborators) { this.rolescollaborators = rolescollaborators; } }
the next thing change controllers have 2 methods, 1 handles requests , 1 handles post requests , so, receives form data.
in one:
public string projectcollaborators(@pathvariable long projectid, model model) { (... code ...) model.addattribute("project", project); // add next line add "rolescollaborators" instance model.addattribute("rolescollaborators", new rolescollaborators()); return "project_collaborators"; }
as can see, added line used thymeleaf template. right wrapper of empty list of roles , collaborators, can add values if need edit existing mappings instead of adding new ones.
in post one:
// changed @modelattribute project rolescollaborators public string projectcollaboratorspost(@modelattribute rolescollaborators rolescollaborators, @pathvariable long projectid, model model) { (... code ...) }
at point, controller prepared receive information sent form, need modify.
<form th:action="@{'/project_collaborators/' + ${project.id}}" method="post" th:object="${rolescollaborators}"> <label th:text="'edit collaborators: ' + ${project.name}">edit collaborators: website project</label> <ul class="checkbox-list"> <li th:each="a, stat : ${assignments}"> <span th:text="${a.role.name}" class="primary">developer</span> <div class="custom-select"> <input type="hidden" th:id="rolescollaborators[__${stat.index}__].roleid" th:name="rolescollaborators[__${stat.index}__].roleid" th:value="${a.role.id}" /> <span class="dropdown-arrow"></span> <select th:field="*{rolescollaborators[__${stat.index}__].collaboratorid}"> <option th:each="collaborator : ${allcollaborators}" th:value="${collaborator.id}" th:text="${collaborator.name}">michael pemulis</option> </select> </div> </li> </ul> <div class="actions"> <input type="submit" value="save" class="button"/> <a href="#" class="button button-secondary">cancel</a> </div> </form>
here there few changes:
- as pointed out in the cause of exception need change th:object="${project}" th:object="${rolescollaborators}", rolescollaborator instance name receive values controller method , sending values post controller method.
- i added hidden input; input store role id send in association collaborator id user picks interface using select element. take @ syntax used.
- i changed th:field value of select element refer field in rollescollaborators object use in th:object="${rolescollaborators}" form attribute. set value of collaborator in rolecollaborator element of rolescollaborators wrapped list.
with these changes code work. of course, can improve other modifications, tried not introduce more modifications focus on problem.
Comments
Post a Comment