simple laravel step-by-step wizard
Version | Laravel Version | Php Version |
---|---|---|
^1.6 | >= 7.0 | ^7.3 || ^8.0 |
^1.4 | 6. || 7. || 8.* | ^7.2 || ^8.0 |
1.1 | 5.* | ^7.0 |
$ composer require smajti1/laravel-wizard
add routes
use App\Http\Controllers\UserWizardController;
Route::get('wizard/user/{step?}', [UserWizardController::class, 'wizard'])->name('wizard.user');
Route::post('wizard/user/{step}', [UserWizardController::class, 'wizardPost'])->name('wizard.user.post');
create steps
add autoload field in composer.json file:
...
"autoload": {
"psr-4": {
...
"App\\Wizard\\Steps\\": "app/Steps"
},
...
regenerate autoloader
$ composer dump-autoload
create step app/Steps/SetUserNameStep.php
namespace App\Wizard\Steps;
class SetUserNameStep extends \Smajti1\Laravel\Step
{
public static $label = 'Set user name';
public static $slug = 'set-user-name';
public static $view = 'wizard.user.steps._set_user_name';
public function process(\Illuminate\Http\Request $request)
{
// for example, create user
...
// next if you want save one step progress to session use
$this->saveProgress($request);
}
public function rules(\Illuminate\Http\Request $request = null): array
{
return [
'username' => 'required|min:4|max:255',
];
}
}
create controller
public $steps = [
'set-username-key' => SetUserNameStep::class,
SetPhoneStep::class,
...
];
protected $wizard;
public function __construct()
{
$this->wizard = new Wizard($this->steps, $sessionKeyName = 'user');
}
public function wizard($step = null)
{
try {
if (is_null($step)) {
$step = $this->wizard->firstOrLastProcessed();
} else {
$step = $this->wizard->getBySlug($step);
}
} catch (StepNotFoundException $e) {
abort(404);
}
return view('wizard.user.base', compact('step'));
}
public function wizardPost(Request $request, $step = null)
{
try {
$step = $this->wizard->getBySlug($step);
} catch (StepNotFoundException $e) {
abort(404);
}
$this->validate($request, $step->rules($request));
$step->process($request);
return redirect()->route('wizard.user', [$this->wizard->nextSlug()]);
}
add base view $wizard variable is now automatic sheared with view
<ol>
@foreach($wizard->all() as $key => $_step)
<li>
@if($step->index == $_step->index)
<strong>{{ $_step::$label }}</strong>
@elseif($step->index > $_step->index)
<a href="https://github.com/smajti1/laravel-wizard/blob/master/{{ route('wizard.user', [$_step::$slug]) }}">{{ $_step::$label }}</a>
@else
{{ $_step::$label }}
@endif
</li>
@endforeach
</ol>
<form action="{{ route('wizard.user.post', [$step::$slug]) }}" method="POST">
{{ csrf_field() }}
@include($step::$view, compact('step', 'errors'))
@if ($wizard->hasPrev())
<a href="https://github.com/smajti1/laravel-wizard/blob/master/{{ route('wizard.user', ['step' => $wizard->prevSlug()]) }}">Back</a>
@else
<a href="#">Back</a>
@endif
<span>Step {{ $step->number }}/{{ $wizard->limit() }}</span>
@if ($wizard->hasNext())
<button type="submit">Next</button>
@else
<button type="submit">Done</button>
@endif
</form>
Laravel wizard is open-sourced software licensed under the MIT license