Problem with PostMapping - GetMapping method - loop in link. SpringBoot - java

I have problems with sending data to one of my tables.
Below you can see my methods: one that shows the template with form, and the second that shoud add this action.
#GetMapping("/addaction/{id}")
public String addAction(Model model, #PathVariable("id") int id ) {
Optional<PlantEntity> plantEntity = plantService.getPlantById(id);
if (plantEntity.isPresent()) {
model.addAttribute("plant", plantEntity.get());
}
return "addaction";
}
#PostMapping("/addaction/{id}")
public String addAction(#ModelAttribute ActionForm actionForm,
#PathVariable("id") int plantId) {
if(!userService.isLogin()) {
return "redirect:/";
}
actionService.addAction(actionForm, plantId);
return "redirect:/plant/"+plantId;
}
Here is my method in Service:
public void addAction (ActionForm actionForm, int plantId) {
PlantEntity plantEntity = new PlantEntity();
plantEntity.setId(plantId);
ActionEntity act = new ActionEntity();
act.setName(actionForm.getName());
act.setDescription(actionForm.getDescription());
act.setPlant(plantEntity);
act.setUser(userService.getUserData());
act.setMonth(actionForm.getMonth());
actionRepository.save(act);
}
and my template: addaction.html
<form method="post" action="'/addaction/'+${plant.getId()}"
th:object="${actionForm}">
<div class="form-group">
<label for="exampleInputEmail1">Name of activity</label> <input
type="text" th:field="*{name}" class="form-control"
id="exampleFormControlInput1" aria-describedby="emailHelp"
placeholder="Name your work">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">What you gonna
do?</label>
<textarea class="form-control" th:field="*{description}"
id="exampleFormControlTextarea1" rows="4"></textarea>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<label class="input-group-text" for="inputGroupSelect01">Month of activity</label>
</div>
<select class="custom-select" th:field="*{month}"
id="inputGroupSelect01">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
</div>
<button type="submit" class="btn btn-dark">Action!</button>
</form>
The main problem is: when I try to addAction the result is:
http://localhost:8080/addaction/'/addaction/'+$%7Bplant.getId()%7D
There is some kind of loop. What am I doing wrong? Thank you for your time!

You don't have to pass '. spring expression language will take without ' also.
Try removing like below.
action="/addaction/${plant.getId()}"
Refer thymeleaf-construct-url-with-variable

Related

Exception sending id field to #PostMapping

I'm getting this exceptions when trying to update an object with a PostMapping:
Caused by: org.thymeleaf.exceptions.TemplateProcessingException:
Exception evaluating SpringEL expression: "libro.id" (template:
"formulario-modificar-libros-p" - line 18, col 15)
Caused by:
org.springframework.expression.spel.SpelEvaluationException: EL1007E:
Property or field 'id' cannot be found on null
Form:
<form th:action="#{/libros/modificar-libro-d/__${libro.id}__}" method="post">
<input hidden th:value="${libro.id}" name="id">
<div class="form-group">
<label>ISBN del libro</label> <input th:value="${libro.isbn}" type="number" class="form-control" name="isbnLibro" required>
</div>
<div class="form-group">
<label>Título del libro</label> <input th:value="${libro.titulo}" type="text" class="form-control" name="tituloLibro" required>
</div>
<div class="form-group">
<label>Año del libro</label> <input th:value="${libro.anio}" type="number" class="form-control" name="anioLibro">
</div>
<div class="form-group">
<label>Ejemplares del libro</label> <input th:value="${libro.ejemplares}" type="number" class="form-control" name="ejemplaresLibro" required>
</div>
<div>
<label>Autor</label>
<select class="form-select" aria-label="Default select example" name="nombreAutor">
<option th:each="autor:${autores}"
th:text="${autor.nombre}"
th:value="${autor.nombre}"
>
</option>
</select>
</div>
<div>
<label>Editorial</label>
<select class="form-select" aria-label="Default select example" name="nombreEditorial">
<option th:each="editorial:${editoriales}"
th:text="${editorial.nombre}"
th:value="${editorial.nombre}"
>
</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Aceptar</button>
</form>
Controller
#PostMapping("/modificar-libro-d/{id}")
public String modificarLibroM(#PathVariable String id, #RequestParam Long isbnLibro, #RequestParam String tituloLibro, #RequestParam Integer anioLibro,
#RequestParam Integer ejemplaresLibro, #RequestParam String nombreAutor, #RequestParam String nombreEditorial){
try {
libroServicio.modificarLibro(id, isbnLibro, tituloLibro, anioLibro, ejemplaresLibro, nombreAutor, nombreEditorial);
return "redirect:/libros/lista-libros-d";
} catch (Exception e) {
return "formulario-modificar-libros-p";
}
}
#GetMapping("/modificar-libro-d/{id}")
public String formularioModificarLibrosM(#PathVariable String id, ModelMap modelo) {
modelo.addAttribute("libro", libroServicio.buscarLibroPorId(id));
modelo.addAttribute("autores", autorServicio.listarAutoresAlta());
modelo.addAttribute("editoriales", editorialServicio.listarEditorialesAlta());
return "formulario-modificar-libros-p";
}
In the entity, all fields have their getters and setters correctly.
It looks like your code is okay but the find by id method on your book service returns null for the given id. Put a breakpoint on it and run it in debug. If a libro object must always be present, consider defining your libroServicio.buscarLibroPorId(id) method such that an exception is thrown for a missing id and/or set up error handling in your thymeleaf template.

