【htmx】行を選択して一括更新
参考 #
実際のコード #
<form id="checked-contacts"
hx-post="/users"
hx-swap="innerHTML settle:3s"
hx-target="#toast">
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Active</th>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td>Joe Smith</td>
<td>joe@smith.org</td>
<td><input type="checkbox" name="active:joe@smith.org"></td>
</tr>
...
</tbody>
</table>
<input type="submit" value="Bulk Update" class="btn primary">
<output id="toast"></output>
</form>公式htmxの サンプルコードです。
概要 #
チェックボックスで選択されたユーザーを/users エンドポイントに POST で送信し、結果メッセージを #toast に表示するというバルク更新。
解説 #
formタグ #
<form id="checked-contacts"
hx-post="/users"
hx-swap="innerHTML settle:3s"
hx-target="#toast">hx-post="/users": HTML form送信ではなく、 htmxで/usersにPOSTリクエストするhx-swap="innerHTML settle:3s: SSRしたHTMLをhx-targetで指定した要素のinnerHTMLに置き換える。- また、描画が安定(settle)してから3秒間はそのまま表示する(アニメーションなどの完了待ちに使ったり)
hx-target="#toast: レスポンス内容を描画する要素を指定(id="toast")
input active #
<tbody id="tbody">
<tr>
<td>Joe Smith</td>
<td>joe@smith.org</td>
<td><input type="checkbox" name="active:joe@smith.org"></td>
</tr>
...
</tbody>name="active:joe@smith.org"- チェックされている要素のみフォーム送信される
active:joe@smith.org=onのような形式でサーバーに送信される
tbodyに複数行存在することが前提
submit #
<input type="submit" value="Bulk Update" class="btn primary">
<output id="toast"></output>submitを押すとhx-postが発火する- SSR結果は
<output id="toast"></output>へレンダリングされる
サーバー側の処理 #
リクエストボディ #
active:joe@smith.org=on
active:bob@tanaka.jp=onGoのコード #
func usersHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var activeEmails []string
for key := range r.PostForm {
if strings.HasPrefix(key, "active:") {
email := strings.TrimPrefix(key, "active:")
activeEmails = append(activeEmails, email)
}
}
fmt.Fprintf(w, "%d users updated successfully", len(activeEmails))
}上記handlerを設定したルーティングへリクエストを送ると、2 users updasted successfully がレスポンスとして返り<output id="toast"></output> 内へ挿入される。