I write my first form using Spring MVC pattern and Hibernate.
I have a problem when I want to update existing row in table.
After click "Edit" Buttno in a table, correct row is found in db. Then I can update "name" field and click SAVE button. Than in database i created new row with new ID.
I have wrote two System.out to check current values of object.
My Controller class:
#Controller
//#RequestMapping("/")
public class InterventionController {
#Autowired
private InterventionService interventionService;
#GetMapping("/")
public String viewHomePage(Model model){
List<InterventionModel> interventionList = interventionService.listAll();
model.addAttribute("interventionList", interventionList);
return "index";
}
#GetMapping("/new")
public String addInterventionForm(Model model){
InterventionModel interventionModel = new InterventionModel();
model.addAttribute("interventionModel", interventionModel);
System.out.println(model.toString());
return "new_intervention";
}
#RequestMapping(value="/save", method = RequestMethod.POST)
public String saveIntervention(#ModelAttribute("interventionModel")InterventionModel interventionModel){
System.out.println("Object retreived from editing view "+interventionModel); // <- just to check in console object attributes
interventionService.save(interventionModel);
return "redirect:/";
}
#RequestMapping("/edit/{id}")
public ModelAndView showEditInterventionForm(#PathVariable(name="id") Long id){
ModelAndView mav = new ModelAndView("edit_intervention");
InterventionModel interventionModel = interventionService.get(id).get(); // <-- Optional received from service layer
mav.addObject("interventionModel", interventionModel);
System.out.println("Object retrieved from database : "+interventionModel); // <- just to check in console object attributes
return mav;
}
#GetMapping("/delete/{id}")
public String deleteIntervention(#PathVariable(name="id") Long id){
interventionService.delete(id);
return "redirect:/";
}
My InterventionModel class doesn't contain any annotation. I don't know if that is a mistake, but that object is DTO between controller and service layer. In the service layer, it is mapped to the entity which is annotated #Entity.
public class InterventionModel {
private Long id;
private String name;
public InterventionModel() {
}
public InterventionModel(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "InterventionModel{" +
"id=" + id +
", name='" + name + '\'' +
'}';
} }
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Interventions</title>
</head>
<body>
<div align="center">
<h1>Interventions</h1>
Create new Intervention
<br><br>
<table border="2" cellpadding="10">
<thead>
<tr>
<th>Intervention Id</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr th:each="intervention :${interventionList}">
<td th:text="${intervention.id}">Intervention Id</td>
<td th:text="${intervention.name}">Name</td>
<td>
<a th:href="#{'/edit/' + ${intervention.id}}">Edit</a>
<a th:href="#{'/delete/' + ${intervention.id}}">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
and edit_intervention.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Edit Intervention</title>
</head>
<body>
<div align="center">
<h1>Edit Intervention</h1>
<br/>
<form action="#" th:action="#{/save}" th:object="${interventionModel}" method="post">
<table border="0" cellpadding="10">
<tr>
<td>Intervention ID</td>
<!-- <td><input type="text" th:field="*{id}" readonly="readonly"/></td>-->
<td><input type="text" th:field="*{id}" readonly="readonly"/></td>
</tr>
<tr>
<td>Intervention name</td>
<td><input type="text" th:field="*{name}"/></td>
</tr>
<tr>
<td colspan="2"><button type="submit">Save</button> </td>
</tr>
</table>
</form>
</div>
</body>
</html>
What is curious for me. Object when is retrieved from DB has proper attributes (id, name) than Model is created and sent to edit_intervention.html form. After changing name, it goes back to save method but there ID number is "null", instead of name which contains changed new value.
For me (as a beginner) it looks like no all attributes are transferred from the view to the save method in controller. When we have ID set to "null" it's a sign for hibernate to create new row.
I guess there is a minor failure which I cannot find.
Logs from terminal when I call update form:
and view how table after modification looks like:
Thank you in advance for help.
As you see your id field is null. Because probably the Long value wasn't set.
In entity class you should mark id property as #Id, also you can always add the #GeneratedValue annotation above.
Related
I am new to springboot and thymeleaf and I'm trying to understand the form handling methods that interact with the code. Below you will find my html documents linked to a Users class. I am trying to change them to link to a customer class amongst other things, but anytime I change the th:object=${users} to match the new entity 'customerentity' it gives me the error below. What more do I have to do to get the bean(?) to register my new attribute? Any help or links to other answers is greatly appreciated.
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerentity' available as request attribute
Here is my entity class
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.springframework.lang.NonNull;
#Entity
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NonNull
private String name;
#NonNull
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// standard constructors / setters / getters / toString
}
The controller class
#Controller
public class UserController {
//set up a UserRepositoty variable
#Autowired
private UserRepository userRepository;
//create an UserRepository instance - instantiation (new) is done by Spring
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
//Mapping for the /index URL when initiated through Tomcat
#RequestMapping({"/index"})
public String showUserList(Model model) {
model.addAttribute("customers", userRepository.findAll());
return "index";
}
//Mapping for the /signup URL - calls the add-user HTML, to add a user
#RequestMapping({"/signup"})
public String showSignUpForm(Users user) {
return "add-user";
}
//Mapping for the /signup URL - to add a user
#RequestMapping({"/adduser"})
public String addUser(#Validated Users users, BindingResult result, Model model) {
if (result.hasErrors()) {
return "add-user";
}
userRepository.save(users);
return "redirect:/index";
}
//Mapping for the /edit/user URL to edit a user
#GetMapping("/edit/{id}")
public String showUpdateForm(#PathVariable("id") long id, Model model) {
Users user = userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
model.addAttribute("customer", user);
return "update-user";
}
//Mapping for the /update/id URL to update a user
#PostMapping("/update/{id}")
public String updateUser(#PathVariable("id") long id, #Validated Users user,
BindingResult result, Model model) {
if (result.hasErrors()) {
user.setId(id);
return "update-user";
}
userRepository.save(user);
return "redirect:/index";
}
//Mapping for the /delete/id URL to delete a user
#GetMapping("/delete/{id}")
public String deleteUser(#PathVariable("id") long id, Model model) {
Users user = userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
userRepository.delete(user);
return "redirect:/index";
}
}
The html documents
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Add User</title>
</head>
<body>
<form action="#" th:action="#{/adduser}" th:object="${users}" method="post">
<label for="name">Name</label>
<input type="text" th:field="*{name}" id="name" placeholder="Name">
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span>
<label for="email">Email</label>
<input type="text" th:field="*{email}" id="email" placeholder="Email">
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></span>
<input type="submit" value="Add User">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Add User</title>
</head>
<body>
<div th:switch="${users}">
<h2 th:case="null">No users yet!</h2>
<div th:case="*">
<h2>Users</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.name}"></td>
<td th:text="${user.email}"></td>
<td><a th:href="#{/edit/{id}(id=${user.id})}">Edit</a></td>
<td><a th:href="#{/delete/{id}(id=${user.id})}">Delete</a></td>
</tr>
</tbody>
</table>
</div>
<p>Add a new user</p>
</div>
</body>
</html>
I am trying send the data through controller to html page but unable data transmission is getting failed. Control is redirecting to the desired page along with labels but form data is not reflecting in the view page.
***HomeController***
package com.example.demo.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.example.demo.domain.User;
#Controller
public class HomeController {
User user = new User();
#RequestMapping("/")
public String home(Model model) {
model.addAttribute("formData", user);
return "index";
}
#RequestMapping(value="/create", method=RequestMethod.POST)
public String processFormData(User user, RedirectAttributes attr) {
attr.addFlashAttribute("user",user);
return "redirect:display";
}
#RequestMapping(value="/display", method=RequestMethod.GET)
public String displayFormData(User user) {
return "result";
}
}
index.html
<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> Home Page </title>
</head>
<body>
<p> Enter Data Below </p>
<form action="/create" method="post" th:object="${formData}">
<p>Full Name:<input type="text" th:feild="${formData.fullName}"/></p>
<p>Age:<input type="text" th:feild="${formData.age}"/></p>
<p>Employed?<input type="checkbox" th:feild="${formData.employed}" th:value="true"/></p>
<p>Gender:</p>
<p>Male<input type="radio" th:feild="${formData.gender}" th:value="Male"/>
Female<input type="radio" th:feild="${formData.gender}" th:value="Female"/></p>
<p><input type="submit" value="Submit"/> <input type="reset" value="Reset"/></p>
</form>
</body>
</html>
result.html
<html xmlns:th="https://thymeleaf.org">
<table>
<tr>
<td><h4>User Name: </h4></td>
<td><h4 th:text="${user.fullName}"></h4></td>
</tr>
<tr>
<td><h4>Age: </h4></td>
<td><h4 th:text="${user.age}"></h4></td>
</tr>
</table>
</html>
The controller class sends and reads a form view. The User data is passed as a parameter to the processForm() handler. Spring tries to fill the bean with the request data. The data is also automatically available for the Thymeleaf result view. The #Controller annotation allows the implementation classes to be autodetected through the classpath scanning.
#Controller is typically used in combination with a #RequestMapping annotation used on request handling methods. I used the #GetMapping and ##PostMapping` as a shortcut to #RequestMapping(method = RequestMethod.POST)
#Controller
public class HomeController {
//This responds to localhost:8080/
#GetMapping("/")
public String sendForm(User user){
return "index";
}
//This responds to localhost:8080/
#PostMapping("/")
public String processForm(User user){
return "result";
}
User Class. This is the User class. It is automatically filled with data from the form request. The attributes must match the form fields. You should be able to see the matching attribute names in the template views below.
public class User {
private String fullName;
private int age;
private String occupation;
public String getFullName() {
return fullName;
}
public void setFullName(String name) {
this.fullName = name;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
index.html
The th:object refers to the user form bean. This is not a class name, but a Spring bean name; therefore it is in lowercase. With the *{} syntax, we refer to the defined object. In this case its the user object. I noticed that you misspelled th:field, this can also create bugs.
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title></title>
</head>
<body>
<p> Enter Data Below </p>
<form th:action="#{/}" th:object="${user}" method="post">
<p>Full Name:<input type="text" th:field="*{fullName}" id="fullName" name="fullname" autofocus="autofocus"></p>
<p>Age:<input type="number" th:field="*{age}" id="age" name="age" autofocus="autofocus" /></p>
<p><input type="submit" value="Submit"/> <input type="reset" value="Reset"/></p>
</form>
</body>
</html>
result.html
We identify the form attributes with the ${} syntax.
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title></title>
</head>
<body>
<table>
<tr>
<td><h4>User Name: </h4></td>
<td><h4 th:text="${user.fullName}"></h4></td>
</tr>
<tr>
<td><h4>Age: </h4></td>
<td><h4 th:text="${user.age}"></h4></td>
</tr>
</table>
</body>
</html>
i'm new to spring-boot. In my system there are two models named subject,course(two databases with the same names and connected by the foreign key course_id).I need to make it possible to select course name in a dropdown list in the addSubject thymeleaf form. Can someone please tell me how to do this
Subject.DAO file
#Service
public class SubjectDAO {
#Autowired
SubjectRepository subjectRepository;
//to save a subject
public Subject save(Subject subject){
return subjectRepository.save(subject);
}
//to search all subjects
public List<Subject> findAll(){
return subjectRepository.findAll();
}
//get a subject by id
public Subject findById(Long id){
return subjectRepository.findById(id).orElse(null);
}
//delete a subject
public void delete(Long id){
subjectRepository.deleteById(id);
}
}
Course.DAO file
#Service
public class CourseDAO {
#Autowired
CourseRepository courseRepository;
//to save a course
public Course save(Course course){
return courseRepository.save(course);
}
//to search all courses
public List<Course> findAll(){
return courseRepository.findAll();
}
//get a course by id
public Course findById(Long id){
return courseRepository.findById(id).orElse(null);
}
//delete a course
public void delete(Long id){
courseRepository.deleteById(id);
}
}
Subject Controller
#Controller
public class SubjectController {
#Autowired
private SubjectDAO subjectDAO;
#RequestMapping("/subject")
public String viewHomePage(Model model){
List<Subject> subjectDetails= subjectDAO.findAll();
model.addAttribute("subjectDetails",subjectDetails);
return "subject";
}
#RequestMapping("/subject/new")
public String addSubject(Model model){
Subject subject =new Subject();
model.addAttribute("subject",subject);
return "addSubject";
}
#RequestMapping(value="/subject/save",method= RequestMethod.POST)
public String saveCourse(#ModelAttribute("subject") Subject subject){
subjectDAO.save(subject);
return "redirect:/subject";
}
#RequestMapping("/subject/edit/{id}")
public ModelAndView updateSubjcet(#PathVariable(name="id")Long id){
ModelAndView mav=new ModelAndView(("updateSubject"));
Subject subject=subjectDAO.findById(id);
mav.addObject("subject",subject);
return mav;
}
#RequestMapping("/subject/delete/{id}")
public String deleteProduct(#PathVariable(name="id") Long id){
subjectDAO.delete(id);
return "redirect:/subject";
}
}
Subject html file
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Adding a Subject</title>
</head>
<body>
<div align="center">
<h1>Add a new Subject</h1>
<br/>
<form action="#" th:action="#{/subject/save}" th:object="${subject}" method="post">
<table border="0" cell[adding="10">
<tr>
<td>Subject code:</td>
<td><input type="text" th:field="*{course_code}" /></td>
</tr>
<tr>
<td>Subject Name:</td>
<td><input type="text" th:field="*{name}" /></td>
</tr>
<tr>
<td>Course:</td>
<td>
<select>
<option value=""></option>
</select>
Z
</td>
</tr>
<tr>
<td colspan="2"><button type="submit">Save</button></td>
</tr>
</table>
</form>
</div>
</body>
</html>
So you want to load Course combo inside subject html
You need to modify subject controller
#RequestMapping("/subject")
public String viewHomePage(Model model){
List<Subject> subjectDetails= subjectDAO.findAll();
List<Course> courseDetail= courseDAO.findAll();
model.addAttribute("subjectDetails",subjectDetails);
model.addAttribute("courses",courseDetail);
return "subject";
}
In HTML
<tr>
<td>Course:</td>
<td>
<select th:field="*{course_code}">
<option value="">Choose..</option>
<option th:each="course: ${courses}" th:value="${course.id}" th:text="${course.name}" />
</select>
</td>
</tr>
<tr>
Edit 1:
I think you are loading addSubject.html
In that case you need to modify addSubject controller
#RequestMapping("/subject/new")
public String addSubject(Model model){
Subject subject =new Subject();
model.addAttribute("subject",subject);
List<Course> courseDetail= courseDAO.findAll();
model.addAttribute("courses",courseDetail);
return "addSubject";
}
Edit 2:
As per your code in Git I can see
#Autowired
private SubjectDAO subjectDAO;
private CourseDAO courseDAO;
It should be
#Autowired
private SubjectDAO subjectDAO;
#Autowired
private CourseDAO courseDAO;
First add all courses to the ModelMap
model.addAttribute("cources",courseDao.findAll());
Then use th:each attribute to populate select options
<select th:field="*{course}">
<option value="">Choose..</option>
<option th:each="c: ${cources}" th:value="${c.id}" th:text="${c.name}" />
</select>
This is my HOME page.
When the user selects a Datacenter the page redirects and shows the list of FisicHost's available for that Datacenter.
Datacenter class
#Entity
#Transactional
public class Datacenter {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
#OneToMany(mappedBy = "datacenter")
#LazyCollection(LazyCollectionOption.FALSE)
private List<FisicHost> fisicHostList;
// I've cut the constructor and get/set to make it shorter
}
This is the view where the user is redirected when it chooses a Datacenter:
each row in the view represents a FiscHost object that is available for the chosen datacenter.
FisicHost class
#Entity
#Transactional
public class FisicHost {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch=FetchType.EAGER)
private Datacenter datacenter;
#OneToMany(mappedBy = "fisicHost")
#LazyCollection(LazyCollectionOption.FALSE)
private List<Credential> credentials;
private String name;
private String ip;
private String operatingSystem;
private String notes;
}
This is the controller method handling the second view (the one that shows the list of available FisicHost's for that datacenter):
#RequestMapping(value = "/chosenDatacenter", method = RequestMethod.POST)
public String datacenterPostHandler(#RequestParam("datacenterList") String name, ModelMap modelMap){
List<Datacenter> allDatacenters = datacenterDao.getAllDatacenters();
for (Datacenter dc : allDatacenters) {
if (dc.getName().equals(name)) {
modelMap.put("datacenter", dc);
if(dc.getFisicHostList().size() != 0) {
List<FisicHost> datacenterFisicHosts = dc.getFisicHostList();
modelMap.put("datacenterFisicHosts", datacenterFisicHosts);
for(FisicHost fh : datacenterFisicHosts){
if(fh.getCredentials().size() != 0){
modelMap.put("fisicHostCredentialsList", credentialDao.getAllCredentialsByFisicHost(fh));
}
}
}
return "chosenDatacenter";
}
}
return null;
}
If the user clicks on the "CREDENCIALES" button a modal pops up and show all the credentials available for that FisicHost.
Credential class:
#Entity
public class Credential {
#Id
private int id;
#ManyToOne(fetch= FetchType.EAGER)
private FisicHost fisicHost;
private String user;
private String password;
private String notes;
private String role;
}
All this is working fine, BUT here comes the problem ...
Whatever button is clicked, the modal is opened showing ALL the credentials for ALL the FisicHosts inside THAT Datacenter and I ONLY want to show the Credentials for the specific FisicHost that was clicked in the corresponding datacenter!
I know this logic in the controller:
for(FisicHost fh : datacenterFisicHosts){
if(fh.getCredentials().size() != 0){
modelMap.put("fisicHostCredentialsList", credentialDao.getAllCredentialsByFisicHost(fh));
}
is only bringing back the last iteration of the loop, so it will always bring the credentials for that FisicHost no matter what ! And that's what happening, but I can't find a different way of doing it ...
Just in case, here is the getAllCredentialsByFisicHost() method from the CredentialDaoImpl class:
#Override
public List<Credential> getAllCredentialsByFisicHost(FisicHost fisicHost) {
// Open a session
Session session = sessionFactory.openSession();
Criteria c = session.createCriteria(Credential.class).add(Restrictions.eq("fisicHost.id", fisicHost.getId()));
List<Credential> allCredentials = c.list();
// Close the session
session.close();
return allCredentials;
}
Please help cause I'm going crazy with this !!!
Thanks a lot to all :)
PS: This is the chosenDatacenter template that is being rendered with ThymeLeaf:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Generic View</title>
<link rel="stylesheet" th:href="#{/css/bootstrap/bootstrap.min.css}" />
<link rel="stylesheet" th:href="#{/css/choosenDatacenter.css}" />
</head>
<body>
<form id="form" action="/getJson" th:object="${datacenterFisicHosts}" method="post">
<table>
<tr class="row">
<th class="tableHeader">Nombre</th>
<th class="tableHeader">IP</th>
<th class="tableHeaders">Sistema Operativo</th>
<th class="tableHeaders">Notas</th>
</tr>
<th:block th:each="fh : ${datacenterFisicHosts}">
<div id="fila">
<tr class="row">
<td id="fisicHostName" th:text="${fh.name}"></td>
<td id="fisicHostIp" th:text="${fh.ip}"></td>
<td id="fisicHostOS" th:text="${fh.operatingSystem}"></td>
<td id="fisicHostNotes" th:text="${fh.notes}"></td>
<td><button type="button" th:onclick="'javascript:openCredentialModal()'">CREDENCIALES</button></td>
</tr>
</div>
</th:block>
</table>
</form>
<!-- Modal -->
<div class="modal fade" id="modalCredenciales" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-title">Credenciales</h5>
</div>
<div class="modal-body">
<table>
<tr class="row">
<th class="tableHeader">Usuario</th>
<th class="tableHeader">Clave</th>
<th class="tableHeaders">Notas</th>
</tr>
<th:block th:each="credential : ${fisicHostCredentialsList}">
<tr class="row">
<td id="credentialUser" th:text="${credential.user}"></td>
<td id="credentialPassword" th:text="${credential.password}"></td>
<td id="credentialRole" th:text="${credential.notes}"></td>
</tr>
</th:block>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<script th:src="#{js/jquery-1.11.3.js}"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script th:src="#{js/chosenDatacenter.js}"></script>
</body>
</html>
You can use Ajax to pass the id to your controller and have it return only the relevant cerdentials, as explained here.
In your controller you add a method that returns the correct list of credentials taking the id of the fisicHost as a parameter:
#RequestMapping("/fisicHost/{id}")
public String fisicHost credentials(#PathVariable("id") String id, ModelMap model)
{
//find credentials by fisicHost using your DAO and add them to model
return "modal/credentials :: modalContents";
}
You'll need a 'modalContents' Thymeleaf fragment to display the credentials as added to model.
Then on the onClick event, you can use Ajax to call the url with the correct id and display the data. In your template, you'd have:
th:onclick="'javascript:openCredentialModal(\'' + ${fh.id} + '\');'"
The Ajax function just calls the url of your controller by passing th id along, and is returned the html code from the thymeleaf fragment. It then packs the html content in the modal.
I was able to create values and store into my db, which displays a view of the list of values stored and additional values that is written into a input will automatically show in the table.
Controller
#Controller
public class AppPortController {
private ApServerService apServerService;
#Autowired
public void setApServerService(ApServerService apServerService) {
this.apServerService = apServerService;
}
#RequestMapping(value = "/editApServer", method = RequestMethod.GET)
public String list(Model model) {
model.addAttribute("apList", apServerService.listAllApServerModels());
return "editApServer";
}
#RequestMapping("editApServer/update/{id}")
public String update(#PathVariable String id, Model model) {
model.addAttribute("apList", apServerService.getApServerModelById(id));
return "editApServer";
}
#RequestMapping("editApServer/new")
public String newServer(Model model){
model.addAttribute("apServer", new ApServerModel());
return "editApServer";
}
#RequestMapping(value = "/addServer", method = RequestMethod.POST)
public String addServer(#ModelAttribute ApServerModel apServerModel) {
apServerService.saveApServerModel(apServerModel);
return "redirect:editApServer";
}
#RequestMapping("editApServer/delete")
public String delete(#PathVariable String host){
apServerService.deleteApServerModel(host);
return "redirect:editApServer";
}
Repository
public interface AppPortRepository extends CrudRepository<ApServerModel, String> {}
POJO
#Document(collection = "apDBServer")
public class ApServerModel {
#Id
private String id;
private String host;
private String port;
//getters and setters
HTML SNIPPET
<table>
<thead>
<tr>
<th> Host Name </th>
<th> Port Name</th>
<th>Id</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr th:each="ApServerModel : ${apList}">
<td th:text ="${ApServerModel.host}"></td>
<td th:text ="${ApServerModel.port}"></td>
<td th:text ="${ApServerModel.id}"></td>
<td><a th:href="${'editApServer/update/' + ApServerModel.id}">Edit</a></td>
<td><a th:href="${'editApServer/delete'}">Delete</a></td>
</tr>
</tbody>
</table>
<br />
<h2>Add AppPortServer</h2>
<form action="/addServer" method="POST">
Host <input type="text" id="host" name="host" /><br />
Port <input type="text" id="port" name="port" /><br />
<input type="submit" />
</form>
Problem
In my controller the delete would not execute(it is not doing what I want it to do). but line below it redirects me back to the same page.
What am I doing wrong? I have been savaging through the internet trying to find the crud functions for mongodb using springboot. Logically speaking why wouldn't my delete work if I follow the logic of the create?
I followed Tutorial, for posting to a table. Then I followed
Tutorial 2 That implements my delete and update. But It does not delete the values.