Open In App

Event Registration System using Spring Boot

Last Updated : 15 May, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Event Registration System plays an important role in the Event Management Business for tracking the Event related details and also we can adjust our time table also according to the events data. In this Article we will explain about the Event Registration System is works with a good example with related output images. First we create a beautiful home page in this page we provide a welcome message and there are two buttons. The Get Started button is used for redirecting the Event Registration page to Book the Slot and other one is Booked Slots button which is used for view the all registered event details.

Here we use Thymeleaf is a java library which is used for handle the render the dynamic data by using the Spring MVC pattern in the this Application. And we gather below event details include ticket and payment details. The Event Registration fields are Event Name, Date and Time, Address, vent Organizer Name, Phone Number, Email, Ticket Type, Total Price, Ticket Price, Quantity, Payment Method.

Ticket & Payment Information:

  • Ticket Type
    • VIP
    • Student
    • General
  • Ticket Price
    • VIP - 500
    • Student - 100
    • General - 300
  • Payment Method
    • Credit Card
    • Debit Card
    • UPI
    • Online Banking

Prerequisites:

  • Spring Boot Framework
  • Thymeleaf
  • MongoDB
  • Spring MVC Pattern
  • Bootstrap Framework
  • Project Type is Gradle
  • Spring Tool Suite IDE (STS)

Gradle Dependencies:

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}


Spring Initializr:

Using Spring Initializr we will will create our project structure.

  • Here we have selected the Project type that is Gradle.
  • Then we filled the Metadata of the Project that are: Group Id, Artifact Id, Name, Description, Java version.
  • Also, we have added here all the required Gradle dependencies which we can see in the build.gradle file.


Spring Initializr



Project Folder Structure:

Folder Structure


Database Connection:

Here we use MongoDB as a database. And below we provide the database connection logic with thymeleaf configuration for handling html files which are located in the template in the resource folder. For the database connection, we need three attribute values that are Host name, Port number of MongoDB.

# database properties
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=eventdb

# thymeleaf configuration
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

Note: Here eventdb is the Database name, 27017 is the port number of MongoDB, and we have used Localhost for running the system.

Model Layer

Here we created one POJO class for handling database operation with repository interface. The POJO class name is EventRegistration and we used one dependency that is lombok which is available in Spring Boot. This is used for Parameterized and non-Parameterized constructors using @Data, @AllArgsConstructor, @NoArgsConstructor, @Document.

EventRegistration.java:

Java
package com.event.management.app.domain;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "eventdata")
public class EventRegistration {
    @Id
    private String id;
    private String eventName;
    private String dateTime;
    private String address;
    private String organizerName;
    private String phone;
    private String email;
    private String ticketType;
    private double ticketPrice;
    private int ticketQuantity;
    private double totalPrice;
    private String paymentMethod;
}


View Layer

In this layer, we have create a view by using HTML, CSS and Bootstrap 5. And we use Thymeleaf Java framework to integrate the both view layer and controller layer with help of the model layer. And The Thymeleaf provide dynamic rendering the application while any change in the controller layer and reflected on the view layer.

index.html:

HTML
<!DOCTYPE html>
<html>

<head>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
    <link rel="shortcut icon" href="https://cdn-icons-png.flaticon.com/512/2037/2037551.png">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <meta charset="UTF-8">
    <title>Event Registration System</title>
</head>

<style>
    .navbar-brand {
        color: white !important;
        font-weight: bold;
    }

    .heading1 {
        text-align: center;
        color: green;
        font-weight: 800;
        font-family: 'Courier New', Courier, monospace;
    }

    /* Step Progress Bar */
    .progressbar {
        margin-top: 3rem;
        margin-left: 50px;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-bottom: 2em;
    }

    .step {
        text-align: center;
        width: 100px;
        position: relative;
    }

    .step .circle {
        display: block;
        width: 30px;
        height: 30px;
        border-radius: 50%;
        background: #28a745;
        color: white;
        line-height: 30px;
        text-align: center;
    }

    .step .title {
        margin-top: 10px;
        margin-left: -70px;
        color: #333;
    }

    .step .line {
        position: absolute;
        top: 14px;
        left: 40px;
        height: 3px;
        width: calc(100% - 50px);
        background: #28a745;
    }

    .step:last-child .line {
        display: none;
    }
