Lab 3: Inline Editing
In this lab, we will create a group Management Page where we can add a user to a group and a navigation bar
Group Management
We start by creating a GroupManagementComponent ViewComponent in the de.tschuehly.easy.spring.auth.group.management package:
@ViewComponent
public class GroupManagementComponent {
public static final String MODAL_CONTAINER_ID = "modalContainer";
public static final String CLOSE_MODAL_EVENT = "close-modal";
public record GroupManagementContext() implements ViewContext { }
public ViewContext render() {
return new GroupManagementContext();
}
}The template is the same as the UserManagementComponent.jte but we added two <a> links to the <nav> element.
@import static de.tschuehly.easy.spring.auth.group.management.GroupManagementComponent.CLOSE_MODAL_EVENT
@import static de.tschuehly.easy.spring.auth.group.management.GroupManagementComponent.MODAL_CONTAINER_ID
@import de.tschuehly.easy.spring.auth.group.management.GroupManagementComponent.GroupManagementContext
@param GroupManagementContext groupManagementContext
<html lang="en">
<head>
<title>Easy Spring Auth</title>
<link rel="stylesheet" href="/css/sakura.css" type="text/css">
<script src="/htmx_1.9.11.js"></script>
<script src="/htmx_debug.js"></script>
<script src="http://localhost:35729/livereload.js"></script>
</head>
<body hx-ext="debug">
<nav>
<h1>
Easy Spring Auth
</h1>
<a href="/">UserManagement</a>
<a href="/group-management">GroupManagement</a>
<hr>
</nav>
<main>
</main>
</body>
<div id="${MODAL_CONTAINER_ID}" hx-on:$unsafe{CLOSE_MODAL_EVENT}="this.innerHTML = null">
</div>
</html>Next, we will create a GroupTableComponent in the de.tschuehly.easy.spring.auth.group.management.table package.
We autowire the groupService and create a GROUP_TABLE_ID constant.
We add the corresponding template GroupTableComponent.jte and set the <table> id to ${GROUP_TABLE_ID}
Now back in the GroupTableComponent.java, we retrieve all groups with the groupService.getAll() method and add this List of groups to the ViewContext
Now we need to replace the <tbody> element of the GroupTableComponent.jte with the following:
(1): We loop over the groupTableContext.groupList() variable with the @for syntax
(2): We show the groupName in a <td>
(3): We loop over the group.memberList
(4): We show the username in a <span>
(5): If the group has no users we show a no member message
Then we render the GroupTableComponent in the GroupManagementComponent. We autowire it and pass it into the ViewContext
In the GroupManagementComponent.jte template we render the GroupTableComponent it in the <main> element, by using the viewContext
Now we need to add the /group-management endpoint to the GroupController:
(1): We autowire the GroupManagementComponent
(2): We create a new @GetMapping
(3): We return the ViewContext retrieved by calling the render() method
If we now run Lab3Application.java and navigate to localhost:8080/group-management to see the rendered groups and members.

Lab-3 Checkpoint 1
If you are stuck you can resume at this checkpoint with:
git checkout tags/lab-3-checkpoint-1 -b lab-3-c1
We haven't done anything new yet, now we are going to start with the inline editing feature.
Inline Editing
We now want to add a new User to one of the groups.
We autowire the GroupTableComponent and create an endpoint in the GroupController:
(1): We define a POST_ADD_USER constant
(2): We define a USER_ID_PARAM constant
(3): We capture the groupName via @PathVariable
(4): We capture the userId via @RequestParam
(5): We add the user to the group via the groupService
(6): We return the GroupTableComponent.render which will render the group table with the new user added
Next, we create a AddUserComponent in the de.tschuehly.easy.spring.auth.group.management.table.user package:
(1): We autowire the UserService
(2): The render method has a groupName parameter
(3): We pass the groupName and the userService.findAll to the AddUserContext.
Now we create a AddUserComponent.jte template in the same package as the AddUserComponent.java
(1): We create a <form> element add an hx-post attribute that targets the POST_ADD_USER endpoint and inserts the groupName in the ViewContext into the Endpoint URI using the HtmxUtil
(2): We target the GROUP_TABLE_ID and swap the outerHTML of the target element.
(3): We create a <select> and use the @for loop syntax to create an option element for each user.
We now autowire the AddUserComponent and create a GET_SELECT_USER endpoint in the GroupController
Back to the GroupTableComponent.jte we add a static import to GET_SELECT_USER and HtmxUtiland add a new <td> in the @for loop.
(1): We create a <button> element that has a hx-get attribute that creates a GET request to /group/groupName/select-user
(2): We swap the outerHTML of the target element. As we didn't set the hx-targetwe replace the <button> element.
Now restart the application and navigate to localhost:8080/group-management.
We can click on the plus and see the selector to add a User to the group. When clicking on Add User to group the table is rerendered with the updated value.

Lab-3 Checkpoint 2
If you are stuck you can resume at this checkpoint with:
git checkout tags/lab-3-checkpoint-1 -b lab-3-c2
Last updated