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.
Related
I am new to spring and I need to be able to delete the selected rows by checkbox. How can I delete multiple rows from the database? I am using Thymeleaf as view.
Here is my code:
HTML
<div class="col-md-12">
<table class="table" id="tableImport">
<thead>
<tr>
<th scope="col">Remove</th>
<th scope="col">Debt Age Rule</th>
<th scope="col">Reminder</th>
<th scope="col">Frequency</th>
<th scope="col">Reorder</th>
</tr>
</thead>
<tbody>
<tr th:each="configCampaign:${listConfigCampaigns}">
<td>
<input type="checkbox" name="my-checkbox">
</td>
<td th:text="${configCampaign.debtagerule}"></td>
<td th:text="${configCampaign.remindebttype}"></td>
<td th:text="'Every '+${configCampaign.every} + ' ' + ${configCampaign.unit}"></td>
<td></td>
</tr>
</tbody>
</table>
<div class="col-md-12" style="text-align: center">
<input class="btn btn-primary" type="button" value="- Remove Selected Action(s)"/>
</div>
</div>
This table shows me data from an arrayList in memory, nothing with a database, I need to remove those selected objects from the array. At the moment I have my controller like this
Entity
private int configid;
private String debtagerule;
private String remindebttype;
private int every;
private String unit;
private boolean selected;
//getters and setters
In addition to the above, this is the controller with which I am currently working
Controller
#GetMapping("/deleteConfigureCampaign")
public String deleteConfig(#ModelAttribute ConfigCampaign configCampaign, Model model) {
listConfigCampaigns.remove(configCampaign);
return "redirect:/configureCampaign";
}
In Spring Boot, You have to use JpaRepository<> for delete data from database and need to understand structure of Spring Boot project.
Here is sturcture of Spring Boot project:
Entity -> Repository -> Service -> Controller -> View.
Here down is code:
Entity
#Table(name = "config_master")
public class ConfigCampaign {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer configid;
private String debtagerule;
private String remindebttype;
private Integer every;
private String unit;
private boolean selected;
// Constructor, Getter and Setter
}
Repository
Use of #Modifying annotation: It is used to enhance the #Query annotation so that we can execute not only SELECT queries, but also INSERT, UPDATE, DELETE, and even DDL queries
#Repository
public interface ConfigRepo extends JpaRepository<ConfigCampaign, Integer>{
#Modifying
#Transactional
#Query(nativeQuery = true, value = "DELETE FROM config_master WHERE configid IN(?1)")
void delConfig(List<Integer> configId);
}
Service
#Service
public class PojoServiceImpl{
#Autowired
private ConfigRepo configRepo;
#Override
public void delConfig(Integer[] configId) {
configRepo.delConfig(Arrays.asList(configId));
}
}
Controller
// Show table of Config Campaign
#RequestMapping(value = "/showconfig", method = RequestMethod.GET)
public String getConfig(Model mdl)
{
List<ConfigCampaign> getConfig = pojoService.getAllConfig();
mdl.addAttribute("config", getConfig);
return "showConfigCampaign";
}
// Delete item from Config Campaign
#RequestMapping(value = "/delcampaign", method = RequestMethod.GET)
public String deleteConfig(#RequestParam("cid") Integer[] configId)
{
pojoService.delConfig(configId);
return "redirect:/showconfig";
}
showConfigCampaign
You have to add configData.configid in checkbox.
<form th:action="#{/delcampaign}" th:object="${sconfig}">
<div class="container">
<div class="row">
<div class="col-sm-12">
<table class="table" style="text-align: center">
<thead>
<tr>
<th scope="col">Remove</th>
<th scope="col">Debt Age Rule</th>
<th scope="col">Reminder</th>
<th scope="col">Frequency</th>
</tr>
</thead>
<tbody>
<tr th:each="configData: ${config}">
<td><input type="checkbox" name="cid" th:value="${configData.configid}"/></td>
<td th:text="${configData.debtagerule}"></td>
<td th:text="${configData.remindebttype}"></td>
<td th:text="${configData.every}"></td>
</tr>
</tbody>
</table>
<input type="submit" value="Delete Users" />
</div>
</div>
</div>
</form>
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>
I have a table in a form that I want to bind each row to an object and then add that object to a list on the server side, but when I do form.bindFromRequest(), I get null values and I can't figure out the binding. The following is my HTML/form.
<tr>
<td><input type="hidden" value="#domains(i).id" name="domains[#i].domainId" readonly></td>
<td><input type="text" value="#domains(i).domain" name="domains[#i].domain"></td>
<td><input type="text" class="no-default-datepicker" value="#domains(i).date.format("yyyy-MM-dd")" name="domains[#i].date" /></td>
<td><input type="hidden" value="#domains(i).cycle" name="domains[#i].cycle">#domains(i).cycle</td>
<td>#defining(if (domains(i).blacklist == true) "checked" else "") { checked =>
<input name="domains[#i].blacklist" type="checkbox" #checked />}
<input type="hidden" name="domains[#i].blacklist" value="false"></td>
<td><input type="text" value="#domains(i).source" name="domains[#i].source"></td>
#for( x <- domains(i).results.indices){
<td><input type="text" value="#domains(i).harvestResults(x).results" name="domains[#i].results[#x].results"></td>
}
</tr>
Edit: Server-side code, but it's wrong and doesn't work. I can't get the harvestResults subclass to bind when I get the form.
public static Result update(){
Form<EditClass> form = form(EditClass.class).bindFromRequest();
EditClass ec = form.get(); //problem starts here, the harvestResults won't work.
return redirect("/search");
}
Data model:
public class Domain {
public static class HarvestInformation{
#JsonProperty("_id")
public String id;
public String name;
public String results;
}
#JsonProperty("_id")
public String id;
public String domain;
public Boolean bl;
public String source;
public Date date;
public Integer cycle;
public List<HarvestInformation> harvestResults;
}
In the below Spring form, my object's ID field is populated, but when I receive the submission in the controller method, all of the form's fields are populated except for the ID field. I've quintuple-checked that the field type and getter/setter types are all the same non-primitive, as I've seen many of the other questions on SO similar to this and that seems to be the common issue. The controller doesn't have any method-level #ModelAttributes, so it isn't being populated otherwise.
Here's the declaration of the POST method, as I debugged it on the first containing line and found that the form's id field is empty:
#RequestMapping(value="/{orgId}", method=RequestMethod.POST)
public String editOrganizationPost(#PathVariable int orgId,
#Valid #ModelAttribute(ORG_FORM) OrganizationForm orgForm,
BindingResult result, RedirectAttributes att,
HttpServletRequest request) {
Here's the form object:
public class OrganizationForm {
private Integer id;
#NotBlank
private String name;
#NotBlank
private String description;
private Set<User> users;
int moveToOrganizationId = 0;
String moveToOrganizationName;
int[] moveFromOrganizationUserSelect = null; // List of selected users
// to be moved to a new
// organization
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public int getMoveToOrganizationId() {
return this.moveToOrganizationId;
}
public void setMoveToOrganizationId(int moveToOrganizationId) {
this.moveToOrganizationId = moveToOrganizationId;
}
public String getMoveToOrganizationName() {
return this.moveToOrganizationName;
}
public void setMoveToOrganizationName(String moveToOrganizationName) {
this.moveToOrganizationName = moveToOrganizationName;
}
public int[] getMoveFromOrganizationUserSelect() {
return this.moveFromOrganizationUserSelect;
}
public void setMoveFromOrganizationUserSelect(
int[] moveFromOrganizationUserSelect) {
this.moveFromOrganizationUserSelect = moveFromOrganizationUserSelect;
}
public boolean isNew() {
return this.id == null || this.id == 0;
}
}
Here is the markup from the JSP file:
<form:form method="post" action="${submitUrl}" commandName="organizationForm">
<form:errors path="*" />
<form:hidden path="id" />
<table class="adminTable editContent">
<tr class="bg_lgtGrey">
<td><fmt:message
key="manageOrganizations.organizationForm.name" />:</td>
<td><form:input path="name" cssClass="inputbox"
tabindex="4" /></td>
</tr>
<tr class="bg_lgtGrey">
<td><fmt:message
key="manageOrganizations.organizationForm.description" />:</td>
<td><form:textarea path="description"
cssClass="inputbox" tabindex="4" /></td>
</tr>
<tr>
<td colspan="2" align="right"><c:choose>
<c:when test="${!organizationForm.new}">
<input type="submit" class="btn btn-primary"
id="submit_button" value="Update" />
</c:when>
<c:otherwise>
<input type="submit" class="btn btn-primary"
id="submit_button" value="Create" />
</c:otherwise>
</c:choose></td>
</tr>
</table>
</form:form>
And here is the generated HTML:
<form id="organizationForm" action="/admin/organizations/1" method="post">
<input id="id" name="id" type="hidden" value="1">
<table class="adminTable editContent">
<tbody><tr class="bg_lgtGrey">
<td>Organization Name:</td>
<td><input id="name" name="name" class="inputbox" tabindex="4" type="text" value="Organization1"></td>
</tr>
<tr class="bg_lgtGrey">
<td>Organization Description:</td>
<td><textarea id="description" name="description" class="inputbox" tabindex="4"></textarea></td>
</tr>
<tr>
<td colspan="2" align="right">
<input type="submit" class="btn btn-primary" id="submit_button" value="Update">
</td>
</tr>
</tbody></table>
</form>
I used Chrome devtools to catch the POST data and here it is:
id=1&name=Organization1&description=
...yet at the breakpoint at the first line of the editOrganizationPost method, the form.id field is set to 0.
I have spent forever trying to figure out why it will bind the name and description but not the ID when sent. I could obviously just inject the ID from the path variable but I am dumbfounded as to why it wouldn't just populate the field naturally.
I had the same problem.. the id field would always be set to 0. Changing the id field to something else didn't work either. After more hit and trail, removing
disabled="true"
from
<form:input path"id" disabled="true"/>
fixed the issue.
I assumed
<form:hidden path="id">
would give the same error but it didn't.
I'm trying to achieve the JSR 303 bean validation in Spring 3.0 by using a simple login use case. The problem is if I submit the form without any value the validation is not happening (i.e the BindingResult method hasErrors() always returning 'false' and printing I'm cool !. Following is the code snippet:
#Controller
public class AnnotatedController {
#RequestMapping(value = "login")
public String validateLogin(#Valid LoginForm loginForm, BindingResult result, HttpServletRequest request) {
if(result.hasErrors())
System.out.println("Got Errors !");
else
System.out.println("I'm cool !");
return "login";
}
}
The bean looks like this :
public class LoginForm {
#NotEmpty
private String userName;
#Size(min=2, max=3)
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Finally the view:
<table>
<form:form action="login.htm" modelAttribute="loginForm">
<tr>
<td>User :</td>
<td><form:input path="userName" /></td>
</tr>
<tr>
<td>Password :</td>
<td><form:input path="password" /></td>
</tr>
<tr><td><input type="submit" value="Ok"> </tr>
</form:form>
</table>
What am I missing ?
Adding <mvc:annotation-driven/>in servlet context XML fixed the issue for me.
you are missing form error tag.use like
<table>
<form:form action="login.htm" commandName="logindetails">
<tr>
<td>User :</td>
<td><form:input path="userName" /></td>
<td><form:errors path="userName" /></td>
</tr>
<tr>
<td>Password :</td>
<td><form:input path="password" /></td>
<td><form:errors path="password" /></td>
</tr>
<tr><td><input type="submit" value="Ok"> </tr>
</form:form>
and also you have to maintain property file with error message.
NotEmpty.logindetails.userName = userName is required!
Range.logindetails.password= password value must be between 2 and 3
Example:
Click here