</style>

<body>
    <nav class="navbar navbar-expand-sm navbar-light bg-success">
        <div class="container">
            <a class="navbar-brand" href="#"><i class="fa fa-calendar" aria-hidden="true"></i> Event Registration System</a>
            <button class="navbar-toggler d-lg-none" type="button" data-bs-toggle="collapse"
                data-bs-target="#collapsibleNavId" aria-controls="collapsibleNavId" aria-expanded="false"
                aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
        </div>
    </nav>

    <main>
        <div class="container">
            <div class="data p-5 m-5">
                <h1 class="heading1">Welcome to Event Registration System</h1>
                                
                <br>
                <h5 class="text-center">
                    The “occasionally remarkable” moments shouldn't be left to chance! They should be planned for, invested in
                </h5>
                <br>
                <!-- Step Progress Bar -->
                <center>
                    <div class="progressbar">
                        <div class="step">
                            <span class="circle"><i class="fa fa-calendar" aria-hidden="true"></i></span>
                            <div class="line"></div>
                            <div class="title">Event</div>
                        </div>
                        <div class="step">
                            <span class="circle"><i class="fa fa-user" aria-hidden="true"></i></span>
                            <div class="line"></div>
                            <div class="title">Register</div>
                        </div>
                        <div class="step">
                            <span class="circle"><i class="fa fa-smile-o" aria-hidden="true"></i></span></span>
                            <div class="title">Celebrate</div>
                        </div>
                    </div>
                </center>
                <br>
                <center>
                    <a th:href="@{/register}" type="button" class="btn btn-success" style="text-decoration: none;">Get Started</a>
                    <a th:href="@{/dashboard}" type="button" class="btn btn-primary" style="text-decoration: none;">Booked Slots</a>
                </center>
                <br>
            </div>
        </div>
    </main>
</body>

</html>


In this HTML page, we provide a navbar and we provide two buttons on the Home page when click on the Get Started button you are redirect to Event Registration Form or you click on Booked Slots button, It will redirect to dashboard page to view all event registration details in the form of Table. Here we use Thymeleaf for rendering dynamic content.

Output:

Below is the Home Page of our Project.

Home Page


EventRegistration.html:

HTML
<!-- event-registration.html -->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
<meta charset="UTF-8">
<link
    href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
    rel="stylesheet">
<link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<link rel="shortcut icon"
    href="https://cdn-icons-png.flaticon.com/512/2037/2037551.png">
<script
    src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<title>Event Registration System</title>
</head>

<style>
.navbar-brand {
    color: white !important;
    font-weight: bold;
}

label {
    font-weight: 600;
    color: rgb(50, 49, 49);
    margin-bottom: 5px;
}
form{
    box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px;
}
</style>

