Readouble

Laravel 11.x Precognition

イントロダクションIntroduction

Laravel Precognition(プリコグニション:予知)により、将来のHTTPリクエストの結果を予測できます。Precognitionの主な使用例の1つは、アプリケーションのバックエンドのバリデーションルールを複製せずとも、フロントエンドのJavaScriptアプリケーションの「ライブ」バリデーションを提供する能力です。Precognitionは、LaravelのInertiaベースのスターターキットと特に相性がよいです。Laravel Precognition allows you to anticipate the outcome of a future HTTP request. One of the primary use cases of Precognition is the ability to provide "live" validation for your frontend JavaScript application without having to duplicate your application's backend validation rules. Precognition pairs especially well with Laravel's Inertia-based starter kits[/docs/{{version}}/starter-kits].

Laravelが「事前認識型リクエスト」を受け取ると、ルートのミドルウェアをすべて実行し、フォームリクエストのバリデーションを含む、ルートのコントローラの依存解決を行いますが、実際にはルートのコントローラメソッドを実行しません。When Laravel receives a "precognitive request", it will execute all of the route's middleware and resolve the route's controller dependencies, including validating form requests[/docs/{{version}}/validation#form-request-validation] - but it will not actually execute the route's controller method.

ライブバリデーションLive Validation

Vueの使用Using Vue

Laravel Precognitionを使用すると、フロントエンドのVueアプリケーションでバリデーションルールを複製することなく、ユーザーにライブバリデーション体験を提供できます。その仕組みを説明するため、アプリケーション内で新規ユーザーを作成するためのフォームを作成してみましょう。Using Laravel Precognition, you can offer live validation experiences to your users without having to duplicate your validation rules in your frontend Vue application. To illustrate how it works, let's build a form for creating new users within our application.

最初に、ルートに対するPrecognitionを有効にするには、ルート定義へHandlePrecognitiveRequestsミドルウェアを追加する必要があります。さらに、ルートのバリデーションルールを格納するため、フォームリクエストを作成する必要もあります。First, to enable Precognition for a route, the HandlePrecognitiveRequests middleware should be added to the route definition. You should also create a form request[/docs/{{version}}/validation#form-request-validation] to house the route's validation rules:

use App\Http\Requests\StoreUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;

Route::post('/users', function (StoreUserRequest $request) {
    // ...
})->middleware([HandlePrecognitiveRequests::class]);

次に、Vue用のLaravel PrecognitionフロントエンドヘルパをNPMにより、インストールします。Next, you should install the Laravel Precognition frontend helpers for Vue via NPM:

npm install laravel-precognition-vue

LaravelのPrecognitionパッケージをインストールすれば、PrecognitionのuseForm関数を使用して、HTTPメソッド(post)、ターゲットURL(/users)、初期フォームデータを指定して、フォームオブジェクトを作成できるようになります。With the Laravel Precognition package installed, you can now create a form object using Precognition's useForm function, providing the HTTP method (post), the target URL (/users), and the initial form data.

次に、ライブバリデーションを有効にするには、各入力の change イベントでフォームのvalidateメソッドを起動し、入力名を指定します。Then, to enable live validation, invoke the form's validate method on each input's change event, providing the input's name:

<script setup>
import { useForm } from 'laravel-precognition-vue';

const form = useForm('post', '/users', {
    name: '',
    email: '',
});

const submit = () => form.submit();
</script>

<template>
    <form @submit.prevent="submit">
        <label for="name">Name</label>
        <input
            id="name"
            v-model="form.name"
            @change="form.validate('name')"
        />
        <div v-if="form.invalid('name')">
            {{ form.errors.name }}
        </div>

        <label for="email">Email</label>
        <input
            id="email"
            type="email"
            v-model="form.email"
            @change="form.validate('email')"
        />
        <div v-if="form.invalid('email')">
            {{ form.errors.email }}
        </div>

        <button :disabled="form.processing">
            Create User
        </button>
    </form>
</template>

これで、フォームがユーザーにより入力されると、Precognitionはルートのフォームリクエストのバリデーションルールに従い、ライブバリデーション出力を提供します。フォームの入力が変更されると、デバウンスされた「事前認識型」バリデーションリクエストをLaravelアプリケーションへ送信します。デバウンスのタイムアウトは、フォームの setValidationTimeout 関数を呼び出すことで設定できます。Now, as the form is filled by the user, Precognition will provide live validation output powered by the validation rules in the route's form request. When the form's inputs are changed, a debounced "precognitive" validation request will be sent to your Laravel application. You may configure the debounce timeout by calling the form's setValidationTimeout function:

form.setValidationTimeout(3000);

バリデーション要求がやり取り中の場合、フォームのvalidatingプロパティはtrue になります。When a validation request is in-flight, the form's validating property will be true:

<div v-if="form.validating">
    Validating...
</div>

バリデーションリクエストやフォーム送信時に返される全てのバリデーションエラーは、自動的にフォームのerrorsオブジェクトへ格納します。Any validation errors returned during a validation request or a form submission will automatically populate the form's errors object:

<div v-if="form.invalid('email')">
    {{ form.errors.email }}
</div>

フォームにエラーがあるかは、フォームのhasErrorsプロパティで判断できます。You can determine if the form has any errors using the form's hasErrors property:

<div v-if="form.hasErrors">
    <!-- ... -->
</div>

また、入力がバリデーションに合格したか失敗したかを判断するには、入力名をフォームのvalid関数かinvalid関数へ渡してください。You may also determine if an input has passed or failed validation by passing the input's name to the form's valid and invalid functions, respectively:

<span v-if="form.valid('email')">
    ✅
</span>

<span v-else-if="form.invalid('email')">
    ❌
</span>

warning Warning! フォーム入力が変更され、バリデーションレスポンスを受信した時点で、初めて有効または無効として表示されます。[!WARNING]
A form input will only appear as valid or invalid once it has changed and a validation response has been received.

Precognitionでフォームの入力のサブセットをバリデートしている場合、エラーを手作業でクリアできると便利です。それには、フォームのforgetError関数を使用します。If you are validating a subset of a form's inputs with Precognition, it can be useful to manually clear errors. You may use the form's forgetError function to achieve this:

<input
    id="avatar"
    type="file"
    @change="(e) => {
        form.avatar = e.target.files[0]

        form.forgetError('avatar')
    }"
>

これまで見てきたように、入力のchangeイベントをフックし、ユーザーが入力した内容を検証できます。これは「ウィザード」を作成するときによくあり、次のステップに進む前に、ユーザーが入力操作をしたかにかかわらず、目に見えるすべての入力を検証したい場合などです。As we have seen, you can hook into an input's change event and validate individual inputs as the user interacts with them; however, you may need to validate inputs that the user has not yet interacted with. This is common when building a "wizard", where you want to validate all visible inputs, whether the user has interacted with them or not, before moving to the next step.

Precognitionでこれを行うには、検証したいフィールドの名前をtouchメソッドへ渡し、「変更済み(touched)」とマークします。それから、onSuccessonValidationErrorコールバックでvalidateメソッドを呼び出てください。To do this with Precognition, you should mark the fields you wish to validate as "touched" by passing their names to the touch method. Then, call the validate method with onSuccess or onValidationError callbacks:

<button
    type="button"
    @click="form.touch(['name', 'email', 'phone']).validate({
        onSuccess: (response) => nextStep(),
        onValidationError: (response) => /* ... */,
    })"
