How to design a Form Modal in Laravel 12 with vue.js and Inertia.js

How to design a Form Modal in Laravel 12 with Inertia.js

Here’s a complete, step-by-step guide on how to create a modal form to submit feedback in a Laravel 12 application using Inertia.js and Vue.js.

This includes:

  • Creating a feedback model and controller in Laravel
  • Building a modal-based feedback form using Vue 3
  • Submitting data via Inertia
  • Showing success messages

📝 Overview

You’ll learn how to:

  • Set up a feedback table using migrations
  • Display a modal form using Vue.js
  • Submit the form with Inertia’s useForm
  • Store feedback in the database with Laravel

✅ Step 1: Create the Feedback Model and Migration

Run this command:

php artisan make:model Feedback -m

Edit the migration file in database/migrations/xxxx_create_feedback_table.php:

public function up(): void
{
    Schema::create('feedback', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email');
        $table->text('message');
        $table->timestamps();
    });
}

Then run:

php artisan migrate

Update your Feedback model to allow mass assignment:

// app/Models/Feedback.php
protected $fillable = ['name', 'email', 'message'];

🧠 Step 2: Create a Feedback Controller

php artisan make:controller FeedbackController

In app/Http/Controllers/FeedbackController.php:

namespace App\Http\Controllers;

use App\Models\Feedback;
use Illuminate\Http\Request;

class FeedbackController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'email' => 'required|email',
            'message' => 'required|string|min:10',
        ]);

        Feedback::create($validated);

        return back()->with('success', 'Thanks for your feedback!');
    }
}

🛣 Step 3: Add the Route

In routes/web.php:

use App\Http\Controllers\FeedbackController;

Route::post('/feedback', [FeedbackController::class, 'store'])->name('feedback.store');

🎨 Step 4: Create the Modal Feedback Form Component

Create a new Vue component:
resources/js/Components/FeedbackModal.vue

<template>
  <div v-if="show" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
    <div class="bg-white p-6 rounded-lg w-full max-w-md shadow-xl relative">
      <h2 class="text-xl font-bold mb-4">Submit Feedback</h2>

      <form @submit.prevent="submit">
        <div class="mb-3">
          <label>Name</label>
          <input v-model="form.name" type="text" class="border p-2 w-full" />
          <div v-if="form.errors.name" class="text-red-500">{{ form.errors.name }}</div>
        </div>

        <div class="mb-3">
          <label>Email</label>
          <input v-model="form.email" type="email" class="border p-2 w-full" />
          <div v-if="form.errors.email" class="text-red-500">{{ form.errors.email }}</div>
        </div>

        <div class="mb-3">
          <label>Message</label>
          <textarea v-model="form.message" class="border p-2 w-full"></textarea>
          <div v-if="form.errors.message" class="text-red-500">{{ form.errors.message }}</div>
        </div>

        <div class="flex justify-between items-center">
          <button type="button" @click="close" class="text-gray-600">Cancel</button>
          <button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded">Send</button>
        </div>

        <div v-if="success" class="text-green-600 mt-3">{{ success }}</div>
      </form>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { useForm, usePage } from '@inertiajs/vue3'

const props = defineProps({
  show: Boolean,
})

const emit = defineEmits(['close'])

const form = useForm({
  name: '',
  email: '',
  message: '',
})

const success = ref(null)

function submit() {
  form.post('/feedback', {
    onSuccess: () => {
      success.value = 'Thank you for your feedback!'
      setTimeout(() => {
        form.reset()
        close()
      }, 1500)
    },
  })
}

function close() {
  success.value = null
  form.reset()
  emit('close')
}
</script>

🧩 Step 5: Use the Modal in a Page

Let’s now display this modal on a page, like Dashboard.vue.

<template>
  <div class="p-8">
    <h1 class="text-2xl font-bold mb-6">Welcome to the Dashboard</h1>
    <button @click="showModal = true" class="bg-green-600 text-white px-4 py-2 rounded">
      Leave Feedback
    </button>

    <FeedbackModal :show="showModal" @close="showModal = false" />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import FeedbackModal from '@/Components/FeedbackModal.vue'

const showModal = ref(false)
</script>

🧠 Step 6: Share Flash Messages (Optional)

To use flash messages, update app/Http/Middleware/HandleInertiaRequests.php:

public function share(Request $request): array
{
    return array_merge(parent::share($request), [
        'flash' => [
            'success' => fn () => $request->session()->get('success'),
        ],
    ]);
}

✅ Final Output

Now, when the user clicks the “Leave Feedback” button:

  • A modal appears with a form
  • The user submits feedback
  • Laravel stores it in the database
  • The modal shows a success message and closes automatically


Leave a Reply

Your email address will not be published. Required fields are marked *