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):

<form
	id="checked-contacts"
	{ hx.Post("/examples/templ/bulk-update/")... }
	{ hx.SwapExtended(
		swap.New().Strategy(swap.OuterHTML).Settle(3 * time.Second),
	)... }
	{ hx.Target("#toast")... }
>
	<h3>Select Rows And Activate Or Deactivate Below</h3>
	<table>
		<thead>
			<tr>
				<th>Name</th>
				<th>Email</th>
				<th>Active</th>
			</tr>
		</thead>
		<tbody id="tbody">
			for _, user := range users {
				<tr>
					<td>{ user.Name }</td>
					<td>{ user.Email }</td>
					<td>
						<input
							type="checkbox"
							name={ user.Email }
							if user.Active {
								checked
							}
						/>
					</td>
				</tr>
			}
		</tbody>
	</table>
	<input type="submit" value="Bulk Update"/>
	@UpdateToast("")
</form>

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;
}
templ UpdateToast(toast string) {
	<span
		id="toast"
		if toast != "" {
			aria-live="polite"
		}
	>
		{ toast }
	</span>
}

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.

Source

Demo

Select Rows And Activate Or Deactivate Below

NameEmailActive
Joe Smithjoe@smith.org
Angie MacDowellangie@macdowell.org
Fuqua Tarkentonfuqua@tarkenton.org
Kim Yeekim@yee.org