Working with Select and Option in Thymeleaf

1. Overview

Thymeleaf is the very popular templating engine bundled together with Spring Boot. We’ve already published a number of articles about it, and we highly recommend going over the Baeldung’s Thymeleaf series.

In this tutorial, we’re going to look at how to work with select and option tags in Thymeleaf.

2. HTML Basics

In HTML we can build a drop-down list with multiple values:

<select>
    <option value="apple">Apple</option>
    <option value="banana">Banana</option>
    <option value="orange">Orange</option>
    <option value="pear">Pear</option>
</select>

Each list consists of select and nested option tags. By default, the web browser will render a list with the first option preselected.

We can control which value is selected by using selected attribute:

<option value="orange" selected>Orange</option>

Moreover, we can specify that an option isn’t selectable by using the disabled attribute:

<option disabled>Please select...</option>

3. Thymeleaf

In Thymleaf we can use th:field attribute to bind the view with the model:

<select th:field="*{gender}">
    <option th:value="'M'" th:text="Male"></option>
    <option th:value="'F'" th:text="Female"></option>
</select>

While the above example doesn’t really require using a template engine, in more advanced examples to follow we’ll see the power of Thymeleaf.

3.1. Option Without Selection

If we think about a scenario in which there are more options to choose from, a clean and neat way to display all of them is by using th:each attribute together with th:value and th:text:

<select th:field="*{percentage}">
    <option th:each="i : ${#numbers.sequence(0, 100)}" th:value="${i}" th:text="${i}">
    </option>
</select>

In the above example, we’re using a sequence of numbers from 0 to 100. We assign the value of each number i to option tag’s value attribute, and we use the same number as the displayed value.

The Thymeleaf code will be rendered in the browser as:

<select id="percentage" name="percentage">
    <option value="0">0</option>
    <option value="1">1</option>
    <option value="2">2</option>
    ...
    <option value="100">100</option>
</select>

Let’s think about this example as create, i.e., we start with a new form, and the percentage value didn’t need to be preselected.

3.2. Selected Option

If we want to expand our form now with an update functionality, i.e., we go back to the previously created record, and we want to populate the form with existing data, then the option needs to be selected.

We can achieve that by adding th:selected attribute along with some condition:

<select th:field="*{percentage}">
    <option th:each="i : ${#numbers.sequence(0, 100)}" th:value="${i}" th:text="${i}"
      th:selected="${i==75}"></option>
</select>

In the above example, we want to preselect the value of 75 by checking if i is equal to 75.

However, this code won’t work, and the rendered HTML will be:

<select id="percentage" name="percentage">
    <option value="0">0</option>
    ...
    <option value="74">74</option>
    <option value="75">75</option>
    <option value="76">76</option>
    ...
    <option value="100">100</option>
</select>

To fix it, we need to remove th:field and replace it with name and id attributes:

<select id="percentage" name="percentage">

In the end, we will get:

<select id="percentage" name="percentage">
    <option value="0">0</option>
    ...
    <option value="74">74</option>
    <option value="75" selected="selected">75</option>
    <option value="76">76</option>
    ...
    <option value="100">100</option>
</select>

4. Conclusion

In this short article, we’ve checked how to work with drop-down/list selectors in Thymeleaf. There is one common pitfall with preselecting values, which we’ve shown the solution for.

As always, the code used during the discussion can be found over on GitHub.

Leave a Reply

Your email address will not be published.