Our form doesn't have validation, so let's add it in this lesson.
First, let's add the validation on the back-end. For this, we will use Form Request.
php artisan make:request StorePostRequest
app/Http/Requests/StorePostRequest.php:
class StorePostRequest extends FormRequest{ public function authorize(): bool { return true; } public function rules(): array { return [ 'title' => 'required|min:3', 'content' => 'required', ]; }}
app/Http/Controllers/PostController.php:
use App\Http\Requests\StorePostRequest; class PostController extends Controller{ // ... public function store(Request $request): RedirectResponse public function store(StorePostRequest $request): RedirectResponse { Post::create([ 'title' => $request->input('title'), 'content' => $request->input('content'), ]); Post::create($request->validated()); return redirect()->route('posts.index'); }}
We don't need anything else on the back-end.
For the front-end, there are a couple of ways to get errors. One way is to get errors from the form helper.
resources/js/Pages/Posts/Create.jsx:
import AppLayout from '../../Layouts/AppLayout.jsx';import { Head, Link, useForm } from '@inertiajs/react'; export default function CreatePost() { // ... return ( <AppLayout> <Head title="New Post" /> <div> <form onSubmit={submit}> <div> <label htmlFor="title" className="block text-sm font-medium text-gray-700">Title</label> <input onChange={(e) => setData('title', e.target.value)} type="text" id="title" className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" /> { errors.title && (<p className="mt-2 text-sm text-red-600">{errors.title}</p>)} </div> <div className="mt-4"> <label htmlFor="content" className="block text-sm font-medium text-gray-700">Content</label> <textarea onChange={(e) => setData('content', e.target.value)} type="text" id="content" className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"></textarea> { errors.content && (<p className="mt-2 text-sm text-red-600">{errors.content}</p>)} </div> <div className="mt-4 py-4 space-x-2"> <button type="submit" className="inline-block rounded-md bg-blue-500 px-4 py-3 text-xs font-semibold uppercase tracking-widest text-white shadow-sm"> Save post </button> <Link href={route('posts.index')} className="inline-block rounded-md border border-gray-300 px-4 py-3 text-xs font-semibold uppercase tracking-widest shadow-sm"> Cancel </Link> </div> </form> </div> </AppLayout> );}
It's that simple. We can see the validation message in the front-end.
Another feature of the Inertia form helper is that we can easily disable the submit button to prevent multiple submits.
If the back-end takes a while to process the form, you can disable the button. Form helper have a processing
method.
resources/js/Pages/Posts/Create.jsx:
import AppLayout from '../../Layouts/AppLayout.jsx';import { Head, Link, useForm } from '@inertiajs/react'; export default function CreatePost() { // ... return ( <AppLayout> <Head title="New Post" /> <div> <form onSubmit={submit}> // ... <div className="mt-4 py-4 space-x-2"> <button type="submit" className="inline-block rounded-md bg-blue-500 px-4 py-3 text-xs font-semibold uppercase tracking-widest text-white shadow-sm"> <button disabled={processing} type="submit" className="inline-block rounded-md bg-blue-500 px-4 py-3 text-xs font-semibold uppercase tracking-widest text-white shadow-sm disabled:opacity-25"> Save post </button> <Link href={route('posts.index')} className="inline-block rounded-md border border-gray-300 px-4 py-3 text-xs font-semibold uppercase tracking-widest shadow-sm"> Cancel </Link> </div> </form> </div> </AppLayout> );}
For example, we could add sleep in the Controller to make the request longer.
app/Http/Controllers/PostController.php:
class PostController extends Controller{ // ... public function store(StorePostRequest $request): RedirectResponse { sleep(2); Post::create($request->validated()); return redirect()->route('posts.index'); }}
After pressing the Save post
button, you cannot click it again.