Two submit buttons to do two different things

Using Thymeleaf, Spring-boot and Java. When I click either of these buttons (listed on same form/page), it submits to the /send path instead of its directed path. Ideas? One button needs to go to send, one needs to go to /addPolicy and append some input items to the page.
<form class="ui form" th:object="${directBind}" method="post" th:action="#{/send}" style="padding:0 10px;">
<h4>Customer Setup</h4>
<div class="row">
<label >Contact Name (First/Last):</label>
<input type="text" th:field="*{contactName}" required="true" />
</div>
<div class="row">
<label for="formAddress">Address:</label>
<input type="text" id="formAddress" th:field="*{formAddress}" required="true"/>
</div>
<div class="row">
<label for="phoneNumber">Phone Number:</label>
<input type="text" id="phoneNumber" th:field="*{phoneNumber}" required="true"/>
</div>
<div class="row">
<label for="email">Email:</label>
<input type="email" id="email" th:field="*{email}" required="true"/>
</div>
<div class="row">
<label for="website" style="margin-top: 1em;"> Website:</label>
<input type="text" id="website" th:field="*{website}" required="true"/>
</div>
<div class="row">
<label for="nameInsured">Name Insured:</label>
<input type="text" id="nameInsured" th:field="*{insuredName}" required="true"/>
</div>
<div class="row">
<label>Business with Agency:</label>
<div th:each="businessAgency : ${businessAgencies}">
<input type="checkbox" th:field="*{businessAgencyList}" th:value="${businessAgency}"/>
<label th:text="${businessAgency}">Business with Agency</label>
</div>
</div>
<div class="row">
<label for="executive">Executive:</label>
<input type="text" id="executive" th:field="*{executive}" required="true"/>
</div>
<div class="row" style="display: inline-block;">
<p>Service Level:</p>
<ul>
<li>
<label class="forCheckbox">
<input type="checkbox" th:field="*{serviceLevel}" required="true"/>
Affiliate Serviced</label>
</li>
</ul>
</div>
<div class="row">
<label for="affiliateRep">Affiliate Designated Representative:</label>
<input type="text" id="affiliateRep" th:field="*{affiliateRep}" required="true" />
</div>
<div>
<h4 style="display: inline;">AMS360 Policy Setup</h4>
<button id="addPolicy" type="submit" name="addPolicy" class="btn btn-default" style="margin-left: 1rem; margin-bottom: 1rem;"><span class="fa fa-plus"></span></button>
</div>
<div class="col-sm-12">
<hr/>
<table class="table table-striped" data-classes="table-no-bordered" data-striped="true" data-show-columns="true" data-pagination="true">
<thead>
<tr>
<th>Policy Number</th>
<th>Policy Term Start Date</th>
<th>Policy Term End Date</th>
<th>Line of Coverage</th>
<th>Parent Company</th>
<th>Writing Company</th>
<th>Bill Type</th>
<th>Quote Premium</th>
<th>Commission</th>
</tr>
</thead>
<tbody>
<tr th:each="ams360Policy,stat : *{ams360Policies}">
<td> <input type="text" class="form-control" th:field="*{ams360Policies[__${stat.index}__].policyNumber}"/></td>
<td> <input type="text" class="form-control" th:field="*{ams360Policies[__${stat.index}__].policyTermStartDate}"/></td>
<td> <input type="text" class="form-control" th:field="*{ams360Policies[__${stat.index}__].policyTermEndDate}"/></td>
<td><input type="text" id="lineOfCoverage" th:field="*{ams360Policies[__${stat.index}__].lineOfCoverage}" /></td>
<td><input type="text" id="parentCompany" th:field="*{ams360Policies[__${stat.index}__].parentCompany}" /></td>
<td><input type="text" id="writingCompany" th:field="*{ams360Policies[__${stat.index}__].writingCompany}" /></td>
<td> <div th:each="billType : ${billTypeList}">
<input type="checkbox" th:field="*{billTypeOptions}" th:value="${billType}"/>
<label th:text="${billType}">Bill Types</label>
</div></td>
<td><input type="text" id="quotePremium" th:field="*{ams360Policies[__${stat.index}__].quotePremium}" /></td>
<td><input type="text" id="commission" th:field="*{ams360Policies[__${stat.index}__].commission}" /></td>
</tr>
</tbody>
</table>
</div>
<h4>PMA Setup</h4>
<div class="row" sec:authorize="hasAnyRole('ADMIN','USER')">
<label>Sub Brand:</label>
<th:block th:switch="${loggedUser==null or loggedUser.client==null }">
<span th:case="false" th:text="${loggedUser.client.getLegalName()}" ></span>
<span th:case="true">Not Applicable</span>
</th:block>
<th:block th:switch="${loggedUser==null or loggedUser.client==null}">
<input th:case="false" type="hidden" name="subBrand" id="subBrand" th:value="${loggedUser.client.getLegalName()}" />
<input th:case="true" type="hidden" name="subBrand" id="subBrand" value="Not Applicable" />
</th:block>
</div>
<!-- Business Class Drop Down Field Below: -->
<div class="row">
<label for="businessClass" >Business Class: </label>
<select class="select-2 form-control" th:field="*{businessClass}" id="businessClass" >
<option value="Animal Services">Animal Services</option>
<option value="Arts Entertainment">Arts & Entertainment</option>
<option value="Auto Services">Auto Services</option>
<option value="Bonds">Bonds</option>
<option value="Carpet Furniture or Upholstery Cleaning">Carpet, furniture or upholstery cleaning</option>
<option value="Clock Making/Repair">Clock Making/Repair</option>
<option value="Contractor - Appliance Install/Repair">Contractor - Appliance Install/Repair</option>
<option value="Contractor - Carpentry (Exterior)">Contractor - Carpentry (Exterior)</option>
<option value="Contractor - Carpentry (Interior)">Contractor - Carpentry (Interior)</option>
<option value="Contractor - Concrete (No Foundations)">Contractor - Concrete (No Foundations)</option>
<option value="Contractor - Debris Removal">Contractor - Debris Removal</option>
<option value="Contractor - Doors and Windows">Contractor - Doors & Windows</option>
<option value="Contractor - Drywall/Plastering /Stucco">Contractor - Drywall/Plastering /Stucco</option>
<option value="Contractor - Electrical">Contractor - Electrical</option>
<option value="Contractor - Excavating">Contractor - Excavating</option>
<option value="Contractor - Fence Installation/Repair">Contractor - Fence Installation/Repair</option>
<option value="Contractor - Floor Covering (Not tile or stone)">Contractor - Floor Covering (Not tile or stone)</option>
<option value="Contractor - General/Builder/New Construction">Contractor - General/Builder/New Construction</option>
<option value="Contractor - Glass Install/Repair (Non-Auto)">Contractor - Glass Install/Repair (Non-Auto)</option>
<option value="Contractor - Grading/Snow Removal ">Contractor - Grading/Snow Removal </option>
<option value="Contractor - Handyman/Remodeling">Contractor - Handyman/Remodeling</option>
<option value="Contractor - Heating and Air">Contractor - Heating & Air</option>
<option value="Contractor - Interior Finish Work">Contractor - Interior Finish Work</option>
<option value="Contractor - Masonry">Contractor - Masonry</option>
<option value="Contractor - Other">Contractor - Other</option>
<option value="Contractor - Painting (Exterior)">Contractor - Painting (Exterior)</option>
<option value="Contractor - Painting (Interior)">Contractor - Painting (Interior)</option>
<option value="Contractor - Painting (Interior/Exterior)">Contractor - Painting (Interior/Exterior)</option>
<option value="Contractor - Paving">Contractor - Paving</option>
<option value="Contractor - Plumbing (Commercial)">Contractor - Plumbing (Commercial)</option>
<option value="Contractor - Plumbing (residential)">Contractor - Plumbing (residential)</option>
<option value="Contractor - Plumbing (Residential/Commercial)">Contractor - Plumbing (Residential/Commercial)</option>
<option value="Contractor - Siding and Gutter Install">Contractor - Siding & Gutter Install</option>
<option value="Contractor - Tile/Stone/Marble/Mosaic/Terrazzo">Contractor - Tile/Stone/Marble/Mosaic/Terrazzo</option>
<option value="Daycares">Daycares</option>
<option value="Domestic Workers">Domestic Workers</option>
<option value="Educational Services">Educational Services</option>
<option value="Farm">Farm</option>
<option value="Food and Beverage">Food & Beverage</option>
<option value="Generic BOP/Package (GL/Property)">Generic BOP/Package (GL/Property)</option>
<option value="Homecare">Homecare</option>
<option value="Homeowners Association">Homeowners Association</option>
<option value="Hotel/Motel">Hotel/Motel</option>
<option value="Janitorial">Janitorial</option>
<option value="Landscaping">Landscaping</option>
<option value="Lessors Risk">Lessors Risk</option>
<option value="Life Science">Life Science</option>
<option value="Locksmith">Locksmith</option>
<option value="Manufacturing">Manufacturing</option>
<option value="Medical Services">Medical Services</option>
<option value="Miscellaneous Services">Miscellaneous Services (Not Construction Related)</option>
<option value="Non-Profit">Non-Profit</option>
<option value="Other">Other</option>
<option value="Personal Lines (Non-Commercial)">Personal Lines (Non-Commercial)</option>
<option value="Personal Services (Beauty, Wellness, Etc.)">Personal Services (Beauty, Wellness, Etc.)</option>
<option value="Personal Trainers/Fitness Instructors/Yoga Instructors">Personal Trainers/Fitness Instructors/Yoga Instructors</option>
<option value="Photography/Videography">Photography/Videography</option>
<option value="Professional Services">Professional Services</option>
<option value="Religious Organizations">Religious Organizations</option>
<option value="Retail/Wholesale">Retail/Wholesale</option>
<option value="Security Firms (Including Private Investigators)">Security Firms (Including Private Investigators)</option>
<option value="Sign painting/lettering (Exterior)">Sign painting/lettering (Exterior)</option>
<option value="Sign painting/lettering (Interior)">Sign painting/lettering (Interior)</option>
<option value="Solar Energy">Solar energy</option>
<option value="Sports/Recreation/Leisure (Other than Fitness and Trainers)">Sports/Recreation/Leisure (Other than Fitness & Trainers)</option>
<option value="Storage Facilities">Storage Facilities</option>
<option value="Technology">Technology</option>
<option value="Trucking/Transportation">Trucking/Transportation</option>
<option value="Upholstery Work">Upholstery Work</option>
<option value="Window Cleaning">Window Cleaning</option>
<option value="Workers Compensation">Workers Compensation</option>
</select>
</div>
<div class="row">
<label for="descriptionOfOps">Description of Operations:</label>
<input type="text" id="descriptionOfOps" th:field="*{descriptionOfOps}" required="true" />
</div>
<div class="formFooter">
<input id="send" type="submit" value="send" name="send" class="btn btn-success finish" data-loading-text="Sent!"/>
</div>
</form>
This is the controller, the addPolicy button is supposed to go to /addPolicy link, the send button is supposed to go to the /send link.
#GetMapping("/directBind")
public String getDirectBind(Model model){
List<String> businessAgencies = new ArrayList<String>();
businessAgencies.add("Personal");
businessAgencies.add("Commercial");
businessAgencies.add("Life");
businessAgencies.add("Benefits");
businessAgencies.add("Health");
businessAgencies.add("Non P and C");
model.addAttribute("businessAgencies", businessAgencies);
Ams360Policy ams360Policy = new Ams360Policy();
List<String> billTypeList = new ArrayList<String>();
billTypeList.add("Direct Bill");
billTypeList.add("Agency Bill");
model.addAttribute("billTypeList", billTypeList);
ams360Policy.setBillTypeOptions(billTypeList);
DirectBind directBind = new DirectBind();
List<String> businessAgencyList = new ArrayList<String>();
directBind.setBusinessAgencyList(businessAgencyList);
model.addAttribute("directBind", directBind);
return "directBind";
}
#RequestMapping(value="/addPolicy", params="addPolicy")
public String addPolicy(final DirectBind directBind, Model model){
directBind.getAms360Policies().add(new Ams360Policy());
model.addAttribute("directBind", directBind);
return "addPolicy";
}
#RequestMapping(value="/send", params="send")
public String send(Model model, #ModelAttribute(value="directBind") DirectBind directBind){
List<String> businessAgencyList = directBind.getBusinessAgencyList();
Mail mail = new Mail();
mail.setFrom("no-reply#hgitservices.com");
mail.setTo(new String[]{"stacief#hgitservices.com"});
mail.setSubject("Oli Affiliate - AMS360 & PMA Data Checklist");
Map<String, Object> mailModel = new HashMap<String, Object>();
mail.setModel(mailModel);
try {
emailService.sendSimpleMessage(mail, directBind);
} catch (Exception e) {
e.printStackTrace();
return ("redirect:/?sentMessageFail");
}
return ("redirect:/?sentMessage");
}
#RequestMapping(value="/email")
public String email(){
return "emailMessage";
}
}
If you are using javascript or js framework like jQuery you could bind the button to a function which will submit the form to specified action.
See Process a Form Submit with Multiple Submit Buttons in Javascript for details.
I infer, you intent is to use one spring controller to process submit actions from two submit buttons.
You can use same name and different value attribute for the two html input button`s. The buttons name and value attribute are sent to controller as request parameter. This will allow the controller to identify which button was clicked and take appropriate action.
<input id="send_id" type="submit" name="action" value="send"/>
<input id="addPolicy_id" type="submit" name="action" value="addPolicy"/>
#RequestMapping(value="/directBind")
public String doExecute(#RequestParam("action") String action, Model model, #ModelAttribute(value="directBind") DirectBind directBind){
if (action=="send"){
//do something
send();
}
if (action=="addPolicy"){
//do something
addPolicy();
}
}

Send values from thymeleaf to a spring boot service class

I am testing a spring boot application which uses thymeleaf, but I could not find any docs explaining how to send select options values from thymeleaf to a spring boot service class.
Basically, what I am trying to achieve is get values from the select tag so that I can insert them to the database through the method below:
Please note: this method is in the service class => it has both get and post mapping in the controller class.
public void addNewJob(JobPostEntity jobPostEntity, #RequestParam(value="selectCategory") String selectCategory) {
jobPostEntity.setJobcategory("test");
jobPostRepository.save(jobPostEntity);
}
the thymeleaf file is:
<form th:action="#{/newjob}" th:object="${addNewJob}" method="post">
<div class="form-group">
<label for="">Offer Title</label>
<input type="text" th:field="*{jobtitle}" class="form-control" placeholder="Entre Offer Title">
<small class="form-text text-muted">We'll never share your email
with anyone else.</small>
</div>
<div class="form-group">
<label >Company Name</label>
<input type="text" th:field="*{jobcompany}" class="form-control" placeholder="Enter Company Name">
</div>
<div class="form-group dropdown">
<label for="sel1">Choose Category (select one):</label>
<select name="*selectCategory"
class="form-control" id="selectCategory"
onchange="getSelectedValue();" th:field="*{selectCategory}">
<option value="">Select Option</option>
<option value="software_engineer">Software Engineer</option>
<option value="graphic_design ">Graphic Design</option>
<option value="customer_service ">Customer Service</option>
<option value="marketing" >Marketing</option>
<option value="healthcare">Health Care</option>
</select>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Offer</label>
<textarea class="form-control" th:field="*{jobtext}" placeholder="Describe your job offer"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit Offer</button>
</form>
First, you need to properly configure your controller class. I assume this is where your addNewJob method is located, so I use this in my example.
You need to have a #GetMapping (which is the same as #RequestMapping(method = RequestMethod.GET) that returns the name of the view (this is your thymeleaf file - in the example below I used jobForm.html for this) and maps to a specific path (/test in example).
#GetMapping("/test")
public String getTestView() {
return "jobform";
}
You will also need a method which creates/retrieve the model object you use to fill the form with. This is mapped as th:object=${addNewJob} in the form:
#ModelAttribute(value = "addNewJob")
public JobPostEntity newEntity() {
return new JobPostEntity();
}
Finally, you will need a method with #PostMapping, that's called when you submit your form. In your example, that's mapped to /newjob, so I used this too:
#PostMapping(value = "/newjob")
public void addNewJob(
#ModelAttribute("addNewJob") final JobPostEntity myEntity) {
System.out.println("got dto: " + myEntity);
System.out.println("selectCategory: " + myEntity.getSelectedCategory());
}
To summarize the controller would look something like this:
#Controller
public class TestController {
#GetMapping("/test")
public String getTestView() {
return "jobform";
}
#PostMapping(value = "/newjob")
public void addNewJob(
#ModelAttribute("addNewJob") final JobPostEntity myEntity) {
System.out.println("got dto: " + myEntity);
System.out.println("selectCategory: " + selectCategory);
}
#ModelAttribute(value = "addNewJob")
public JobPostEntity newEntity() {
return new JobPostEntity();
}
}
As for the select option to work, I'd also put that field in the modelAttribute, so you don't have to treat them separately:
public class JobPostEntity {
private String jobtitle;
private String jobcompany;
private String jobtext;
private String selectCategory;
//getters/setters
}
Your pasted html code also contains a few issues:
you don't have the opening tags for form
the select tag doesn't have thymeleaf mapping for it (th:field)
the input tags doesn't have closing elements
The fixed version, which works for me, looks something like this (excluding the body/head/etc wrapper tags):
<form th:action="#{/newjob}" th:object="${addNewJob}" method="post">
<div class="form-group">
<label for="">Offer Title</label>
<input type="text" th:field="*{jobtitle}" class="form-control" placeholder="Entre Offer Title" />
<small class="form-text text-muted">We'll never share your email
with anyone else.</small>
</div>
<div class="form-group">
<label >Company Name</label>
<input type="text" th:field="*{jobcompany}" class="form-control" placeholder="Enter Company Name"/>
</div>
<div class="form-group dropdown">
<label for="sel1">Choose Category (select one):</label>
<select name="*selectCategory"
class="form-control" id="selectCategory"
onchange="getSelectedValue();"
th:field="*{selectCategory}">
<option value="">Select Option</option>
<option value="software_engineer">Software Engineer</option>
<option value="graphic_design ">Graphic Design</option>
<option value="customer_service ">Customer Service</option>
<option value="marketing" >Marketing</option>
<option value="healthcare">Health Care</option>
</select>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Offer</label>
<textarea class="form-control" th:field="*{jobtext}" placeholder="Describe your job offer"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit Offer</button>
</form>
if you start your application and type http://localhost:8080/test (if you use the default context path / port ) in your browser, the form should appear and work as expected.
also, you can find a pretty good tutorial on here http://www.baeldung.com/thymeleaf-in-spring-mvc

How to hold filter parameters. Pagination

I have some problem with search filter and pagination. Filter works good, but i can't say the same about pagination.
I have a table with users. I can show all users or by filter(by name, by email). When i'm using filter and trying to go to second page, it return all users without filtration. I understand why it happens, because has no filter parameters. Help me find solution. How can i hold selected filters? Something with sessions?
Here my code.
My Controller
#Controller
#RequestMapping(value = "/admin")
public class AdminController {
#Autowired
UserService userService;
#RequestMapping(value = "/edit-user", method = RequestMethod.GET)
public ModelAndView editUsers(#RequestParam(value = "page", defaultValue = "0") Integer page,
#RequestParam(value = "pattern", required = false) String pattern,
#RequestParam(value = "category", required = false) String category) {
ModelAndView view = new ModelAndView("edit-user");
if(pattern == null){
Page<User> userList = userService.findAll(page);
view.addObject("userList", userList.getContent()).addObject("maxPage", userList.getTotalPages());
}else if(category.equals("username")){
Page<User> userList = userService.findByUsernameContaining(pattern, page);
view.addObject("userList", userList.getContent()).addObject("maxPage", userList.getTotalPages());
}else {
Page<User> userList = userService.findByEmailContaining(pattern, page);
view.addObject("userList", userList.getContent()).addObject("maxPage", userList.getTotalPages());
}
return view;
}
}
My part of JSP
<div class="row top-buffer">
<div class="col-md-4 col-md-offset-4">
<form class="form-inline text-center" role="form" method="get" action="/admin/edit-user?pattern=pattern?category=category">
<fieldset>
<!-- Search Name -->
<div class="form-group">
<label class="sr-only" for="item-name">Product Name</label>
<input id="item-name" name="pattern" placeholder="..." class="form-control">
</div>
<!-- Search Category -->
<div class="form-group">
<label class="sr-only" for="item-category">Product Category</label>
<select id="item-category" name="category" class="form-control">
<option value="username" selected>By username</option>
<option value="email">By email</option>
</select>
</div>
<!-- Search Action -->
<div class="form-group">
<button type="submit" class="btn btn-primary"><span
class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
</div>
</fieldset>
</form>
</div>
</div>
<div class="row top-buffer">
<div class="col-md-8 col-md-offset-2">
<table class="table">
<thead>
<th>Id</th>
<th>Username</th>
<th>Email</th>
<th>Password</th>
</thead>
<c:forEach var="user" items="${userList}">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.email}</td>
<td>${user.password}</td>
<td>
<button type="button" class="btn btn-info btn-sm editButton" data-toggle="modal"
data-target="#myModal" data-id="${user.id}">Edit
</button>
</td>
</tr>
</c:forEach>
</table>
</div>
</div>
<div class="row">
<div class="col-md-4 pull-right">
<ul class="pagination">
<c:forEach begin="0" end="${maxPage - 1}" var="i">
<li>${i+1}</li>
</c:forEach>
</ul>
</div>
</div>
In your case, putting filter information in session should be OK. You can create a Filter enum that has e.g. name, email fields. Store/update a Filter instance in session every time user wants to filter something.
You can attach your filters to your link(page number in your case) as a query string like so:
${i+1}
In your controller, you need to get the filter information and handle it accordingly (get the value of param filterby, which is name or email). If the filterby param has no value, then no filter is chosen.

print an arraylist while passing it from a controller to a jsp

hi i am trying to print the contents of an arraylist in a jsp
here is the controller code
#RequestMapping(value = "/deleteFilter", method = RequestMethod.GET)
public String deleteFilter(FilterValues filterData,ModelMap modalMap) {
logger.info("delete a filter");
ArrayList<String> filtername= mongoService.getTargetFiltersName();
modalMap.addAttribute("filterslist", filtername);
return "delete";
}
and here is the part of the jsp where i have to print it
<div class="col-xs-4">
<label for="pwd">Filter Name:</label>
<select type="Filter Name" class="form-control" id="pwd" placeholder="Enter Filter Name">
<c:forEach items="${filterslist}" var="filtername">
<option value="${filtername.value}">${filtername.value}</option>
</c:forEach>
</select>
</div>
its giving me errors
thanks in advance
i think you should use the following code as you are iterating on an ArrayList of String
<div class="col-xs-4">
<label for="pwd">Filter Name:</label>
<select type="Filter Name" class="form-control" id="pwd" placeholder="Enter Filter Name">
<c:forEach items="${filterslist}" var="filtername">
<option value="${filtername}">${filtername}</option>
</c:forEach>
</select>
</div>

Categories