<body>

    <nav class="navbar navbar-expand-sm navbar-light bg-success">
        <div class="container">
            <a class="navbar-brand" href="#"><i class="fa fa-calendar"
                aria-hidden="true"></i> Event Registration System</a>
        </div>
    </nav>

    <main>
        <div class="container">

            <!-- Display flash messages for success or error -->
            <div th:if="${success}" class="alert alert-success mt-3 alert-dismissible fade show" role="alert">
                <i class="fa fa-check-circle" aria-hidden="true"></i> <span
                    th:text="${success}"></span>
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>    
            </div>
            
            <div th:if="${error}" class="alert alert-danger mt-3 alert-dismissible fade show" role="alert">
                <i class="fa fa-exclamation-circle" aria-hidden="true"></i> <span
                    th:text="${error}"></span>
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>    
            </div>

            <div class="p-4 m-4">
                <!-- Use Thymeleaf form tag and set action to point to the controller -->
                <form th:action="@{/register}" method="post"
                    class="form-control p-5">
                    <h3 class="p-2 mb-5 text-center"
                        style="font-weight: bold; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: green;">Register
                        Your Event</h3>

                    <!-- Event & User Information -->
                    <div class="row g-3">
                        <h6 class="p-1 text-success" style="font-weight: bold;">Event
                            & User Information</h6>
                        <div class="col-sm-6">
                            <div class="mb-3">
                                <label>Event Name</label> <select
                                    class="form-control form-select" name="eventName" required>
                                    <option value="">Select an event</option>
                                    <option value="Event 1">Event 1</option>
                                    <option value="Event 2">Event 2</option>
                                    <option value="Event 3">Event 3</option>
                                    <option value="Event 4">Event 4</option>
                                    <option value="Event 5">Event 5</option>
                                </select>
                            </div>
                            <div class="mb-3">
                                <label><i class="fa fa-calendar" aria-hidden="true"></i>
                                    Date and Time</label> <input type="datetime-local" class="form-control"
                                    name="dateTime" required>
                            </div>
                            <div class="mb-3">
                                <label><i class="fa fa-location-arrow"
                                    aria-hidden="true"></i> Address</label>
                                <textarea rows="1" class="form-control" name="address"></textarea>
                            </div>
                        </div>
                        <div class="col-sm-6">
                            <div class="mb-3">
                                <label><i class="fa fa-user" aria-hidden="true"></i>
                                    Event Organizer Names</label> <input type="text" class="form-control"
                                    name="organizerName" required>
                            </div>
                            <div class="mb-3">
                                <label><i class="fa fa-phone" aria-hidden="true"></i>
                                    Phone Number</label> <input type="tel" class="form-control"
                                    name="phone" required>
                            </div>
                            <div class="mb-3">
                                <label><i class="fa fa-envelope" aria-hidden="true"></i>
                                    Email</label> <input type="email" class="form-control" name="email"
                                    required>
                            </div>
                        </div>
                    </div>

                    <!-- Ticket & Payment Information -->
                    <div class="row g-3 mt-3">
                        <h6 class="p-1 text-success" style="font-weight: bold;">Ticket
                            & Payment Information</h6>
                        <div class="col-sm-6">
                            <div class="mb-3">
                                <label><i class="fa fa-ticket" aria-hidden="true"></i>
                                    Ticket Type</label> <select class="form-control form-select"
                                    id="ticketType" name="ticketType" required>
                                    <option value="">Select Ticket</option>
                                    <option value="vip">VIP</option>
                                    <option value="general">General</option>
                                    <option value="student">Student</option>
                                </select>
                            </div>
                            <div class="mb-3">
                                <label>Ticket Price</label> <input type="number"
                                    class="form-control" id="ticketPrice" name="ticketPrice"
                                    readonly>
                            </div>
                            <div class="mb-3">
                                <label>Quantity</label> <input type="number"
                                    class="form-control" id="ticketQuantity" name="ticketQuantity"
                                    required>
                            </div>
                        </div>
                        <div class="col-sm-6">
                            <div class="mb-3">
                                <label>Total Price</label> <input type="number"
                                    class="form-control" id="totalPrice" name="totalPrice" readonly>
                            </div>
                            <div class="mb-3">
                                <label>Payment Method</label> <select
                                    class="form-control form-select" name="paymentMethod" required>
                                    <option value="">Select Payment Method</option>
                                    <option value="creditcard">Credit Card</option>
                                    <option value="debitcard">Debit card</option>
                                    <option value="upi">UPI</option>
                                    <option value="banking">Online Banking</option>
                                </select>
                            </div>
                        </div>
                    </div>

                    <button class="btn btn-success mt-3" type="submit">Book
                        Event Slot</button>
                </form>

            </div>
        </div>
    </main>

    <!-- Include your JavaScript logic for updating prices -->
    <script>
        const ticketPrices = {
            "vip": 500,
            "general": 300,
            "student": 100
        };

        const ticketTypeSelect = document.getElementById("ticketType");
        const ticketQuantityInput = document.getElementById("ticketQuantity");
        const ticketPriceInput = document.getElementById("ticketPrice");
        const totalPriceInput = document.getElementById("totalPrice");

        function updatePrices() {
            const ticketType = ticketTypeSelect.value;
            const quantity = parseInt(ticketQuantityInput.value) || 0;

            if (ticketType in ticketPrices) {
                const ticketPrice = ticketPrices[ticketType];
                ticketPriceInput.value = ticketPrice;
            } else {
                ticketPriceInput.value = "";
            }

            if (ticketPriceInput.value && quantity > 0) {
                const total = quantity * parseInt(ticketPriceInput.value);
                totalPriceInput.value = total;
            } else {
                totalPriceInput.value = "";
            }
        }

        ticketTypeSelect.addEventListener("change", updatePrices);
        ticketQuantityInput.addEventListener("input", updatePrices);
    </script>
