'Dynamic dropdowns using thymeleaf, spring boot
I have 3 dropdowns(one is populate with cities, one with agencies and one with services). If I select one city, the second dropdown should load the data(agencies), and if i select one agency, the 3 dropdown should load data(services). I am able to populate the first dropdown(cities), but I don't know how to populate the second and third.
Should i write a controller for each dropdown and return the value? If the answer is yes, how can I return the value? I've read that Thymeleaf is not a component technology but a template technology like JSP. So there is not components or built-in mechanism in Thymeleaf to do client-server communication. So I need to program that communication using plain old HTML forms or using AJAX calls. How can I program it using plain old HTML?
I tried using forms, but I click submit only once, it is not what I need. I read the posts about dropdowns, but couldn't find anything helpful. I saw that the easy way is to use jQuery, but I don't know jQuery. Is there a way I can do this using only thymeleaf and spring boot? Thanks! I will post my code below.
appointment.html
<form th:action="@{/appointment/create}" method="post" id="appointmentForm">
<input type="hidden" name="id" th:value="${appointment.id}"/>
<div class="form-group">
<label for="location">Alege orasul:</label>
<select class="form-control" required="required"
th:value="${appointment.location}" name="location" id="location">
<option disabled="disabled" selected="selected" > --
alege orasul --</option>
<option th:each="city : ${cities}" th:value="${city.id}"
th:text="${city.name}" ></option>
</select>
</div>
</form>
<form th:action="@{/appointment/agency}" method="post" id="appointmentForm">
<input type="hidden" name="id" th:value="${appointment.id}"/>
<div class="form-group">
<label for="location">Alege agentia:</label>
<select class="form-control" th:value="${appointment.agency}" name="agency" id="agency" required="required">
<option disabled="disabled" selected="selected" > -- alege agentia --</option>
<option th:each="agency : ${agencies}" th:value="${agency.id}" th:text="${agency.name}" ></option>
</select>
</div>
</form>
<form th:action="@{/appointment/service}" method="post" id="appointmentForm">
<input type="hidden" name="id" th:value="${appointment.id}"/>
<div class="form-group">
<label for="location">Alege serviciul:</label>
<select class="form-control" th:value="${appointment.service}" name="service" id="service" required="required">
<option disabled="disabled" selected="selected" > -- alege serviciul --</option>
<option th:each="service : ${services}" th:value="${service.id}" th:text="${service.name}" ></option>
</select>
</div>
</form>
AppController.java
@Controller
@RequestMapping("/appointment")
public class AppointmentController {
@Autowired
UserService userService;
AppointmentService appointmentService;
CityService cityService;
AgencyService agencyService;
SerService serService;
private ModelAndView mav;
@RequestMapping(value="/create", method=RequestMethod.GET)
public String createAppointmentPost(Model model, @ModelAttribute("city") City
city, @ModelAttribute("agency") Agency agency){
Appointment appointment=new Appointment();
model.addAttribute("appointment", appointment);
model.addAttribute("dateString", "");
model.addAttribute("cities", cityService.findAll());
//getAllAgencies(model, city);
getAllServices(model,agency);
return "appointment";
}
@RequestMapping(value="/agency", method=RequestMethod.GET)
public String getAllAgencies(Model model, @ModelAttribute("city") City city){
model.addAttribute("agencies", agencyService.listAllAgencies(city));
return "redirect:/appointment/create";
}
public void getAllServices(Model model, @ModelAttribute("agency") Agency
agency){
if(agency==null){
return;
}
model.addAttribute("services", serService.listAllServices(agency));
}
Solution 1:[1]
So I was able solving this using jQuery.
Here is a useful link: http://www.rockhoppertech.com/blog/spring-mvc-3-cascading-selects-using-jquery/ I will post my code below, maybe will help someone
-mycontroller
@RequestMapping(value="/create", method=RequestMethod.GET)
public String createAppointmentPost(Model model, @ModelAttribute("city") City
city,
@ModelAttribute("agency") Agency agency){
Appointment appointment=new Appointment();
model.addAttribute("appointment", appointment);
model.addAttribute("dateString", "");
model.addAttribute("cities", cityService.findAll());
return "appointment";
}
@RequestMapping(value = "/agencies", method = RequestMethod.GET)
public @ResponseBody
List<Agency> findAllAgencies(
@RequestParam(value = "cityId", required = true) Long cityId) {
City city = cityService.findCity(cityId);
return agencyService.listAllAgencies(city);
}
-thymeleaf
<div class="form-group">
<label for="location">Alege orasul:</label>
<select class="form-control" required="required"
th:value="${appointment.location}" name="location" id="location">
<option disabled="disabled" selected="selected" > --
alege orasul --
</option>
<option th:each="city : ${cities}" th:value="${city.id}"
th:text="${city.name}" >
</option>
</select>
</div>
<div class="form-group">
<label for="location">Alege agentia:</label>
<select class="form-control" th:value="${appointment.agency}"
name="agency" id="agency" required="required">
<option disabled="disabled" selected="selected" > --alege
agentia --</option>
</select>
</div>
jQuery- for one dropdown
$('#location').change(
function() {
$.getJSON("http://localhost:8181/appointment/agencies", {
cityId : $(this).val(),
ajax : 'true'
}, function(data) {
var html = '<option value="">--alege agentia--</option>';
var len = data.length;
for ( var i = 0; i < len; i++) {
html += '<option value="' + data[i].nume + '">'
+ data[i].nume + '</option>';
}
html += '</option>';
$('#agency').html(html);
});
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | agata |