行を編集する

このサンプルは、編集可能な行を実装する方法を示しています。まずはテーブルの本体を見てみましょう

<table class="table delete-row-example">
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th></th>
    </tr>
  </thead>
  <tbody hx-target="closest tr" hx-swap="outerHTML">
    ...
  </tbody>
</table>

これにより、テーブル内のリクエストがリクエストがトリガーされた最も近い囲み行をターゲットにして、行全体を置き換えます。

次に行の HTML を示します

<tr>
      <td>${contact.name}</td>
      <td>${contact.email}</td>
      <td>
        <button class="btn danger"
                hx-get="/contact/${contact.id}/edit"
                hx-trigger="edit"
                onClick="let editing = document.querySelector('.editing')
                         if(editing) {
                           Swal.fire({title: 'Already Editing',
                                      showCancelButton: true,
                                      confirmButtonText: 'Yep, Edit This Row!',
                                      text:'Hey!  You are already editing a row!  Do you want to cancel that edit and continue?'})
                           .then((result) => {
                                if(result.isConfirmed) {
                                   htmx.trigger(editing, 'cancel')
                                   htmx.trigger(this, 'edit')
                                }
                            })
                         } else {
                            htmx.trigger(this, 'edit')
                         }">
          Edit
        </button>
      </td>
    </tr>

ここでは、JavaScript を使用して派手にし、一度に 1 行のみを編集できるようにしています。.editing クラスを持つ行があるかどうかを確認し、ユーザーがこの行を編集して他の行を削除することを確認します。該当する場合は、他の行にキャンセルイベントを送信して、最初の状態に戻るリクエストを発行します。

次に、現在の要素で edit イベントをトリガーします。これにより、htmx リクエストがトリガーされ、行の編集可能なバージョンが取得されます。

ユーザーが複数の行を編集しているかどうかを気にしない場合は、ハイパーでカスタムの hx-trigger を省略し、通常のクリック処理を htmx で処理できます。編集ボタンをクリックしたときにテーブル全体をターゲットにすることによって、相互排他を実装することもできます。ここでは、htmx と JavaScript を統合して問題を解決し、サーバーとのインタラクションを少し限定する方法を説明します。さらに、便利な SweetAlert 確認ダイアログを使用できます。

最後に、データが編集されているときの行の表示を以下に示します

<tr hx-trigger='cancel' class='editing' hx-get="/contact/${contact.id}">
  <td><input name='name' value='${contact.name}'></td>
  <td><input name='email' value='${contact.email}'></td>
  <td>
    <button class="btn danger" hx-get="/contact/${contact.id}">
      Cancel
    </button>
    <button class="btn danger" hx-put="/contact/${contact.id}" hx-include="closest tr">
      Save
    </button>
  </td>
</tr>

ここでは、いくつかのことが行われています。まず、行自体が cancel イベントに応答し、行の読み取り専用バージョンが戻ります。現在の編集を取り消すことができるキャンセルボタンがあります。最後に、連絡先を更新するために PUT を発行する保存ボタンがあります。hx-include があり、最も近い行のすべての入力が含まれます。HTML の制約により、テーブルの行はフォームで使用するのに非常に困難です(tr 内に直接 form を配置することはできません)ので、これにより処理が少し快適になります。

サーバーリクエスト ↑ 表示

🔗デモ