Reputation: 434
I am creating a Spring Boot JPA application with Thymeleaf templates in the front end. The application is used to manage a set of user skills which are organised into categories.
I need to create a cascading dropdown in a form where a category (e.g. Programming Languages, Admin, Project Management) is selected from a first dropdown and then a second dropdown displays the skills associated with that category. So if 'Programming Languages' was selected in the first dropdown, the options in the second dropdown box may be Java, Python, C++, etc. for example. This form will eventually be used to perform a search of users that have those skills.
In my controller, I create a map where the key is the category as a String and the value is a list of associated skills, where the Skill class is a Java data object containing the skill name and id: -
Map<String, List<Skill>> skillsMap = new HashMap();
I populate this map with all the category and skill information and add it to my Model. It contains all the info that will be required in the form: -
model.addAttribute("skillsMap", skillsMap);
In my view within a Thymeleaf template, I then retrieve this map from the model and start to build a form with it. This select successfully displays the categories: -
<select id="category">
<option value="NONE">----Select----</option>
<option th:each="entry : ${skillsMap.entrySet()}" th:value="${entry.key}"
th:text="${entry.key}">
</option>
</select>
The behaviour I want is that after I have made the category selection in the first dropdown, a second dropdown is then displayed with the skills from that category as options.
To achieve this, I have attempted to capture the value of the category dropdown in a JavaScript variable. This is in a script section at the bottom of the template below the form: -
<script>
$(document).ready(function() {
$("#category").change(function() {
var cat = $("#category").val();
});
});
</script>
I reference the value of this variable 'cat' in a second select field: -
<select id="skill">
<option value="NONE">----Select----</option>
<option th:each="skill : ${skillsMap.get(cat)}" th:value="${skill.id}"
th:text="${skill.name}">
</option>
</select>
This is not yet working and the second dropdown remains unpopulated.
When I hard-code the second dropdown with an actual category value, Admin in this case, it displays the values as expected:
<select id="skill">
<option value="NONE">----Select----</option>
<option th:each="skill : ${skillsMap.get('Admin')}" th:value="${skill.id}"
th:text="${skill.name}">
</option>
</select>
I therefore know that it is the way I am trying to set and reference the 'cat' variable where the issue lies. Of all the technologies used in this project, the JavaScript/JQuery side of things is by far my weakest and I am not sure if what I am trying to do is fundamentally the wrong approach or if I just have some syntax issues. I would be extremely grateful if anyone could point me in the right direction!
Upvotes: 0
Views: 1265
Reputation: 1493
var data = {
skill1: ['a', 'b'],
skill2: ['c'],
skill3: ['d']
}
$(document).ready(function() {
$("#category").change(function() {
var skill = $("#category").val();
var optionList = "";
var skillList = data[skill];
for (var i = 0; i < skillList.length; i++) {
optionList += "<option value=" + skillList[i] + ">" + skillList[i] + "</option>";
}
$("#skill").html(optionList);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="category">
<option value="skill1">skill1</option>
<option value="skill2">skill2</option>
<option value="skill3">skill3</option>
</select>
<select id="skill">
</select>
You can replace all options with the .html()
method for the second select when the first select changes.
Upvotes: 1