Labs ICT
Pro Login

Validation Display

Showing validation errors with th:errorclass.

Validation Display in Thymeleaf

When form data is invalid, you need to show users what went wrong. Thymeleaf provides powerful tools for displaying validation errors with clean styling.

Adding Error Styling with th:errorclass

The th:errorclass attribute adds a CSS class to an input when it has an error. This makes it easy to highlight invalid fields.


<input type="text" th:field="*{name}" th:errorclass="is-invalid"/>
    

When the name field has an error, the input gets the class is-invalid. With Bootstrap, that automatically turns the border red.

Checking for Errors with #fields

Use the #fields utility to check if specific fields have errors. This lets you conditionally show error messages.


<div th:if="${#fields.hasErrors('name')}" class="error">
    <p th:text="${#fields.errors('name')}"></p>
</div>
<input type="text" th:field="*{name}" th:errorclass="is-invalid"/>
    

#fields.hasErrors('name') returns true if the name field failed validation. #fields.errors('name') returns the error message.

Bootstrap Error Styling

Combine th:errorclass with Bootstrap's validation classes for professional-looking error states.


<form th:action="@{/submit}" th:object="${user}" method="post">
    <div class="mb-3">
        <label for="name" class="form-label">Name</label>
        <input type="text" id="name" th:field="*{name}"
               th:errorclass="is-invalid" class="form-control"/>
        <div th:if="${#fields.hasErrors('name')}" class="invalid-feedback">
            <p th:each="error : ${#fields.errors('name')}" th:text="${error}"></p>
        </div>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>
    

The invalid-feedback div only appears when there are errors. Using th:each handles multiple error messages for the same field.

Try it Yourself →

Global Errors

Sometimes errors aren't tied to a specific field. Use #fields.globalErrors() to display them.


<div th:if="${#fields.hasGlobalErrors()}" class="alert alert-danger">
    <p th:each="error : ${#fields.globalErrors()}" th:text="${error}"></p>
</div>
    

Global errors show up as a general alert at the top of the form. They're useful for things like "login failed" or "account locked."

The Controller with Validation

Your controller needs @Valid to trigger validation. Errors go into the BindingResult.


@PostMapping("/submit")
public String handleSubmit(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "form";
    }
    return "success";
}
    

When errors exist, you return the form view so Thymeleaf can display them. Without @Valid, validation never runs.