>Next Step</button>

もちろん、フォーム送信に対するレスポンスに反応してコードを実行することもできます。フォームのsubmit関数は、AxiosのリクエストPromiseを返します。これは、レスポンスペイロードへのアクセス、送信成功時のフォーム入力のリセット、または失敗したリクエストの処理に便利な方法を提供します。Of course, you may also execute code in reaction to the response to the form submission. The form's submit function returns an Axios request promise. This provides a convenient way to access the response payload, reset the form inputs on successful submission, or handle a failed request:

const submit = () => form.submit()
    .then(response => {
        form.reset();

        alert('User created.');
    })
    .catch(error => {
        alert('An error occurred.');
    });

フォームのprocessingプロパティを調べれば、フォーム送信リクエストが処理中か判断できます。You may determine if a form submission request is in-flight by inspecting the form's processing property:

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

VueとInertiaの使用Using Vue and Inertia

lightbulb Note: VueとInertiaを使ってLaravelアプリケーションを開発するとき、有利に開始したい場合は、スターターキットの一つを使うことを検討してください。Laravelのスターターキットは、新しいLaravelアプリケーションにバックエンドとフロントエンドの認証へスカフォールドを提供します。[!NOTE]
If you would like a head start when developing your Laravel application with Vue and Inertia, consider using one of our starter kits[/docs/{{version}}/starter-kits]. Laravel's starter kits provide backend and frontend authentication scaffolding for your new Laravel application.

