カスタマイズされた確認 UI

htmx は hx-confirm 属性をサポートし、ユーザーの操作を確認するための簡単な仕組みを提供します。これは javascript で既定の confirm() 関数を使用しますが、信頼性は高いものの、アプリケーションの UX と一致しない場合があります。

このサンプルでは、sweetalert2 を使用して、カスタム確認ダイアログを実装する方法を説明します。以下は、クリック + カスタムイベントメソッドを使用するものと、組み込みの hx-confirm 属性と htmx:confirm イベントを使用するものの 2 つのサンプルです。

#クリック + カスタムイベントの使用

<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<button hx-get="/confirmed" 
        hx-trigger='confirmed'
        onClick="Swal.fire({title: 'Confirm', text:'Do you want to continue?'}).then((result)=>{
            if(result.isConfirmed){
              htmx.trigger(this, 'confirmed');  
            } 
        })">
  Click Me
</button>

ここでは javascript を使用して、クリック時に確認を求める Sweet Alert 2 を表示します。ユーザーがダイアログを確認すると、カスタムの「confirmed」イベントをトリガーしてリクエストをトリガーし、hx-trigger によって取得されます。

#バニラ JS、hx-confirm

<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
  document.addEventListener("htmx:confirm", function(e) {
    // The event is triggered on every trigger for a request, so we need to check if the element
    // that triggered the request has a hx-confirm attribute, if not we can return early and let
    // the default behavior happen
    if (!evt.detail.target.hasAttribute('hx-confirm')) return

    // This will prevent the request from being issued to later manually issue it
    e.preventDefault()

    Swal.fire({
      title: "Proceed?",
      text: `I ask you... ${e.detail.question}`
    }).then(function(result) {
      if (result.isConfirmed) {
        // If the user confirms, we manually issue the request
        e.detail.issueRequest(true); // true to skip the built-in window.confirm()
      }
    })
  })
</script>
  
<button hx-get="/confirmed" hx-confirm="Some confirm text here">
  Click Me
</button>

javascript を追加して、クリック時に Sweet Alert 2 を呼び出して確認を求めます。ユーザーがダイアログを確認すると、issueRequest メソッドを呼び出してリクエストをトリガーします。skipConfirmation=true を引数として渡して window.confirm をスキップします。

これにより、質問が要素(例:Django リスト)に依存する場合に便利なプロンプトで hx-confirm の値を使用できるようになります。

{% for client in clients %}
<button hx-post="/delete/{{client.pk}}" hx-confirm="Delete {{client.name}}??">Delete</button>
{% endfor %}

htmx:confirm イベントの詳細については こちらを参照してください。