1. Introduction
In this article, we are going to present the Thymeleaf Input Email component that checks the correctness of the provided email address on the browser level. The component comes with many built-in features. We can use the pattern
attribute to set a regular expression the input's contents must match in order to be valid, or multiple
parameter to allow many comma-separated e-mail addresses to be entered.
Follow below links to find more useful informations about Thymeleaf and Thymeleaf Forms:
Thymeleaf Posts
Building forms in Thymeleaf
2. Dependencies
2.1. Maven dependencies
To present how the Input Email component works with Thymeleaf we used a simple Spring Boot application created as a Maven project with the following dependencies:
2.2. Front-End libraries
bootstrap - a frontend framework for creating responsive websites.
Project Maven pom.xml
file has the following structure:
Copy
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>thymeleaf-bootstrap-input-email</artifactId>
<properties>
<bootstrap.version>4.0.0-2</bootstrap.version>
<webjars-locator.version>0.30</webjars-locator.version>
<lombok.version>1.18.2</lombok.version>
<font-awesome.version>5.11.2</font-awesome.version>
</properties>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>${webjars-locator.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>font-awesome</artifactId>
<version>${font-awesome.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. Model, Controller, and Main Application class
The model layer contains one class Form
with the following structure:
Copy
package com.frontbackend.thymeleaf.bootstrap.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@NoArgsConstructor
public class Form {
private String email;
}
GET and POST requests on the root context are handled by a simple Spring Web Controller IndexController
with the following structure:
Copy
package com.frontbackend.thymeleaf.bootstrap.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.frontbackend.thymeleaf.bootstrap.model.Form;
@Controller
@RequestMapping({ "/", "/index" })
public class IndexController {
@GetMapping
public String main(Model model) {
model.addAttribute("form", new Form());
return "index";
}
@PostMapping
public String save(Form form, Model model) {
model.addAttribute("form", form);
return "saved";
}
}
The Application
is the Java class with the main method that starts the Spring Boot application server:
Copy
package com.frontbackend.thymeleaf.bootstrap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4. Templates
The presentation layer contains two Thymeleaf templates:
index.html - a view that presents the input email component,
saved.html - the result view that presents provided email address.
The index.html
template has the following structure:
Copy
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Spring Boot Thymeleaf Application - Bootstrap Input Email</title>
<link th:rel="stylesheet" th:href="@{webjars/bootstrap/4.0.0-2/css/bootstrap.min.css} "/>
<link th:rel="stylesheet" th:href="@{webjars/font-awesome/5.11.2/css/all.css} "/>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
<div class="container">
<a class="navbar-brand" href="/">Thymeleaf - Bootstrap Input Email</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Services</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<form method="post" th:object="${form}">
<div class="form-group row">
<div class="col-md-4 mt-5">
<label for="birthdate">Email address</label>
<div class="input-group">
<input type="email" class="form-control" id="birthdate" autocomplete="off" th:field="*{email}"/>
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-at"></i></span>
</div>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
</div>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/popper.js/umd/popper.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</body>
</html>
To present the submitted values we used the saved.html
template with the following structure:
Copy
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Spring Boot Thymeleaf Application - Bootstrap Input Email</title>
<link th:rel="stylesheet" th:href="@{webjars/bootstrap/4.0.0-2/css/bootstrap.min.css} "/>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
<div class="container">
<a class="navbar-brand" href="/">Thymeleaf - Bootstrap Input Email</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive"
aria-controls="navbarResponsive"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Services</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<h2 class="mt-5">Email address: <strong th:text="${form.email}"></strong></h2>
<a th:href="@{/}" class="btn btn-primary">Go back</a>
</div>
</body>
</html>
5. The output
The running application is available under http://locahost:8080
URL and presents the following functionality:
6. Conclusion
In this article, we presented the Thymeleaf Input Email component in a simple Spring Boot application. Using the built-in component to enter an email address has many advantages. With this approach we are dependency-free. Input email components are supported by all browsers and come with many additional features.
As usual, the code used in this article is available under our GitHub repository .
{{ 'Comments (%count%)' | trans {count:count} }}
{{ 'Comments are closed.' | trans }}