I'm working on trying to add two objects on a single form and running into issues with the field being concatenated when they have the same name. See below
Project Entity
@Entity
@SequenceGenerator(name = "project_project_id_seq", allocationSize = 1, initialValue = 1)
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "project_project_id_seq")
private Long projectId;
private String projectName;
private String address;
Client Entity
@Entity
@SequenceGenerator(name = "company_seq", sequenceName = "client_company_id_seq", allocationSize = 1, initialValue = 1)
public class Client extends Company {
public Client(String companyName, String address, String city, String state, String zipcode) {
super(companyName, address, city, state, zipcode);
}
public Client() {
}
}
Controller
@Controller
@RequestMapping("/projects")
public class ProjectController {
@Autowired
private ProjectService projectService;
@Autowired
private ClientService clientService;
@GetMapping("/addNew")
public String addNewProject(Model model) {
model.addAttribute("project", new Project());
model.addAttribute("client", new Client());
return "addNewProject";
}
@PostMapping("/addNew")
public String checkProjectInfo(@ModelAttribute Project project, @ModelAttribute Client client, Model model) {
model.addAttribute("project", project);
model.addAttribute("client", client);
clientService.addNew(client);
project.setClient(client);
projectService.addNew(project);
return "projectAdded";
}
}
Relevant html portions (I didn't include the whole thing but can if needed)
(Project portion)
<form action="#" th:action="@{/projects/addNew}" method="post">
<div >
<div >
<div >
<h5 >Project details</h5>
</div>
<div >
<div >
<div >
<input type="text" th:value="${project.projectName}" name="projectName" id="projectNameForm" placeholder="Project Name" />
</div>
</div>
<!-- Text input -->
<div >
<div >
<input type="text" th:name="address" th:value="${project.address}" id="projectAddressForm" placeholder="Address" />
</div>
(Client portion)
<div >
<div >
<input type="text" th:field="${client.companyName}" id="clientNameForm" placeholder="Client Name" />
</div>
</div>
<!--Client address -->
<div >
<div >
<input type="text" th:name="address" th:value="${client.address}" id="clientAddressForm" placeholder="Address" />
</div>
</div>
I've tried using th:object for each of them within the same div, tried using th:field instead of th:value. The problem is this keeps concatenating the address because they have the same name (the projectName/clientName fields work just fine as they're unique). I added the project. and client. after looking at another question here but that didn't change anything. I want to avoid making them all unique fields because I want to add other Company classes as well(Client extends Company). This also applies for other fields I want to use (city/state etc).
Is there something I can do to make sure the two different addresses are not concatenated? Thanks in advance.
CodePudding user response:
If you want to submit multiple objects, you should create a single page form object that contains all your objects and submit than, instead of trying to submit each object individually.
class ProjectForm {
private Project project;
private Client client;
// getters and setters
}
Then your names will be unique (should be something like project.address
etc...).
Alternatively, if your projects actually contains a client as in your code project.setClient(client);
, you can just submit the project:
@GetMapping("/addNew")
public String addNewProject(Model model) {
Project project;
model.addAttribute("project", project = new Project());
project.setClient(new Client());
return "addNewProject";
}
<input type="text" th:value="${project.projectName}" name="projectName" id="projectNameForm" placeholder="Project Name" />
<input type="text" th:value="${project.client.address}" th:name="client.address" id="clientAddressForm" placeholder="Address" />
Finally, just as a note, Thymeleaf has utility properties for this... the form should actually look like this:
<form action="#" th:action="@{/projects/addNew}" th:object="${project}" method="post">
<input type="text" th:field="*{projectName}" id="projectNameForm" placeholder="Project Name" />
<input type="text" th:field="*{client.address}" id="clientAddressForm" placeholder="Address" />