Courses

Vue Laravel 12 Starter Kit: CRUD Project

Create Form with Inertia Form Helper

Summary of this lesson:
- Creating a "Create Task" button and page
- Building form structure with useForm inertia hook
- Implementing form submission and validation handling

The final part of this simple CRUD is Create and Edit forms. They will be similar, with a few differences. Let's start with adding a new task.


Link to Create Task Page

First, let's add a link above the table to lead to the Route for creating the task.

In the Laravel Routes, we have Route::resource('tasks', TaskController::class), so we need to link to the /tasks/create URL.

To do that in our Index.vue, we import the Link component and add this button-style link above the table.

resources/js/pages/Tasks/Index.vue

import {Head, router} from '@inertiajs/vue3';
import {Head, router, Link} from '@inertiajs/vue3';
import {Button} from '@/components/ui/button';
import {Button, buttonVariants} from '@/components/ui/button';
 
// ...
 
<Head title="Tasks List"/>
 
<div class="mt-4">
<Link
:class="buttonVariants({variant: 'outline'})" href="/tasks/create"> Create Task
</Link>
</div>
 
<Table class="mt-4">

This is the visual result:

Now, let's build the page for the Create form.


Create Task: Empty "Skeleton" Page

In the Controller, we have this:

app/Http/Controllers/TaskController.php:

public function create()
{
return Inertia::render('Tasks/Create');
}

So, we need to create the appropriate Vue component. For now, let's hard-code some text inside.

resources/js/pages/Tasks/Create.vue:

<script setup lang="ts">
import AppLayout from '@/layouts/AppLayout.vue';
import {Head} from '@inertiajs/vue3';
</script>
 
<template>
<AppLayout>
<Head title="Create Task"/>
<div class="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">Form will be here.</div>
</AppLayout>
</template>

Now, when we click the "Create Task" link/button, we will see this:

Now, let's build the actual form. It will have only one input element: task name. But even for that, we will create a more complex structure, so you will learn the general process of how to build forms in Vue + Inertia.


Inertia useForm()

First, we need to import and use a useForm from Inertia Vue.

resources/js/pages/Tasks/Create.vue:

import {Head} from '@inertiajs/vue3';
import {Head, useForm} from '@inertiajs/vue3';
 
// ...
 
const form = useForm({
name: '',
});

Build the Form HTML

This is our HTML+JS code using the already pre-installed Shadcn components.

resources/js/pages/Tasks/Create.vue:

 
<script setup lang="ts">
import InputError from '@/components/InputError.vue';
import {Button} from '@/components/ui/button';
import {Input} from '@/components/ui/input';
import {Label} from '@/components/ui/label';
import AppLayout from '@/layouts/AppLayout.vue';
import {Head, useForm} from '@inertiajs/vue3';
 
const form = useForm({
name: '',
});
</script>
 
<template>
<AppLayout>
<Head title="Create Task"/>
<div class="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
<form class="space-y-6">
<div class="grid gap-2">
<Label htmlFor="name">Task Name *</Label>
 
<Input id="name" v-model="form.name" class="mt-1 block w-full"/>
 
<InputError :message="form.errors.name"/>
</div>
 
<div class="flex items-center gap-4">
<Button :disabled="form.processing" variant="default">Create Task</Button>
</div>
</form>
</div>
</AppLayout>
</template>

Here's the visual result!


Form Submit Action and Validation

Finally, we need to define what happens after the form is submitted.

A reminder of what we have in Controller:

app/Http/Controllers/TaskController.php:

public function store(StoreTaskRequest $request)
{
Task::create($request->validated() + ['is_completed' => false]);
 
return redirect()->route('tasks.index');
}

In the Vue component, we create a method that calls the Laravel route of tasks.store and passes the data from the form.

resources/js/pages/Tasks/Create.vue:

<script setup lang="ts">
// ...
 
const submitForm = () => {
form.post(route('tasks.store'), {
preserveScroll: true,
});
};
</script>
 
<template>
<AppLayout>
<Head title="Create Task"/>
<div class="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
<form class="space-y-6">
<form class="space-y-6"
@submit.prevent="submitForm">
// ...

The code should be pretty readable and self-explanatory. You may have seen the taskName variable above, and it may make sense from this piece of code: it's used to refocus that input in case of validation errors.

Speaking of validation errors, they will work automatically, coming from the back-end Controller, shown with the <InputError> component:

But if we pass a valid task name, we get redirected to the table, where we see our new task!

Here's the GitHub commit for this lesson.


In the next lesson, we will build the Edit Task form.

Previous: Delete Task and Shadcn Vue Toast Notification

No comments yet…

avatar
You can use Markdown