htmx はエラー処理が下手だという批判を時々聞きます。なぜそうではないのか、例を示します。 htmx を使用した一般的な操作の 1 つは、HTML フォーム (application/x-www-form-urlencoded タイプ) をバックエンド サーバーに送信し、応答を取得することです。もちろん、幸せな道とは、応答が成功し、htmx が HTML フラグメントの交換を行う場合です。しかし、悲しい道を見てみましょう。
一般的な UX のニーズは、検証に失敗した各フィールドの横にエラー メッセージを表示することです。 Bulma CSS フレームワークのドキュメントからこの例を見てください: https://bulma.io/documentation/form/general/#complete-form-example
これは見た目は良いですが、潜在的にすべてのフィールドにカスタム マークアップとレイアウトが必要になります。 HTML Constraint Validation API に対する最新のブラウザ サポートを利用したらどうなるでしょうか?これにより、ドキュメントのマークアップの外側に存在する独自のポップアップを使用して、各フィールドにエラー メッセージを添付できます。ここで例を参照できます: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/reportValidity#results
検証に失敗したすべてのフィールドに対して次のようなメッセージがポップアップ表示されたらどうなるでしょうか?これがこの投稿の質問です。
ペイロード fullname=Foo&email=bar@baz.com のフォームを処理するエンドポイント POST /users があるとします。バックエンドでデータを取得してデコードし、成功すれば、前述したように幸せな道を歩むことになります。しかし、フォームのデコードが失敗すると、興味深い点が生じます。
ここが重要なポイントです: フォームのデコードが失敗した場合、発生した可能性のある他のエラーではなく、この特定のエラーについて htmx に知らせる何らかの方法が必要です。ここで決断を下さなければなりません。検証に失敗したフォームに 422 Unprocessable Content ステータス コードを使用するとします。
次に、検証エラー メッセージを正確にフォーマットする方法を決定する必要があります。前述の制約検証 API は JavaScript API であるため、ほぼそれによって決定が行われます。エラーは JSON としてフォーマットされます。
フォームの例は次のとおりです:
<form id=add-user-form method=post action=/users hx-post=/users > <input name=fullname> <input type=email> <input type=submit value="Add User"> </form>
もちろん、実際のアプリでは、これらの入力は両方とも required 属性を持ちます。ここでは、デモンストレーションの目的でそれらを省略しているだけです。
フルネームと電子メールのフィールドを空のままにしてこのフォームを送信すると、バックエンドはフォームの検証に失敗し、次のように応答します。
HTTP 422 Content-Type: application/json { "add-user-form": { "fullname": "Please fill out this field", "email": "Please fill out this field" } }
どうすればこれを実現できるでしょうか? htmx は、トリガーされた要素の ID (この場合は add-user-form) を含むリクエスト ヘッダー HX-Trigger を送信します。したがって、そこから最も外側のオブジェクトのキーを取得します。次に、フォーム検証関数は、検証に失敗したフィールドの名前とそれぞれのエラー メッセージを通知します。これにより、キーと値を含む内部オブジェクトが得られます。
バックエンドからのこの応答では、JSON を走査し、対応する各フォーム フィールドにエラー メッセージを添付するための JavaScript が必要です。
document.addEventListener('htmx:responseError', evt => { const xhr = evt.detail.xhr; if (xhr.status == 422) { const errors = JSON.parse(xhr.responseText); for (const formId of Object.keys(errors)) { const formErrors = errors[formId]; for (const name of Object.keys(formErrors)) { const field = document.querySelector(`#${formId} [name="${name}"]`); field.setCustomValidity(formErrors[name]); field.addEventListener('focus', () => field.reportValidity()); field.addEventListener('change', () => field.setCustomValidity('')); field.focus(); } } } else { // Handle the error some other way console.error(xhr.responseText); } });
ここでは 3 つの重要なことを行っています:
上記の 4 番目のアクションは、重要ではありませんが、あると便利です。フィールドの 1 つに焦点を当てて、エラー メッセージをポップアップ表示します。これは、フォームの送信で問題が発生したことをユーザーに示します。もちろん、input:invalid 擬似セレクターをターゲットにして CSS で無効な状態の入力を強調表示するなど、さらに大きなヒントを提供することもできます。
フォームが送信されて検証エラーが発生するたびに、応答によってエラー メッセージが適切な場所に自動的に入力されます。
細心の注意を払っている方は、このテクニックは htmx に限定されないようだと思われるかもしれませんが、それは正しいです。 Constraint Validation API に基づくこの手法は、フォームを使用するフロントエンドで使用できます。特に htmx で使用する必要はありません。バックエンド サーバーからのフォーム検証エラーを処理できるようにこれを調整するだけです。
最新のブラウザーの組み込み機能を利用することで、コードの適応性が高まり、ブラウザーが UI に対して行う今後の改善の恩恵を受けることができます。
以上がhtmx でのフォーム エラーの処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。