フォーム

フォームの送信

Inertiaで従来のHTMLフォーム送信を行うことは可能ですが、フルページリロードが発生するため、推奨されません。代わりに、フォーム送信をインターセプトし、 Inertiaを使ってリクエストを行うのが良いでしょう。.

<script setup>
import { reactive } from 'vue'
import { router } from '@inertiajs/vue3'

const form = reactive({
  first_name: null,
  last_name: null,
  email: null,
})

function submit() {
  router.post('/users', form)
}
</script>

<template>
  <form @submit.prevent="submit">
    <label for="first_name">First name:</label>
    <input id="first_name" v-model="form.first_name" />
    <label for="last_name">Last name:</label>
    <input id="last_name" v-model="form.last_name" />
    <label for="email">Email:</label>
    <input id="email" v-model="form.email" />
    <button type="submit">Submit</button>
  </form>
</template>

上記の例でお気づきかもしれませんが、Inertiaを使用する場合、XHR/fetchリクエストを手動で行う場合のように、クライアント側でフォームのレスポンスを検査する必要は通常ありません。

代わりに、サーバー側のルート/コントローラーは通常、リダイレクトレスポンスを発行します。そしてもちろん、ユーザーを以前にいたページにリダイレクトすることを妨げるものは何もありません。このアプローチを使用すると、Inertiaフォームの送信処理は、従来のHTMLフォームの送信処理と非常に似たものになります。

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');
    }
}

サーバーサイドバリデーション

Inertiaでのサーバーサイドバリデーションエラーの処理は、手動XHR/fetchリクエストからのエラーの処理とは少し異なります。XHR/fetchリクエストを行う場合、通常は422ステータスコードのレスポンスを検査し、フォームのエラーステートを手動で更新します。

ただし、Inertiaを使用する場合、422レスポンスがサーバーから返されることはありません。代わりに、上記の例で見たように、ルート/コントローラーは通常、従来的なフルページフォーム送信と非常によく似たリダイレクトレスポンスを返します。

Inertiaでのバリデーションエラーの処理と表示に関する詳細については、 バリデーションのドキュメントを参照してください。

フォームヘルパー

フォームの操作は非常に一般的なため、Inertiaには、一般的なフォーム送信の処理に必要なボイラープレートコードの量を削減するのに役立つように設計されたフォームヘルパーが含まれています。

<script setup>
import { useForm } from '@inertiajs/vue3'

const form = useForm({
  email: null,
  password: null,
  remember: false,
})
</script>

<template>
  <form @submit.prevent="form.post('/login')">
    <!-- email -->
    <input type="text" v-model="form.email">
    <div v-if="form.errors.email">{{ form.errors.email }}</div>
    <!-- password -->
    <input type="password" v-model="form.password">
    <div v-if="form.errors.password">{{ form.errors.password }}</div>
    <!-- remember me -->
    <input type="checkbox" v-model="form.remember"> Remember Me
    <!-- submit -->
    <button type="submit" :disabled="form.processing">Login</button>
  </form>
</template>

フォームを送信するには、getpostputpatchdeleteメソッドを使用できます。

form.submit(method, url, options)
form.get(url, options)
form.post(url, options)
form.put(url, options)
form.patch(url, options)
form.delete(url, options)

submitメソッドは、訪問オプションのすべてをサポートしています。たとえば、 preserveStatepreserveScroll、およびイベントコールバックなどがあり、フォーム送信が成功した場合のタスクを実行するのに役立ちます。たとえば、onSuccessコールバックを使用して、入力を元の状態にリセットすることができます。

form.post('/profile', {
  preserveScroll: true,
  onSuccess: () => form.reset('password'),
})

フォームデータをサーバーに送信する前に変更する必要がある場合は、 transform()メソッドを使用します。

form
  .transform((data) => ({
    ...data,
    remember: data.remember ? 'on' : '',
  }))
  .post('/login')

processingプロパティを使用して、フォームが現在送信中かどうかを追跡できます。これは、送信ボタンを無効にすることで、二重フォーム送信を防ぐのに役立ちます。

<button type="submit" :disabled="form.processing">Submit</button>

フォームがファイルをアップロードしている場合、現在の進捗イベントはprogressプロパティから利用できるため、アップロードの進捗状況を簡単に表示できます。

<progress v-if="form.progress" :value="form.progress.percentage" max="100">
  {{ form.progress.percentage }}%
</progress>

フォームのバリデーションエラーがある場合は、errorsプロパティから利用できます。Laravelを利用したInertiaアプリケーションを構築する場合、$request->validate()を使用した場合など、アプリケーションがValidationExceptionのインスタンスをスローすると、フォームエラーが自動的に入力されます。

<div v-if="form.errors.email">{{ form.errors.email }}</div>
フォームのバリデーションとエラーの詳細については、 バリデーションのドキュメントを参照してください。.

フォームにエラーがあるかどうかを判断するには、hasErrorsプロパティを使用できます。フォームのエラーをクリアするには、clearErrors()メソッドを使用します。

// Clear all errors...
form.clearErrors()

// Clear errors for specific fields...
form.clearErrors('field', 'anotherfield')

クライアント側の入力バリデーションライブラリを使用している場合や、クライアント側で手動でバリデーションを行う場合は、setErrors()メソッドを使用してフォームに独自のエラーを設定できます。

// Set a single error...
form.setError('field', 'Your error message.');

// Set multiple errors at once...
form.setError({
  foo: 'Your error message for the foo field.',
  bar: 'Some other error for the bar field.'
});
実際フォーム送信とは異なり、フォームインスタンスにエラーを手動で設定する場合、ページのpropsは変更されません。

フォームが正常に送信されると、wasSuccessfulプロパティはtrueになります。これに加えて、フォームにはrecentlySuccessfulプロパティがあり、 フォームが正常に送信された後、2秒間trueに設定されます。このプロパティは、一時的な成功メッセージを表示するために利用できます。

フォームの値をデフォルト値に戻すには、reset()メソッドを使用します。

// Reset the form...
form.reset()

// Reset specific fields...
form.reset('field', 'anotherfield')

フォームのデフォルト値が古くなった場合は、defaults()メソッドを使用して更新できます。すると、次回reset()メソッドが呼び出されたときに、フォームは正しい値にリセットされます。

// Set the form's current values as the new defaults...
form.defaults()

// Update the default value of a single field...
form.defaults('email', 'updated-default@example.com')

// Update the default value of multiple fields...
form.defaults({
  name: 'Updated Example',
  email: 'updated-default@example.com',
})

フォームに変更があるかどうかを判断するには、isDirtyプロパティを使用できます。

<div v-if="form.isDirty">There are unsaved form changes.</div>

フォーム送信をキャンセルするには、cancel()メソッドを使用します。

form.cancel()

Inertiaにフォームのデータとエラーを履歴状態に保存するように指示するには、フォームをインスタンス化するときに、最初の引数として一意のフォームキーを指定できます。

import { useForm } from '@inertiajs/vue3'

const form = useForm('CreateUser', data)
const form = useForm(`EditUser:${user.id}`, data)

ファイルアップロード

ファイルを含むリクエストまたはフォーム送信を行う場合、Inertiaは自動的にリクエストデータをFormDataオブジェクトに変換します。

ファイルアップロードの詳細については、 ファイルアップロードのドキュメントを参照してください。.

XHR/fetch送信

Inertiaを使用してフォームを送信する方法は、ほとんどの場合にうまく機能しますが、フォーム送信をより詳細に制御する必要がある場合は、お好みのライブラリを使用して、プレーンなXHRまたはfetchリクエストを自由に行うことができます。