</body>

</html>


The above HTML code describes the Event Registration Form and this form contains different fields and we divided into two categories namely Event & User Information and Ticket & Payment Information. You can observe this in the below image and it gives the entire view of the Event Registration. Here by the help of Thymeleaf we insert the form data into MongoDB by using EventRegistration.java POJO class.

Note: Here we have used java script for handling total ticker price and display ticket price based on the Ticker selection like VIP, Student, General And we provide payment mode also.

Output:

Below is the interface of Event and User Information, where we can register our event.

Event Registration Form


dashboard.html:

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
    <link rel="shortcut icon" href="https://cdn-icons-png.flaticon.com/512/2037/2037551.png">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <title>Event Registration System</title>
</head>

<style>
    .navbar-brand {
        color: white !important;
        font-weight: bold;
    }
    table{
        box-shadow: rgba(0, 0, 0, 0.02) 0px 1px 3px 0px, rgba(27, 31, 35, 0.15) 0px 0px 0px 1px;
    }
</style>

<body>
    <nav class="navbar navbar-expand-sm navbar-light bg-success">
        <div class="container">
            <a class="navbar-brand" href="#"><i class="fa fa-calendar" aria-hidden="true"></i> Event Registration System</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                data-bs-target="#collapsibleNavId" aria-controls="collapsibleNavId" aria-expanded="false"
                aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
        </div>
    </nav>

    <main>
        <div class="container-fluid">
            <div class="table-responsive mt-5">
                <table class="table table-bordered">
                    <thead class="bg-success text-white">
                        <th>SI.No</th>
                        <th>Event Name</th>
                        <th>Date and Time</th>
                        <th>Address</th>
                        <th>Organizer Name</th>
                        <th>Phone</th>
                        <th>Email</th>
                        <th>Ticket Type</th>
                        <th>Ticket Price</th>
                        <th>Ticket Quantity</th>
                        <th>Total Price</th>
                        <th>Payment Method</th>
                    </thead>
                    <tbody>
                        <tr th:each="event, iterStat : ${events}">
                            <td th:text="${iterStat.count}"></td>
                            <td th:text="${event.eventName}"></td>
                            <td th:text="${event.dateTime}"></td>
                            <td th:text="${event.address}"></td>
                            <td th:text="${event.organizerName}"></td>
                            <td th:text="${event.phone}"></td>
                            <td th:text="${event.email}"></td>
                            <td th:text="${event.ticketType}"></td>
                            <td th:text="${event.ticketPrice}"></td>
                            <td th:text="${event.ticketQuantity}"></td>
                            <td th:text="${event.totalPrice}"></td>
                            <td th:text="${event.paymentMethod}"></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </main>
</body>
</html>


This HTML code describes the User Dashboard and It will show available Event Registrations in the MongoDB in the form of Table. Here The controller layer fetch data from the Database and Model layer provide that data on the View Layer.

Output:

Below is the Event Registration Dashboard, where we can see all the details about the registered event.

 Event Dashboard


Repository

In this application, we have created Mongo Repository interface named EventRepo using @Repository Annotation for Handling CRUD operations in this application. It interacts with Database. This Connection extends to MongoRepository.

EventRepo.java:

Java
package com.event.management.app.repo;

import org.springframework.data.mongodb.repository.MongoRepository;

import com.event.management.app.domain.EventRegistration;

public interface EventRepo extends MongoRepository<EventRegistration, String>{

}


Controller Layer

In Event Registration System, we have created one Controller class with name EventController by using @Controller Spring Annotations. This class is used for define the API end points to hit the API through the Web Browser. Here every API have different request types like GET, POST. It holds all the business logic and provide the output on the web page by using Thymeleaf Framework.

EventController.java:

