Time to complete: 3 days.
1. Creating approximate design
2. Research:
- How do you make websites with Java?
- Java Web Application Tutorial for Beginners
- Spring Boot JSP Hello World Example Tutorial (Video)
‼️ Build an ENTIRE TODO Web Application with Java Spring Boot 3.0.0 in 62 min (Video)
💡 decided to use Spring Boot, Thymeleaf and HTML for application instead of JSP as those technologies are more familiar to me.
Generated a template using https://start.spring.io/.
- H2 database
- Spring Web
- Spring Data JPA
- Thymeleaf
- Validation
- Spring Devtools
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
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
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 inToDoElement
classCascadeTyde.All
- all actions done onToDoList
will be cascaded to childrenorphanRemoval
- in caseToDoList
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)
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 thendiv
(element) of each list and its elements in a form of a table. Lists are extracted usingThymeleaf
:<div th:each = "list : ${toDoLists}"></div>
- element where program is iterating through all the liststh:href="@{/create-element/{id}(id=${list.id})}
- create a reference usingid
field oflist
object<tr th:each="element : ${list.toDoElements}"></tr>
- show rows with help of elements' iteration, got from thetoDoElements
field oflist
object<span th:if="${element.isDone}"></span>
or<span th:unless="${element.isDone}"></span>
for conditionsth:text="${element.name}"
showname
of theelement
th:object="${toDoList}"
orth:field="${toDoList.name}"
object or field reference
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.
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.
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