How to Create a Laravel Multi Step Form
In many cases, to give user little bit of flexibility and ease, you may need to create a multi-step form. Today we will learn how to do that in Laravel. So let’s get started. Let’s break down how to create a multi-step form in Laravel. First we will do the database stuff like migration, table structure etc. Then we will register our routes in web.php file and write our controller logic. Finally, we will do the view stuff. Be with us.
1. Database Setup:
If you’re want to store the form data, you’ll need a database table. Let’s assume you’re collecting user information like name, mail address and address, so our migration file will look like this:
// Migration (database/migrations/create_users_table.php) use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name')->nullable(); // From step 1 $table->string('email')->nullable(); // From step 2 $table->string('address')->nullable(); // From step 3 $table->timestamps(); }); } // ... down() method };
2. Routes register:
Routes: we will need two route, one for showing the multi step form, one for storing the data in DB.
use App\Http\Controllers\MultiStepFormController; // Create this controller Route::get('/multi-step-form', [MultiStepFormController::class, 'index'])->name('multi-step-form.index'); Route::post('/multi-step-form', [MultiStepFormController::class, 'store'])->name('multi-step-form.store');
3. Controller logic:
To support our routes, we will create two controller method, one for viewing the form and another for storing the form data. First one is “index” and for showing the form. it will by default take the first step as one because we are setting it like this:
$step = $request->input('step', 1); // Default to step 1
Also you can see session is being used here, just think of it as temporary data. Because before storing it to database, we must need to store it in some local storage, in this case we are using session. Then we are returning the form.
Finally there is store function. You have to closely look for the view file and store logic together. From the view file (available in next step), we are receiving step variable. Also we are receiving the form data from the session storage. After that we are validating each step data with predefined rules for name, email and address. Then we are merging all data to a array called $data. To store these data in DB, we are creating a new User object and saving to the DB. Finally we are clearing the current session and redirecting the user to specific target.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; // If you have a User model class MultiStepFormController extends Controller { public function index(Request $request) { $step = $request->input('step', 1); // Default to step 1 $data = $request->session()->get('form_data', []); // Store data in session return view('multi-step-form', compact('step', 'data')); } public function store(Request $request) { $step = $request->input('step'); $data = $request->session()->get('form_data', []); // Validate data for the current step (Important!) $rules = []; switch ($step) { case 1: $rules = ['name' => 'required|string|max:255']; break; case 2: $rules = ['email' => 'required|email|max:255']; break; case 3: $rules = ['address' => 'required|string|max:255']; break; } $validatedData = $request->validate($rules); // Merge validated data into the session $data = array_merge($data, $validatedData); $request->session()->put('form_data', $data); if ($step < 3) { // 3 is the last step return redirect()->route('multi-step-form.index', ['step' => $step + 1]); } else { // All steps complete, save to database $user = new User(); // Or User::create($data); if you have mass assignment set up $user->name = $data['name']; $user->email = $data['email']; $user->address = $data['address']; $user->save(); $request->session()->forget('form_data'); // Clear session data return redirect()->route('multi-step-form.index')->with('success', 'Form submitted successfully!'); } } }
4. View File: Below is the pretty simple view file containing the fields for multi step form.
<!DOCTYPE html> <html> <head> <title>Multi-Step Form</title> </head> <body> <h1>Multi-Step Form</h1> @if (session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif <form method="POST" action="{{ route('multi-step-form.store') }}"> @csrf <input type="hidden" name="step" value="{{ $step }}"> @if ($step == 1) <div> <label for="name">Name:</label> <input type="text" name="name" id="name" value="{{ $data['name'] ?? '' }}" required> @error('name') <div class="alert alert-danger">{{ $message }}</div> @enderror </div> @elseif ($step == 2) <div> <label for="email">Email:</label> <input type="email" name="email" id="email" value="{{ $data['email'] ?? '' }}" required> @error('email') <div class="alert alert-danger">{{ $message }}</div> @enderror </div> @elseif ($step == 3) <div> <label for="address">Address:</label> <input type="text" name="address" id="address" value="{{ $data['address'] ?? '' }}" required> @error('address') <div class="alert alert-danger">{{ $message }}</div> @enderror </div> @endif <button type="submit"> @if ($step < 3) Next @else Submit @endif </button> @if ($step > 1) <a href="{{ route('multi-step-form.index', ['step' => $step - 1]) }}">Previous</a> @endif </form> </body> </html>
Key Improvements and Explanations:
- Session Storage: Form data is stored in the session (
$request->session()
) so it’s preserved between steps. - Validation: Crucially, validation is performed for each step. This prevents incomplete or incorrect data from being submitted. The example uses a
switch
statement for step-specific validation rules. - Clear Session: After successful submission, the session data is cleared (
$request->session()->forget('form_data')
). - Error Handling: The
@error
directives in the Blade template display validation errors. - Previous Button: Added a “Previous” button to allow users to go back and correct information.
- Database Storage: Shows how to save the data to the database using a model.
- Route Naming: Using named routes (
route('multi-step-form.index')
) makes the code more maintainable.
What we can do for further enhancements:
- JavaScript for Client-Side Validation/UX: Consider adding JavaScript for a smoother user experience (e.g., real-time validation, progress indicators).
- More Robust Validation: Use more complex validation rules as needed.
- Conditional Logic: You might need to show/hide fields based on previous answers. JavaScript or conditional logic in your Blade templates can handle this.
- Packages: For very complex forms, you might consider a package like
spatie/laravel-data
to help manage the data flow.
This comprehensive example provides a basic foundation for building multi-step forms in Laravel. Modify it to your specific requirements/needs and add styling as needed. Let me know if you have any other questions!
Check Out More Resources:
Articles:
Website: https://laravelplug.com/
YouTube Channel: https://www.youtube.com/channel/UCnTxncHQcBSNs4RCuhWgF-A?sub_confirmation=1
WordPress Playlist: https://www.youtube.com/watch?v=8VvXzFAFwQU&list=PLVoVZqAh8dTLHZ51egvEU7dsOrRCSIMWx
Tools Playlist: https://www.youtube.com/watch?v=gTQoUn3BQkM&list=PLVoVZqAh8dTK-DWHBGWOEEvzvPQrgFne-
WordPress Tutorials: https://laravelplug.com/category/wordpress/
Laravel Tutorials: https://laravelplug.com/category/laravel/
PHP Tutorials: https://laravelplug.com/category/php/
SQL Tutorials: https://laravelplug.com/category/sql/
Various Tips: https://laravelplug.com/category/tips/
Useful Tools: https://laravelplug.com/category/tools/
Socials:
Twitter: https://twitter.com/LaravelPlug
Pinterest: https://www.pinterest.com/LaravelPlugCom/
Facebook: https://www.facebook.com/groups/1020759861842360
Mail: info@laravelplug.com
#Laravel #sql #mysql
That’s All. Feel free to knock me. Thanks.