Spring Boot + Bootstrap + Thymeleaf Color Picker

April 18, 2020 No comments Spring Boot Bootstrap Thymeleaf Input Color Picker

Spring Boot + Bootstrap + Thymeleaf Color Picker

1. Introduction

In this article, we are going to present Thymeleaf Color Picker component that allows you to select a color in RGB, HEX and HSL format.

Searching for more information about Thymeleaf? please check the following links:
Thymeleaf Articles
Forms in Thymeleaf

2. Dependencies

2.1. Maven dependencies

The sample Spring Boot application used in this article is a Maven project with three common dependencies:

2.2. Front-End libraries
  • bootstrap - a frontend framework for creating responsive websites.
  • bootstrap-colorpicker - JavaScript library for creating awesome color picker components.

Maven pom.xml file have the following structure:

<?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-color-picker</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

In model layer we have a single object Colors with three fields: hex, rgb, hsl. This class will be used as a main Thymeleaf form object:

package com.frontbackend.thymeleaf.bootstrap.model;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@NoArgsConstructor
public class Colors {

    private String hex;

    private String rgb;

    private String hsl;

}

GET and POST request to root context / and /index path are handled by Spring Web Controller class formed with the following structure:

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.Colors;

@Controller
@RequestMapping({ "/", "/index" })
public class IndexController {

    @GetMapping
    public String main(Model model) {
        Colors colors = new Colors();
        colors.setHex("#AD9597");
        model.addAttribute("colors", colors);
        return "index";
    }

    @PostMapping
    public String save(Colors colors, Model model) {
        model.addAttribute("colors", colors);
        return "saved";
    }
}

The Application is the Java class with the main method that starts the Spring Boot application server:

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 views:

  • index.html - the view for presenting color picker component,
  • saved.html - this view is used to present the submitted values.

The index.html template has the following structure:

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Spring Boot Thymeleaf Application - Bootstrap Color Picker</title>

    <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/4.0.0-2/css/bootstrap.min.css} "/>
    <link th:rel="stylesheet" th:href="@{/assets/bootstrap-colorpicker/css/bootstrap-colorpicker.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 Color Picker</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-sm-5 mt-5">
            <form method="post" th:object="${colors}">

                <div class="form-group">
                    <div id="cp2" class="input-group" title="Using input value">
                        <input type="text" class="form-control input-lg" th:field="*{hex}"/>
                        <span class="input-group-append">
                    <span class="input-group-text colorpicker-input-addon"><i></i></span>
                  </span>
                    </div>
                </div>

                <div class="form-group">
                    <div id="cp3a" class="input-group" data-color="rgb(241, 138, 49)"
                         title="Using data-color attribute in the colorpicker element">
                        <input type="text" class="form-control input-lg" th:field="*{rgb}"/>
                        <span class="input-group-append">
                    <span class="input-group-text colorpicker-input-addon"><i></i></span>
                  </span>
                    </div>
                </div>

                <div class="form-group">
                    <div id="cp3b" class="input-group" title="Using data-color attribute in the input">
                        <input type="text" class="form-control input-lg" data-color="hsl(56, 93%, 63%)"
                               th:field="*{hsl}"/>
                        <span class=" input-group-append">
                    <span class="input-group-text colorpicker-input-addon"><i></i></span>
                    </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-colorpicker/js/bootstrap-colorpicker.js}"></script>

<script>
    $(function () {
        $('#cp2, #cp3a, #cp3b').colorpicker();
    });
</script>

</body>
</html>

We used external JavaScript plugin for creating Color Picker components: https://github.com/itsjavi/bootstrap-colorpicker. It allows you to select color in a three different format (RGB, HSL, HEX) and gives you ability to add favorite colors to the browser memory.

To initialize bootstrap-colorpicker library we used below code:

$('#cp2, #cp3a, #cp3b').colorpicker();

The saved.html template has the following structure:

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Spring Boot Thymeleaf Application - Bootstrap Color Picker</title>

    <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/4.0.0-2/css/bootstrap.min.css} "/>
    <link th:rel="stylesheet" th:href="@{/assets/prism/prism.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 Color Picker</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-sm-12 mt-5 mb-5">
            <div class="mt-2">Hex: <strong th:text="${colors.hex}"></strong></div>
            <div class="mt-2">RGB: <strong th:text="${colors.rgb}"></strong></div>
            <div class="mt-2">HSL: <strong th:text="${colors.hsl}"></strong></div>
        </div>
    </div>

    <a th:href="@{/}" class="btn btn-primary">Go back</a>
</div>

<script th:src="@{/assets/prism/prism.js}"></script>

</body>
</html>

5. The output

The running application is available under http://locahost:8080 URL and presents the following functionality:

Thymeleaf bootstrap color picker

6. Conclusion

In this article, we presented Thymeleaf Color Picker component. You can use it to select the color using Thymeleaf forms. Even though HTML5 already provides a component for color selection but it is not as rich in functionality as the one we chose.

As usual, the code used in this article is available under our GitHub repository.

{{ message }}

{{ 'Comments are closed.' | trans }}