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.
No comments yet…