1. Introduction
In this article, we will present the Thymeleaf Switch component that allows selecting true/false values in Thymeleaf forms .
Looking for more useful informations about Thymeleaf? check the following articles:
Thymeleaf Tutorials
Forms in Thymeleaf
2. Dependencies
2.1. Maven dependencies
To present how the Switch component works with Thymeleaf we used a simple Spring Boot application created as a Maven project where we used the following dependencies:
2.2. Front-End libraries
bootstrap - a frontend framework for creating responsive websites,
bootstrap-switch - a JavaScript library for creating switch components.
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-switch</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>
</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.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 a single class that will store known languages as boolean fields:
Copy
package com.frontbackend.thymeleaf.bootstrap.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@NoArgsConstructor
public class KnownLanguages {
private boolean java;
private boolean css;
private boolean angular;
private boolean react;
private boolean python;
private boolean go;
}
GET and POST requests on the root context are handled by a simple Spring Web Controller 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.KnownLanguages;
@Controller
@RequestMapping({ "/", "/index" })
public class IndexController {
@GetMapping
public String main(Model model) {
model.addAttribute("languages", new KnownLanguages());
return "index";
}
@PostMapping
public String save(KnownLanguages skills, Model model) {
model.addAttribute("languages", skills);
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 switch component with options to select,
saved.html - the result view that presents selected known languages.
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 Switch</title>
<link th:rel="stylesheet" th:href="@{assets/bootstrap-switch/bootstrap-switch.min.css}"/>
<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 Switch</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">
<div class="row">
<div class="col">
<h2 class="mt-5">Known languages</h2>
<form method="post" th:object="${languages}">
<div class="ml-2">
<div class="form-group mt-3">
<span class="ml-2">JAVA <input type="checkbox" th:field="*{java}" data-toggle="switch"/></span>
</div>
<div class="form-group mt-3">
<span class="ml-2">CSS <input type="checkbox" th:field="*{css}" data-toggle="switch"/></span>
</div>
<div class="form-group mt-3">
<span class="ml-2">Angular <input type="checkbox" th:field="*{angular}" data-toggle="switch"/></span>
</div>
<div class="form-group mt-3">
<span class="ml-2">Python <input type="checkbox" th:field="*{python}" data-toggle="switch"/></span>
</div>
<div class="form-group mt-3">
<span class="ml-2">React <input type="checkbox" th:field="*{react}" data-toggle="switch"/></span>
</div>
<div class="form-group mt-3">
<span class="ml-2">Go <input type="checkbox" th:field="*{go}" data-toggle="switch"/></span>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
</div>
</div>
</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>
<script th:src="@{assets/bootstrap-switch/bootstrap-switch.min.js}"></script>
<script>
$('[data-toggle="switch"]').bootstrapSwitch();
</script>
</body>
</html>
The custom switch components were built using external JavaScript library bootstrap-switch
: https://github.com/Bttstrp/bootstrap-switch .
To initialize the library we used the following JavaScript code:
Copy
$('[data-toggle="switch"]').bootstrapSwitch();
The saved.html
file 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 Switch</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 Switch</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">Known languages</h2>
<p>JAVA: <strong class="badge" th:text="${languages.java}"
th:classappend="${languages.java ? 'badge-success' : 'badge-secondary'}"></strong>
</p>
<p>CSS: <strong class="badge" th:text="${languages.css}"
th:classappend="${languages.css ? 'badge-success' : 'badge-secondary'}"></strong>
</p>
<p>Angular: <strong class="badge" th:text="${languages.angular}"
th:classappend="${languages.angular ? 'badge-success' : 'badge-secondary'}"></strong>
</p>
<p>Python: <strong class="badge" th:text="${languages.python}"
th:classappend="${languages.python ? 'badge-success' : 'badge-secondary'}"></strong>
</p>
<p>React: <strong class="badge" th:text="${languages.react}"
th:classappend="${languages.react ? 'badge-success' : 'badge-secondary'}"></strong>
</p>
<p>Go: <strong class="badge" th:text="${languages.go}"
th:classappend="${languages.go ? 'badge-success' : 'badge-secondary'}"></strong>
</p>
<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 Switch component. Switches are used to let the user select one or more options for a limited number of choices. This article covers how we can use that component with the Thymeleaf template engine.
As usual, the code used in this article is available under our GitHub repository .
{{ 'Comments (%count%)' | trans {count:count} }}
{{ 'Comments are closed.' | trans }}