Bulk Update
This demo shows how to implement a common pattern where rows are selected and then bulk updated. This is accomplished by putting a form around a table, with checkboxes in the table, and then including the checked values in the form submission(POST request)
:
return FormEl(
ID("checked-contacts"),
hx.Post("/examples/gomponents/bulk-update/"),
hx.SwapExtended(
swap.New().Strategy(swap.OuterHTML).Settle(3*time.Second),
),
hx.Target(
"#toast",
),
H3(g.Text("Select Rows And Activate Or Deactivate Below")),
Table(
THead(
Tr(
Td(g.Text("Name")),
Td(g.Text("Email")),
Td(g.Text("Activate")),
),
),
TBody(
ID("tbody"),
g.Group(
g.Map(users, func(u form.UserModel) g.Node {
return Tr(
Td(g.Text(u.Name)),
Td(g.Text(u.Email)),
Td(
Input(
Type("checkbox"),
Name(u.Email),
g.If(u.Active,
Checked(),
),
),
),
)
}),
),
),
),
Input(
Type("submit"),
Value("Submit"),
),
UpdateToast(""),
)
The server will bulk-update the statuses based on the values of the checkboxes. We respond with a small toast message about the update to inform the user, and use ARIA to politely announce the update for accessibility.
#toast.htmx-settling {
opacity: 100;
}
#toast {
background: #E1F0DA;
opacity: 0;
transition: opacity 3s ease-out;
}
func UpdateToast(toast string) g.Node {
return Span(
ID("toast"),
g.If(toast != "",
g.Attr("aria-live", "polite"),
),
g.Text(toast),
)
}
The cool thing is that, because HTML form inputs already manage their own state, we don’t need to re-render any part of the users table. The active users are already checked and the inactive ones unchecked!
You can see a working example of this code below.