Skip to content

Project for simple to-do lists, using Java as a Backend (with Spring Data and Spring Web + H2 database) and HTML as Frontend (with Thymeleaf)

Notifications You must be signed in to change notification settings

yanamlnk/simple-todo-lists

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple to-dos. Place for your lists 🖤

Time to complete: 3 days.

Day 1

1. Creating approximate design

image

2. Research:

💡 decided to use Spring Boot, Thymeleaf and HTML for application instead of JSP as those technologies are more familiar to me.

Day 2

BASIC ELEMENTS:

Generated a template using https://start.spring.io/.

—— Application dependencies ——

  • H2 database
  • Spring Web
  • Spring Data JPA
  • Thymeleaf
  • Validation
  • Spring Devtools

—— Configuration ——

Defaul port 8080.

In application.properties

  • Configure H2 database
  • Configure H2 console
  • Configure Thymeleaf cache
  • Configure JPA

💡 h2-console is actually an awesome tool to look at your database. When you start your application, you can acces it using /h2-console endpoint, using JDBC URL, User Name and Password from your configurations

—— Backend ——

1. Entities

class ToDoList {
    Long id;
    List <Element> elements
    String listName
}
class ToDoElement {
    Long id
    ToDoList todoList;
    String name;
    Boolean isDone;
}
  • @Entity - to specify that this class is an entity
  • @Table - to specify table name (indifferent from class name)
  • @Id to specify id of the entity
  • @GeneratedValue to generate id automatically
  • @NoBlank - validator

RELATIONSHIPS:

ONE List can have MANY Elements.

In ToDoList:

@OneToMany(mappedBy = "toDoList", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ToDoElement> toDoElements = new ArrayList<>();
  • mappedBy - to indicate field name in ToDoElement class
  • CascadeTyde.All - all actions done on ToDoList will be cascaded to children
  • orphanRemoval - in case ToDoList will be deleted, all child elements will be deleted, too.

In ToDoElement:

@ManyToOne
@JoinColumn(name = "toDoList_Id")
private ToDoList toDoList;
  • name of the foreign key in the table

2. Repositories

What actions will I need?

Action Repository Method
Add list ToDoListRepository ToDoList save(ToDoList toDoList)
Delete list ToDoListRepository void delete(ToDoList entity)
Edit name of the list ToDoListRepository ToDoList save(ToDoList toDoList)
Find list ToDoListRepository Optional findById(Long id)
Find all lists ToDoListRepository List findAll()
Add element to the list ToDoElementRepository ToDoElement save(ToDoElement toDoElement) - (setting ToDoList beforehand)
Delete element from the list ToDoElementRepository void delete(ToDoElement toDoElement)
Mark element as done ToDoElementRepository ToDoElement save(ToDoElement toDoElement) - (setting boolean beforehand)
Edit name of the element ToDoElementRepository ToDoElement save(ToDoElement toDoElement) - (setting new name beforehand)
Find element ToDoElementRepository Optional findById(Long id)

3. Controller

Start from Home Page Controller with @GetMapping(“/) method

  • Returns ModelAndView object - object for rendering views with associated data.
  • “home” argument in the constructor - name of the “View” (so name of the html file).
  • addObject method adds some data to the Model. “toDoLists” is keyword that will be used to refer to that data in HTML file, toDoListRepository.findAll() is the data itself)

💡(P.S. MVC model - Model View Controller model. Model responsible for data, View for UI, Controller - for taking input from view and manipulating the Model based on the input. Then Model updates View with new data)

—— Frontend ——

home.html

Responsible for home page

  • In head configure encoding, colours, and viewport to be visible from different devices
  • In body is a heading, and then div (element) of each list and its elements in a form of a table. Lists are extracted using Thymeleaf:
    • <div th:each = "list : ${toDoLists}"></div> - element where program is iterating through all the lists
    • th:href="@{/create-element/{id}(id=${list.id})} - create a reference using id field of list object
    • <tr th:each="element : ${list.toDoElements}"></tr> - show rows with help of elements' iteration, got from the toDoElements field of list object
    • <span th:if="${element.isDone}"></span> or <span th:unless="${element.isDone}"></span> for conditions
    • th:text="${element.name}" show name of the element
    • th:object="${toDoList}" or th:field="${toDoList.name}" object or field reference

—— Test run ——

Error: Table "LISTS" not found (this database is empty); -> Don’t forget to put in application.properties the following:

spring.jpa.hibernate.ddl-auto=create-drop

“The values create, create-drop, validate, and update basically influence how the schema tool management will manipulate the database schema at startup.”

💡 Usually used for tests, but here it is better to use this property to create database and tables, and then drop it after program stops. Not recommended for production.

—— Additional Features ——

1. Button to add the list

  • under the heading
  • when you click on it, it opens new page where you fill information on new list
________________________________________

|Back|__(name of the list)__|Create|
________________________________________
  • Create button in home.html under the heading, with new endpoint
  • Create new controller class, create GetMapping method for endpoint from the step 1. Returns new html page (create-list-page)
  • In create-list-page.html add:
    • Back button -> returns to home page
    • Form to accept name of the new list AND create new endpoint to POST
    • Submit button
  • In class from the step 2, create PostMapping to the endpoint from step 3, to save new element to the database

2. Button to add new element to the list

  • at the end of each list
  • when you click on it, it opens new page where you fill information on new element

  • Create button in home.html under the table, with new endpoint that contains list id
  • In controller class, create GetMapping method for endpoint from the step 1. Returns new html page (create-element-page)
  • In create-element-page.html add:
    • Back button -> returns to home page
    • Form to accept name of the new list AND create new endpoint to POST (again that contains list id)
    • Submit button
  • In class from the step 2, create PostMapping to the endpoint from step 3, to save new element to the database

3. Ability to complete the element

  • before name of the element
  • button “Done!”
  • When element is done, it has strikethrough effect
  • when click again, the element is “undone”

To do this, add new button in home.html that will have GET endpoint. In controller class, created method that will change isDone field to the opposite.

Day 3

4. Edit button to the list to edit name and delete list

  • to the left of the list
  • 2 separate buttons, one for Delete, another for Edit.

  • Delete -> as with complete button, simply got you to the endpoint where the element is deleted based on its id.
  • Edit -> as in button to add new element. It get to the new page where you can rename and submit new name.

5. Edit button to each of the elements to edit name or delete element

The same steps and process as in previous stage

6. Done button must change to “Undone” button if task is completed