VueとInertiaと一緒にPrecognitionを使用する前に、より一般的なVueでPrecognitionを使用するドキュメントを必ず確認してください。VueをInertiaで使用する場合、NPM経由でInertia互換のPrecognitionライブラリーをインストールする必要があります。Before using Precognition with Vue and Inertia, be sure to review our general documentation on using Precognition with Vue[#using-vue]. When using Vue with Inertia, you will need to install the Inertia compatible Precognition library via NPM:

npm install laravel-precognition-vue-inertia

一度インストールしたら、PrecognitionのuseForm関数は、上で説明したバリデーション機能で強化した、Inertiaフォームヘルパを返します。Once installed, Precognition's useForm function will return an Inertia form helper[https://inertiajs.com/forms#form-helper] augmented with the validation features discussed above.

フォームヘルパのsubmitメソッドが効率化され、HTTPメソッドやURLを指定する必要がなくなりました。その代わりに、Inertiaのvisitオプションを最初で唯一の引数として渡してください。また、submitメソッドは、上記のVueの例で見られるように、Promiseを返すことはありません。代わりに、Inertiaがサポートしているイベントコールバックsubmitメソッドへ指定するvisitオプションに指定します。The form helper's submit method has been streamlined, removing the need to specify the HTTP method or URL. Instead, you may pass Inertia's visit options[https://inertiajs.com/manual-visits] as the first and only argument. In addition, the submit method does not return a Promise as seen in the Vue example above. Instead, you may provide any of Inertia's supported event callbacks[https://inertiajs.com/manual-visits#event-callbacks] in the visit options given to the submit method:

<script setup>
import { useForm } from 'laravel-precognition-vue-inertia';

const form = useForm('post', '/users', {
    name: '',
    email: '',
});

const submit = () => form.submit({
    preserveScroll: true,
    onSuccess: () => form.reset(),
});
</script>

Reactの使用Using React

Laravel Precognitionを使用すると、フロントエンドのReactアプリケーションへバリデーションルールを複製することなく、ユーザーにライブバリデーション体験を提供できます。その仕組みを説明するため、アプリケーション内で新規ユーザーを作成するためのフォームを作成してみましょう。Using Laravel Precognition, you can offer live validation experiences to your users without having to duplicate your validation rules in your frontend React application. To illustrate how it works, let's build a form for creating new users within our application.

最初に、ルートに対するPrecognitionを有効にするには、ルート定義へHandlePrecognitiveRequestsミドルウェアを追加する必要があります。さらに、ルートのバリデーションルールを格納するため、フォームリクエストを作成する必要もあります。First, to enable Precognition for a route, the HandlePrecognitiveRequests middleware should be added to the route definition. You should also create a form request[/docs/{{version}}/validation#form-request-validation] to house the route's validation rules:

use App\Http\Requests\StoreUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;

Route::post('/users', function (StoreUserRequest $request) {
    // ...
})->middleware([HandlePrecognitiveRequests::class]);

次に、React用のLaravel PrecognitionフロントエンドヘルパをNPMによりインストールします。Next, you should install the Laravel Precognition frontend helpers for React via NPM:

npm install laravel-precognition-react

LaravelのPrecognitionパッケージをインストールすれば、PrecognitionのuseForm関数を使用して、HTTPメソッド(post)、ターゲットURL(/users)、初期フォームデータを指定して、フォームオブジェクトを作成できるようになります。With the Laravel Precognition package installed, you can now create a form object using Precognition's useForm function, providing the HTTP method (post), the target URL (/users), and the initial form data.

ライブバリデーションを有効にするには、各入力のchangeイベントとblurイベントをリッスンする必要があります。changeイベントハンドラでは、setData関数でフォームのデータをセットし、入力名と新しい値を渡します。次に、blurイベントハンドラで、入力名を指定し、フォームのvalidateメソッドを呼び出します。To enable live validation, you should listen to each input's change and blur event. In the change event handler, you should set the form's data with the setData function, passing the input's name and new value. Then, in the blur event handler invoke the form's validate method, providing the input's name:

import { useForm } from 'laravel-precognition-react';

export default function Form() {
    const form = useForm('post', '/users', {
        name: '',
        email: '',
    });

    const submit = (e) => {
        e.preventDefault();

        form.submit();
    };

    return (
        <form onSubmit={submit}>
            <label htmlFor="name">Name</label>
            <input
                id="name"
                value={form.data.name}
                onChange={(e) => form.setData('name', e.target.value)}
                onBlur={() => form.validate('name')}
            />
            {form.invalid('name') && <div>{form.errors.name}</div>}

            <label htmlFor="email">Email</label>
            <input
                id="email"
                value={form.data.email}
                onChange={(e) => form.setData('email', e.target.value)}
                onBlur={() => form.validate('email')}
            />
            {form.invalid('email') && <div>{form.errors.email}</div>}

            <button disabled={form.processing}>
                Create User
            </button>
        </form>
    );
};

これで、フォームがユーザーにより入力されると、Precognitionはルートのフォームリクエストのバリデーションルールに従い、ライブバリデーション出力を提供します。フォームの入力が変更されると、デバウンスされた「事前認識型」バリデーションリクエストをLaravelアプリケーションへ送信します。デバウンスのタイムアウトは、フォームの setValidationTimeout 関数を呼び出すことで設定できます。Now, as the form is filled by the user, Precognition will provide live validation output powered by the validation rules in the route's form request. When the form's inputs are changed, a debounced "precognitive" validation request will be sent to your Laravel application. You may configure the debounce timeout by calling the form's setValidationTimeout function:

form.setValidationTimeout(3000);

バリデーション要求がやり取り中の場合、フォームのvalidatingプロパティはtrue になります。When a validation request is in-flight, the form's validating property will be true:

{form.validating && <div>Validating...</div>}

バリデーションリクエストやフォーム送信時に返される全てのバリデーションエラーは、自動的にフォームのerrorsオブジェクトへ格納します。Any validation errors returned during a validation request or a form submission will automatically populate the form's errors object:

{form.invalid('email') && <div>{form.errors.email}</div>}

フォームにエラーがあるかは、フォームのhasErrorsプロパティで判断できます。You can determine if the form has any errors using the form's hasErrors property:

{form.hasErrors && <div><!-- ... --></div>}

また、入力がバリデーションに合格したか失敗したかを判断するには、入力名をフォームのvalid関数かinvalid関数へ渡してください。You may also determine if an input has passed or failed validation by passing the input's name to the form's valid and invalid functions, respectively:

{form.valid('email') && <span>✅</span>}

{form.invalid('email') && <span>❌</span>}

warning Warning! フォーム入力が変更され、バリデーションレスポンスを受信した時点で、初めて有効または無効として表示されます。[!WARNING]
A form input will only appear as valid or invalid once it has changed and a validation response has been received.

Precognitionでフォームの入力のサブセットをバリデートしている場合、エラーを手作業でクリアできると便利です。それには、フォームのforgetError関数を使用します。If you are validating a subset of a form's inputs with Precognition, it can be useful to manually clear errors. You may use the form's forgetError function to achieve this:

<input
    id="avatar"
    type="file"
    onChange={(e) => {
        form.setData('avatar', e.target.value);

        form.forgetError('avatar');
    }}
>

これまで見てきたように、入力のblurイベントをフックして、ユーザーが入力を操作したときに個々の入力を検証できます。これは「ウィザード」を作成するときによくあり、次のステップに進む前に、ユーザーが入力操作したかにかかわらず、目に見えるすべての入力を検証したい場合などです。As we have seen, you can hook into an input's blur event and validate individual inputs as the user interacts with them; however, you may need to validate inputs that the user has not yet interacted with. This is common when building a "wizard", where you want to validate all visible inputs, whether the user has interacted with them or not, before moving to the next step.

Precognitionでこれを行うには、検証したいフィールドの名前をtouchメソッドへ渡し、「変更済み(touched)」とマークします。それから、onSuccessonValidationErrorコールバックでvalidateメソッドを呼び出てください。To do this with Precognition, you should mark the fields you wish to validate as "touched" by passing their names to the touch method. Then, call the validate method with onSuccess or onValidationError callbacks:

<button
    type="button"
    onClick={() => form.touch(['name', 'email', 'phone']).validate({
        onSuccess: (response) => nextStep(),
        onValidationError: (response) => /* ... */,
    })}
>Next Step</button>

もちろん、フォーム送信に対するレスポンスに反応してコードを実行することもできます。フォームのsubmit関数は、AxiosのリクエストPromiseを返します。これは、レスポンスペイロードへのアクセス、送信成功時のフォーム入力のリセット、または失敗したリクエストの処理に便利な方法を提供します。Of course, you may also execute code in reaction to the response to the form submission. The form's submit function returns an Axios request promise. This provides a convenient way to access the response payload, reset the form's inputs on a successful form submission, or handle a failed request:

const submit = (e) => {
    e.preventDefault();

    form.submit()
        .then(response => {
            form.reset();

            alert('User created.');
        })
        .catch(error => {
            alert('An error occurred.');
        });
};

フォームのprocessingプロパティを調べれば、フォーム送信リクエストが処理中か判断できます。You may determine if a form submission request is in-flight by inspecting the form's processing property:

<button disabled={form.processing}>
    Submit
</button>

ReactとInertiaの使用Using React and Inertia

lightbulb Note: ReactとInertiaを使ってLaravelアプリケーションを開発するとき、有利に開始したい場合は、スターターキットの一つを使うことを検討してください。Laravelのスターターキットは、新しいLaravelアプリケーションにバックエンドとフロントエンドの認証へスカフォールドを提供します。[!NOTE]
If you would like a head start when developing your Laravel application with React and Inertia, consider using one of our starter kits[/docs/{{version}}/starter-kits]. Laravel's starter kits provide backend and frontend authentication scaffolding for your new Laravel application.

ReactとInertiaと一緒にPrecognitionを使用する前に、より一般的なVueでPrecognitionを使用するドキュメントを必ず確認してください。VueをInertiaで使用する場合、NPM経由でInertia互換のPrecognitionライブラリーをインストールする必要があります。Before using Precognition with React and Inertia, be sure to review our general documentation on using Precognition with React[#using-react]. When using React with Inertia, you will need to install the Inertia compatible Precognition library via NPM:

npm install laravel-precognition-react-inertia

一度インストールしたら、PrecognitionのuseForm関数は、上で説明したバリデーション機能で強化した、Inertiaフォームヘルパを返します。Once installed, Precognition's useForm function will return an Inertia form helper[https://inertiajs.com/forms#form-helper] augmented with the validation features discussed above.

フォームヘルパのsubmitメソッドが効率化され、HTTPメソッドやURLを指定する必要がなくなりました。その代わりに、Inertiaのvisitオプションを最初で唯一の引数として渡してください。また、submitメソッドは、上記のReactの例で見られるように、Promiseを返すことはありません。代わりに、Inertiaがサポートしているイベントコールバックsubmitメソッドへ指定するvisitオプションに指定します。The form helper's submit method has been streamlined, removing the need to specify the HTTP method or URL. Instead, you may pass Inertia's visit options[https://inertiajs.com/manual-visits] as the first and only argument. In addition, the submit method does not return a Promise as seen in the React example above. Instead, you may provide any of Inertia's supported event callbacks[https://inertiajs.com/manual-visits#event-callbacks] in the visit options given to the submit method:

import { useForm } from 'laravel-precognition-react-inertia';

const form = useForm('post', '/users', {
    name: '',
    email: '',
});

const submit = (e) => {
    e.preventDefault();

    form.submit({
        preserveScroll: true,
        onSuccess: () => form.reset(),
    });
};

AlpineとBladeの使用Using Alpine and Blade

Laravel Precognitionを使用し、フロントエンドのAlpineアプリケーションでバリデーションルールを複製しなくても、ユーザーへライブバリデーション体験を提供することができます。その仕組みを説明するために、アプリケーション内で新規ユーザーを作成するフォームを作成してみましょう。Using Laravel Precognition, you can offer live validation experiences to your users without having to duplicate your validation rules in your frontend Alpine application. To illustrate how it works, let's build a form for creating new users within our application.

最初に、ルートに対するPrecognitionを有効にするには、ルート定義へHandlePrecognitiveRequestsミドルウェアを追加する必要があります。さらに、ルートのバリデーションルールを格納するため、フォームリクエストを作成する必要もあります。First, to enable Precognition for a route, the HandlePrecognitiveRequests middleware should be added to the route definition. You should also create a form request[/docs/{{version}}/validation#form-request-validation] to house the route's validation rules:

use App\Http\Requests\CreateUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;

Route::post('/users', function (CreateUserRequest $request) {
    // ...
})->middleware([HandlePrecognitiveRequests::class]);

次に、Alpine用のLaravel PrecognitionフロントエンドヘルパをNPMでインストールします。Next, you should install the Laravel Precognition frontend helpers for Alpine via NPM:

npm install laravel-precognition-alpine

それから、PrecognitionプラグインをAlpineへ登録するために、resources/js/app.jsファイルへ登録します。Then, register the Precognition plugin with Alpine in your resources/js/app.js file:

import Alpine from 'alpinejs';
import Precognition from 'laravel-precognition-alpine';

window.Alpine = Alpine;

Alpine.plugin(Precognition);
Alpine.start();

Laravel Precognitionパッケージをインストール、登録した状態で、Precognitionの$formの「マジック」を使い、HTTPメソッド(post)、ターゲットURL(/users)、初期フォームデータを指定してフォームオブジェクトを作成できるようになりました。With the Laravel Precognition package installed and registered, you can now create a form object using Precognition's $form "magic", providing the HTTP method (post), the target URL (/users), and the initial form data.

ライブバリデーションを有効にするため、フォームのデータを関連する入力と結合し、各入力のchangeイベントをリッスンする必要があります。changeイベントハンドラは、フォームのvalidateメソッドを呼び出し、入力名を指定する必要があります。To enable live validation, you should bind the form's data to its relevant input and then listen to each input's change event. In the change event handler, you should invoke the form's validate method, providing the input's name:

<form x-data="{
    form: $form('post', '/register', {
        name: '',
        email: '',
    }),
}">
    @csrf
    <label for="name">Name</label>
    <input
        id="name"
        name="name"
        x-model="form.name"
        @change="form.validate('name')"
    />
    <template x-if="form.invalid('name')">
        <div x-text="form.errors.name"></div>
    </template>

    <label for="email">Email</label>
    <input
        id="email"
        name="email"
        x-model="form.email"
        @change="form.validate('email')"
    />
    <template x-if="form.invalid('email')">
        <div x-text="form.errors.email"></div>
    </template>

    <button :disabled="form.processing">
        Create User
    </button>
</form>

これで、フォームがユーザーにより入力されると、Precognitionはルートのフォームリクエストのバリデーションルールに従い、ライブバリデーション出力を提供します。フォームの入力が変更されると、デバウンスされた「事前認識型」バリデーションリクエストをLaravelアプリケーションへ送信します。デバウンスのタイムアウトは、フォームの setValidationTimeout 関数を呼び出すことで設定できます。Now, as the form is filled by the user, Precognition will provide live validation output powered by the validation rules in the route's form request. When the form's inputs are changed, a debounced "precognitive" validation request will be sent to your Laravel application. You may configure the debounce timeout by calling the form's setValidationTimeout function:

form.setValidationTimeout(3000);

バリデーション要求がやり取り中の場合、フォームのvalidatingプロパティはtrue になります。When a validation request is in-flight, the form's validating property will be true:

<template x-if="form.validating">
    <div>Validating...</div>
</template>

バリデーションリクエストやフォーム送信時に返される全てのバリデーションエラーは、自動的にフォームのerrorsオブジェクトへ格納します。Any validation errors returned during a validation request or a form submission will automatically populate the form's errors object:

<template x-if="form.invalid('email')">
    <div x-text="form.errors.email"></div>
</template>

フォームにエラーがあるかは、フォームのhasErrorsプロパティで判断できます。You can determine if the form has any errors using the form's hasErrors property:

<template x-if="form.hasErrors">
    <div><!-- ... --></div>
</template>

また、入力がバリデーションに合格したか失敗したかを判断するには、入力名をフォームのvalid関数かinvalid関数へ渡してください。You may also determine if an input has passed or failed validation by passing the input's name to the form's valid and invalid functions, respectively:

<template x-if="form.valid('email')">
    <span>✅</span>
</template>

<template x-if="form.invalid('email')">
    <span>❌</span>
</template>

warning Warning! フォーム入力が変更され、バリデーションレスポンスを受信した時点で、初めて有効または無効として表示されます。[!WARNING]
A form input will only appear as valid or invalid once it has changed and a validation response has been received.

これまで見てきたように、入力のchangeイベントをフックし、ユーザーが入力した内容を検証できます。これは「ウィザード」を作成するときによくあり、次のステップに進む前に、ユーザーが入力操作をしたかにかかわらず、目に見えるすべての入力を検証したい場合などです。As we have seen, you can hook into an input's change event and validate individual inputs as the user interacts with them; however, you may need to validate inputs that the user has not yet interacted with. This is common when building a "wizard", where you want to validate all visible inputs, whether the user has interacted with them or not, before moving to the next step.

Precognitionでこれを行うには、検証したいフィールドの名前をtouchメソッドへ渡し、「変更済み(touched)」とマークします。それから、onSuccessonValidationErrorコールバックでvalidateメソッドを呼び出てください。To do this with Precognition, you should mark the fields you wish to validate as "touched" by passing their names to the touch method. Then, call the validate method with onSuccess or onValidationError callbacks:

<button
    type="button"
    @change="form.touch(['name', 'email', 'phone']).validate({
        onSuccess: (response) => nextStep(),
        onValidationError: (response) => /* ... */,
    })"
>Next Step</button>

フォームのprocessingプロパティを調べれば、フォーム送信リクエストが処理中か判断できます。You may determine if a form submission request is in-flight by inspecting the form's processing property:

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

直前のフォームデータの再取得Repopulating Old Form Data

前述のユーザー作成の例では、Precognitionを使用してライブバリデーションを実行しています。しかし、フォームを送信するために従来のサーバサイドフォーム送信を実行しています。そのため、フォームにはサーバサイドのフォーム送信から返された「古い」入力やバリデーションエラーを保持しているでしょう。In the user creation example discussed above, we are using Precognition to perform live validation; however, we are performing a traditional server-side form submission to submit the form. So, the form should be populated with any "old" input and validation errors returned from the server-side form submission:

<form x-data="{
    form: $form('post', '/register', {
        name: '{{ old('name') }}',
        email: '{{ old('email') }}',
    }).setErrors({{ Js::from($errors->messages()) }}),
}">

他の方法として、XHRでフォームを送信したい場合は、Axiosリクエストプロミスを返す、フォームのsubmit関数を使用します。Alternatively, if you would like to submit the form via XHR you may use the form's submit function, which returns an Axios request promise:

<form
    x-data="{
        form: $form('post', '/register', {
            name: '',
            email: '',
        }),
        submit() {
            this.form.submit()
                .then(response => {
                    form.reset();

                    alert('User created.')
                })
                .catch(error => {
                    alert('An error occurred.');
                });
        },
    }"
    @submit.prevent="submit"
>

Axiosの設定Configuring Axios

Precognitionのバリデーションライブラリは、Axios HTTPクライアントを使用して、アプリケーションのバックエンドにリクエストを送信します。使いやすいように、アプリケーションで必要であれば、Axiosインスタンスをカスタマイズできます。例えば、laravel-precognition-vueライブラリを使用する場合、アプリケーションのresources/js/app.jsファイル内の各送信リクエストへ、リクエストヘッダを追加できます。The Precognition validation libraries use the Axios[https://github.com/axios/axios] HTTP client to send requests to your application's backend. For convenience, the Axios instance may be customized if required by your application. For example, when using the laravel-precognition-vue library, you may add additional request headers to each outgoing request in your application's resources/js/app.js file:

import { client } from 'laravel-precognition-vue';

client.axios().defaults.headers.common['Authorization'] = authToken;

もしくは、すでにアプリケーション用に設定したAxiosインスタンスがある場合は、代わりにそのインスタンスを使用するようにPrecognitionへ指示することもできます。Or, if you already have a configured Axios instance for your application, you may tell Precognition to use that instance instead:

import Axios from 'axios';
import { client } from 'laravel-precognition-vue';

window.axios = Axios.create()
window.axios.defaults.headers.common['Authorization'] = authToken;

client.use(window.axios)

warning Warning! Inertia的なPrecognitionライブラリでは、設定したAxiosインスタンスのみをバリデーションリクエストに使用します。フォーム送信は常にInertiaが送信します。[!WARNING]
The Inertia flavored Precognition libraries will only use the configured Axios instance for validation requests. Form submissions will always be sent by Inertia.

バリデーションルールのカスタマイズCustomizing Validation Rules

リクエストのisPrecognitiveメソッドを使用すれば、事前認識型リクエスト時に実行するバリデーションルールをカスタマイズできます。It is possible to customize the validation rules executed during a precognitive request by using the request's isPrecognitive method.

例えば、ユーザー作成フォームにおいて、最終的なフォーム送信時にのみ、パスワードの「データ漏洩」をバリデートしたい場合があります。事前認識型のバリデーションリクエストでは、パスワードが必須であることと、最低8文字であることをバリデートします。isPrecognitiveメソッドを使用すると、フォームリクエストで定義されたルールをカスタマイズできます。For example, on a user creation form, we may want to validate that a password is "uncompromised" only on the final form submission. For precognitive validation requests, we will simply validate that the password is required and has a minimum of 8 characters. Using the isPrecognitive method, we can customize the rules defined by our form request:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;

class StoreUserRequest extends FormRequest
{
    /**
     * リクエストへ適用するバリデーションルールの取得
     *
     * @return array
     */
    protected function rules()
    {
        return [
            'password' => [
                'required',
                $this->isPrecognitive()
                    ? Password::min(8)
                    : Password::min(8)->uncompromised(),
            ],
            // ...
        ];
    }
}

ファイルアップロードの処理Handling File Uploads

Laravel Precognitionは、事前認識型バリデーションリクエスト中にファイルのアップロードや検証をデフォルトでは行いません。これにより、大きなファイルが不必要に何度もアップロードされないようにしています。By default, Laravel Precognition does not upload or validate files during a precognitive validation request. This ensure that large files are not unnecessarily uploaded multiple times.

この振る舞いのため、アプリケーションで対応するフォームリクエストのバリデーションルールをカスタマイズすることで、完全なフォーム送信にのみ、このフィールドが必要であることを指定する必要があります。Because of this behavior, you should ensure that your application customizes the corresponding form request's validation rules[#customizing-validation-rules] to specify the field is only required for full form submissions:

/**
 * このリクエストに適用するバリデーションルールの取得
 *
 * @return array
 */
protected function rules()
{
    return [
        'avatar' => [
            ...$this->isPrecognitive() ? [] : ['required'],
            'image',
            'mimes:jpg,png',
            'dimensions:ratio=3/2',
        ],
        // ...
    ];
}

すべてのバリデーションリクエストへファイルを含めたい場合は、クライアント側のフォームインスタンスでvalidateFiles関数を呼び出します。If you would like to include files in every validation request, you may invoke the validateFiles function on your client-side form instance:

form.validateFiles();

副作用の管理Managing Side-Effects

HandlePrecognitiveRequestsミドルウェアをルートに追加する場合、他のミドルウェアで事前認識型リクエスト時にスキップすべき副作用があるかどうかを検討する必要があります。When adding the HandlePrecognitiveRequests middleware to a route, you should consider if there are any side-effects in other middleware that should be skipped during a precognitive request.

例えば、各ユーザーがアプリケーションとやり取りした「操作」の総数を増加させるミドルウェアがあり、事前認識型リクエストは操作としてカウントしたくない場合です。これを実現するには、操作数を増やす前にリクエストのisPrecognitiveメソッドをチェックする必要があるでしょう。For example, you may have a middleware that increments the total number of "interactions" each user has with your application, but you may not want precognitive requests to be counted as an interaction. To accomplish this, we may check the request's isPrecognitive method before incrementing the interaction count:

<?php

namespace App\Http\Middleware;

use App\Facades\Interaction;
use Closure;
use Illuminate\Http\Request;

class InteractionMiddleware
{
    /**
     * 受信リクエストの処理
     */
    public function handle(Request $request, Closure $next): mixed
    {
        if (! $request->isPrecognitive()) {
            Interaction::incrementFor($request->user());
        }

        return $next($request);
    }
}

テストTesting

もしテスト内で事前認識型リクエストを行いたい場合、LaravelのTestCasePrecognitionリクエストヘッダを追加するwithPrecognitionヘルパがあります。If you would like to make precognitive requests in your tests, Laravel's TestCase includes a withPrecognition helper which will add the Precognition request header.

さらに、事前認識型リクエストが成功したこと、例えばバリデーションエラーを返さないことを宣言したい場合は、レスポンスのassertSuccessfulPrecognitionメソッドを使用します。Additionally, if you would like to assert that a precognitive request was successful, e.g., did not return any validation errors, you may use the assertSuccessfulPrecognition method on the response:

Pest
it('validates registration form with precognition', function () {
    $response = $this->withPrecognition()
        ->post('/register', [
            'name' => 'Taylor Otwell',
        ]);

    $response->assertSuccessfulPrecognition();

    expect(User::count())->toBe(0);
});
PHPUnit
public function test_it_validates_registration_form_with_precognition()
{
    $response = $this->withPrecognition()
        ->post('/register', [
            'name' => 'Taylor Otwell',
        ]);

    $response->assertSuccessfulPrecognition();
    $this->assertSame(0, User::count());
}

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作