Java
package com.event.management.app.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; // Use Controller for Thymeleaf
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.event.management.app.domain.EventRegistration;
import com.event.management.app.service.EventService;

@Controller // Change to Controller for Thymeleaf views
public class EventController {

    @Autowired
    private EventService service;

    @GetMapping("/")
    public String showForm(Model model) {
        // Providing an empty EventRegistration object for form binding
        model.addAttribute("eventRegistration", new EventRegistration());
        return "index";
    }

    @GetMapping("/register")
    public String signupPage() {
        return "signup";
    }

    @GetMapping("/dashboard")
    public String showBookings(Model model) {
        var events = service.getAllEvents();
        model.addAttribute("events", events);
        return "dashboard";
    }

    @PostMapping("/register")
    public String registerEvent(@ModelAttribute EventRegistration eventRegistration, BindingResult bindingResult,
            RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
            redirectAttributes.addFlashAttribute("error", "Failed to register event. Please correct the errors.");
            return "redirect:/register";
        }

        try {
            // Save the registration data
            service.saveEvent(eventRegistration);
            redirectAttributes.addFlashAttribute("success", "Event successfully registered!");
            return "redirect:/register";  // Redirect to clear form data and show flash message
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", "An error occurred during registration. Please try again.");
            return "redirect:/register";
        }
    }
}


In the above Controller class we have different API end points for different purpose in our project. Below we provide details information about that APIs.

  • @GetMapping("/"): This API URL is used for by default display the index page by using Thymeleaf.
  • @GetMapping("/register"): This API URL is used for display the Event Registration Form to the end user.
  • @GetMapping("/dashboard"): This API URL is used for display the Dashboard page with available event Registrations details to the end user.
  • @PostMapping("/register"): This API URL is used for save the event Registration details in the MongoDB by using POST mapping. When data is successfully saved then you got one alert message and also when got error then also you got one alert message for representing the error.

APIs Information

In this application, we use different types APIs with various mappings for different purpose. Below we provide a detailed information for each API with related output for better understanding the concept.

1. @GetMapping("/"):

This API is used for display the home page by default to the end user where Hit this URL through browser. And Its mapping type is GET Mapping then only user can view the HTML page.

API: http://localhost:8080/

    @GetMapping("/")
public String showForm(Model model) {
// Providing an empty EventRegistration object for form binding
model.addAttribute("eventRegistration", new EventRegistration());
return "index";
}


@GetMapping will display the Index page of the Application as shown below:

Index Page


2. @GetMapping("/register"):

This API is used for display the Event Registration page to the end user where Hit this URL through browser. And Its mapping type is GET Mapping then only user can view the HTML page.

http://localhost:8080/register

@GetMapping("/register")
public String signupPage() {
return "signup";
}


This Endpoint will redirect us to the Event Registration Page as shown below:

Event Registration Page


3. @GetMapping("/dashboard"):

This API is used for display the Event dashboard page to the end user where Hit this URL through browser. And Its mapping type is GET Mapping then only user can view the HTML page. In this page we can to view all registered event details.

@GetMapping("/dashboard")
public String showBookings(Model model) {
var events = service.getAllEvents();
model.addAttribute("events", events);
return "dashboard";
}


This Endpoint will redirect us to the Event Dashboard page as shown below:

Event Dashboard page


4. @PostMapping("/register"):

This API is used for save the event details by the help of the Thymeleaf where hit this URL through browser. And Its mapping type is POST Mapping then only data is saved into the MongoDB. And we got alert message for success or even fail. In this API method we call the save method from event repository interface, It can handle the all database operations.

@PostMapping("/register")
public String registerEvent(@ModelAttribute EventRegistration eventRegistration, BindingResult bindingResult,
RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("error", "Failed to register event. Please correct the errors.");
return "redirect:/register";
}

try {
// Save the registration data
service.saveEvent(eventRegistration);
redirectAttributes.addFlashAttribute("success", "Event successfully registered!");
return "redirect:/register"; // Redirect to clear form data and show flash message
} catch (Exception e) {
redirectAttributes.addFlashAttribute("error", "An error occurred during registration. Please try again.");
return "redirect:/register";
}
}


Using this API we can register a new event as shown below:

Event Registered Successfully



Next Article

Similar Reads