フォーム
Inertia は、フォームを構築するための 2 つの主要な方法を提供します。<Form> コンポーネントと useForm ヘルパーです。どちらもサーバーサイドフレームワークのバリデーションと統合されており、フルページのリロードなしでフォーム送信を処理します。
Form コンポーネント
Inertia は、従来の HTML フォームとよく似た挙動をする <Form> コンポーネントを提供しますが、内部では Inertia を使用してフルページのリロードを回避します。これは、Inertia でフォームを始める最も簡単な方法です。
従来の HTML フォームと同様に、入力フィールドに Vueならv-model、ReactならonChange ハンドラー、Svelteならbind:を追加する必要はありません。各入力に name 属性 、Reactなら(該当する場合は)defaultValue を指定するだけで、Form コンポーネントがデータ送信を処理してくれます。
このコンポーネントは、ネストされたデータ構造、ファイルアップロード、ドット区切りのキー記法にも対応しています。
送信前にフォームデータを変更するために、transform プロパティを渡すことができます。これは追加のフィールドを注入したり、既存のデータを変換したりするのに便利ですが、hidden input を使う方法でも可能です。
Wayfinder
Wayfinder を使用する場合、生成されたオブジェクトをそのまま action プロパティに渡すことができます。Form コンポーネントは、Wayfinder オブジェクトから HTTP メソッドと URL を自動的に推論します。
デフォルト値
チェックボックス入力
チェックボックスを扱う際には、value="1" のように明示的な value 属性を追加したくなる場合があります。value 属性がない場合、チェックされたチェックボックスは "on" として送信されますが、これは一部のサーバーサイドのバリデーションルールでは適切な boolean 値として認識されないことがあります。
スロットプロパティ
<Form> コンポーネントは、デフォルトスロットを通じてリアクティブな状態やヘルパーメソッドを公開します。これにより、フォームの処理状態、エラー、ユーティリティ関数にアクセスできます。
defaults メソッドを使用すると、現在のフィールド値に合わせてフォームのデフォルト値を更新できます。これを呼び出すと、その後の reset() 呼び出しではフィールドがこれらの新しいデフォルト値に復元され、isDirty プロパティは更新後のデフォルトからの変更を追跡します。useForm とは異なり、このメソッドは引数を受け取らず、常に現在のすべてのフォーム値を使用します。
errors オブジェクトはネストされたフィールドに対してドット記法を使用するため、複雑なフォーム構造のバリデーションメッセージを表示できます。
Props とオプション
action と method に加えて、<Form> コンポーネントはいくつかの props を受け取ります。その多くは、Inertia の visit オプション で利用可能なオプションと同一です。
一部の props は、混乱を避けるためにトップレベルではなく、意図的に options の下にまとめられています。たとえば、only、except、reset は 部分的なリロード に関連するものであり、部分的な送信 には関係しません。一般的なルールとして、トップレベルの props はフォーム送信そのものに関するもので、options はその後の visit を Inertia がどのように処理するかを制御します。
処理中のフォームをスタイリングするには、次の方法で inert 状態のフォームを対象にできます。
イベント
<Form> コンポーネントは、フォーム送信時に標準の訪問 イベント をすべて発火します。
フォームのリセット
Form コンポーネントには、送信後にフォームをリセットできるいくつかの属性が用意されています。
resetOnSuccess は、送信が成功した後にフォームをリセットするために使用できます。
resetOnError は、エラー発生後にフォームをリセットするために使用できます。
新しいデフォルト値の設定
Form コンポーネントは setDefaultsOnSuccess プロパティを提供しており、送信が成功した後に現在のフォームの値を新しいデフォルト値として設定できます。
ドット記法(Dotted Key Notation)
<Form> コンポーネントは、フラットな入力名からネストされたオブジェクトを作成するためにドット記法をサポートしています。これにより、フォームデータを便利に構造化できます。
上記の例では、以下のデータ構造が生成されます。
{
"user": {
"name": "John Doe",
"skills": ["JavaScript"]
},
"address": {
"street": "123 Main St"
}
}もしフィールド名に文字通りのドットを使いたい場合(ネストの区切りとしてではなく)、バックスラッシュでエスケープできます。
上記の例では、以下のデータ構造が生成されます。
{
"app.name": "My Application",
"settings": {
"theme.mode": "dark"
}
}プログラムによるアクセス
refs を使うことで、フォームのメソッドにプログラムからアクセスできます。これは、フォームの外部からフォームのアクションをトリガーする必要がある場合に、スロットプロップ の代替手段として利用できます。
React と Vue では、refs を使うとフォームのすべてのメソッドとリアクティブな状態にアクセスできます。Svelte では refs はメソッドのみを提供するため、isDirty や errors のようなリアクティブな状態は スロットプロップ でアクセスする必要があります。
Precognition
v2.3+<Form> コンポーネントは Laravel Precognition に対応しており、クライアント側でサーバーのバリデーションルールを重複させることなく、リアルタイムでフォームの検証が可能です。
サーバーが設定されたら、validate() にフィールド名を渡すことでそのフィールドを検証できます。invalid() ヘルパーはフィールドにバリデーションエラーがあるかを確認し、validating はリクエストが進行中かどうかを示します。
valid() ヘルパーを使うことで、フィールドがバリデーションに成功したかどうかも確認できます。
複数フィールドの検証
only オプションを使うと、複数のフィールドを一度に検証できます。これはウィザード形式のフォームで、次のステップに進む前に表示されているすべてのフィールドを検証したい場合に便利です。
Touch と Validate
touch() メソッドは、バリデーションをトリガーせずにフィールドを「タッチ済み」とマークします。その後、引数なしで validate() を呼ぶことで、タッチ済みのすべてのフィールドを検証できます。
touched() ヘルパーは引数なしで呼び出すと、どのフィールドでもタッチ済みかを確認できます。reset() メソッドは、リセット対象のフィールドのタッチ状態をクリアします。
オプション
validate() メソッドは、コールバックや設定を含むオプションオブジェクトを受け取れます。
validate('username', {
onSuccess: () => {
// バリデーション成功時の処理
},
onValidationError: (response) => {
// バリデーション失敗時の処理 (422レスポンスなど)
},
onBeforeValidation: (newRequest, oldRequest) => {
// falseを返すとバリデーションを防止
},
onFinish: () => {
// バリデーション後に常に実行される
},
})オプションオブジェクトのみを渡して特定のフィールドを検証することも可能です。
validate({
only: ['name', 'email'],
onSuccess: () => goToNextStep(),
})バリデーションリクエストは自動的にデバウンスされます。最初のリクエストは即時に発火し、その後の変更はデフォルトで 1500ms デバウンスされます。このタイムアウトはカスタマイズ可能です。
デフォルトでは、不要なアップロードを避けるためファイルはバリデーションリクエストに含まれません。ファイルサイズや MIME タイプの検証が必要な場合は、ファイルバリデーションを有効化できます。
デフォルトでは、バリデーションエラーは文字列(最初のエラーメッセージ)として簡略化されます。複数のバリデーションルールがあるフィールドのすべてのエラーを表示したい場合は、エラーを配列として保持できます。
フォームヘルパー
<Form> コンポーネントに加えて、Inertia はプログラム的にフォームのデータや送信動作を制御したい場合に便利な useForm ヘルパーも提供しています。
フォームを送信するには、get、post、put、patch、delete メソッドを使用できます。
これらの送信メソッドは、preserveState や preserveScroll、イベントコールバックなど、通常の visit オプション をサポートしています。例えば、onSuccess コールバックを使って、フォーム送信後に入力を初期状態にリセットすることが可能です。
送信前にフォームデータを変換したい場合は、transform() メソッドを使うことができます。
processing プロパティを使うと、フォームが現在送信中かどうかを追跡できます。これにより、送信ボタンを無効化して二重送信を防ぐことができます。
ファイルをアップロードしている場合、progress プロパティから現在の進捗を取得できるので、アップロード進行状況を簡単に表示できます。
フォームのエラー
バリデーションエラーは errors プロパティから取得できます。Laravel をバックエンドに使う Inertia アプリケーションでは、ValidationException がスローされると、フォームエラーは自動的にセットされます。例えば $request->validate() のようなケースです。
フォームのバリデーションやエラーについて詳しくは、バリデーションのドキュメント を参照してください。
フォームにエラーがあるか確認するには hasErrors プロパティを使います。エラーをクリアする場合は clearErrors() メソッドを使用します。
クライアントサイドで独自にバリデーションを行う場合や手動で入力を検証する場合は、setErrors() メソッドでフォームに任意のエラーを設定できます。
手動でエラーを設定しても、ページの props は変更されません。
フォームが正常に送信された場合、wasSuccessful プロパティは true になります。また、recentlySuccessful プロパティは送信成功後 2 秒間 true になり、一時的な成功メッセージを表示するのに利用できます。
recentlySuccessful の持続時間は、アプリケーションデフォルト で form.recentlySuccessfulDuration オプションを設定してカスタマイズ可能です。デフォルトは 2000 ミリ秒です。
フォームのリセット
フォームの値を初期値に戻すには reset() メソッドを使用します。
フォームを初期値に戻しつつバリデーションエラーも同時にクリアしたい場合は、resetAndClearErrors() メソッドを使うと、reset() と clearErrors() を一度に実行できます。
新しいデフォルト値の設定
フォームのデフォルト値が古くなった場合は、defaults() メソッドを使って更新できます。こうすることで、次回 reset() メソッドを呼び出した際にフォームは正しい値にリセットされます。
フォームフィールドの変更追跡
フォームに変更があるか確認するには、isDirty プロパティを使用します。
フォーム送信のキャンセル
フォーム送信をキャンセルするには、cancel() メソッドを使用します。
フォームデータと履歴状態
Inertia にフォームのデータやエラーを 履歴状態 に保存させるには、フォーム生成時に一意のキーを最初の引数として渡します。
フィールドの除外
場合によっては、特定のフィールドを履歴状態に保存しないようにしたいことがあります。たとえば、セキュリティ上の理由でパスワードフィールドを除外することができます。
複数のフィールドを除外する場合は、追加の引数として渡します。
form.dontRemember('password', 'password_confirmation')Wayfinder
v2.0.6+Wayfinder をフォームヘルパーと併用する場合、生成されたオブジェクトを直接 form.submit に渡すだけで、HTTP メソッドや URL が自動的に推測されます。
Precognition
v2.3+<Form> コンポーネントと同様に、useForm ヘルパーはリアルタイムバリデーションの Precognition に対応しています。HTTP メソッドとバリデーション用エンドポイントを指定して withPrecognition() をチェーンすることで有効化できます。
互換性のため、laravel-precognition パッケージと同様に、最初の引数にメソッドと URL を渡すこともできます。
const form = useForm('post', '/users', {
name: '',
email: '',
})Wayfinder と組み合わせて Precognition を使用することも可能です。
import { store } from 'App/Http/Controllers/UserController'
const form = useForm({
name: '',
email: '',
}).withPrecognition(store())
// または Wayfinder を最初の引数として渡す...
const form = useForm(store(), {
name: '',
email: '',
})Precognition を有効化したら、特定のフィールドのバリデーションを実行するには validate() を呼び出します。invalid() ヘルパーでエラーの有無を確認でき、validating はリクエスト進行中を示します。
valid() ヘルパーで、フィールドがバリデーションを通過しているか確認できます。
タッチとバリデーション
touch() メソッドでフィールドを「タッチ済み」とマークできます(バリデーションは発生しません)。その後、引数なしで validate() を呼び出すと、タッチ済みフィールドすべてをバリデートできます。touched() ヘルパーでフィールドがタッチ済みか確認でき、reset() でタッチ状態をリセットします。
オプション
バリデーションリクエストは自動でデバウンスされます。最初のリクエストは即座に実行され、その後の変更はデフォルトで 1500ms デバウンスされます。setValidationTimeout() でこのタイムアウトを変更可能です。
デフォルトではファイルはバリデーションリクエストから除外され、不要なアップロードを防ぎます。validateFiles() を使うことでファイルバリデーションを有効化できます。
デフォルトでは、バリデーションエラーは文字列(最初のエラーメッセージ)のみ簡略化されます。withAllErrors() を使うと、すべてのエラーを配列として取得可能です。
Precognition が有効な場合、submit() を引数なしで呼び出すと、設定されたエンドポイントに送信されます。
サーバーサイドのレスポンス
Inertia を使う場合、従来の XHR や fetch のようにクライアント側でフォームレスポンスを直接確認することはほとんどありません。代わりに、サーバーサイドのルートやコントローラーでフォーム処理後に リダイレクト を返すのが一般的です。
class UsersController extends Controller
{
public function index()
{
return Inertia::render('Users/Index', [
'users' => User::all(),
]);
}
public function store(Request $request)
{
User::create($request->validate([
'first_name' => ['required', 'max:50'],
'last_name' => ['required', 'max:50'],
'email' => ['required', 'max:50', 'email'],
]));
return to_route('users.index');
}
}このリダイレクトベースのアプローチは、<Form> コンポーネント、useForm ヘルパー、手動ルーター送信のすべてで機能します。Inertia のフォーム処理を従来のサーバーサイドフォーム送信と同じ感覚で扱えます。
サーバーサイドバリデーション
<Form> コンポーネントや useForm ヘルパーは、サーバーサイドのバリデーションエラーを自動で処理します。サーバーがバリデーションエラーを返すと、追加の設定なしで errors オブジェクトで利用可能になります。
従来の XHR や fetch リクエストで 422 ステータスコードをチェックする必要がある場合とは異なり、Inertia はバリデーションエラーをリダイレクトベースのフローの一部として処理します。これは従来のサーバーサイドフォーム送信と同じですが、ページ全体のリロードは発生しません。
エラーバッグや高度なシナリオを含むバリデーションエラーの完全なガイドは、バリデーションのドキュメントをご覧ください。
手動フォーム送信
<Form> コンポーネントや useForm ヘルパーを使わずに、Inertia の router メソッドを直接使ってフォームを手動で送信することも可能です。
ファイルアップロード
ファイルを含むリクエストやフォーム送信を行う場合、Inertia は自動的に送信データを FormData オブジェクトに変換します。これは <Form> コンポーネント、useForm ヘルパー、手動の router 送信すべてで機能します。
進行状況の追跡を含むファイルアップロードの詳細は、ファイルアップロードのドキュメントをご覧ください。
XHR / Fetch 送信
Inertia を使ったフォーム送信はほとんどの状況で問題なく動作します。しかし、フォーム送信の制御をより細かく行いたい場合は、従来の XHR や fetch を使って好きなライブラリで送信することも可能です。