Registration with Wizard Steps

2024-06-08

If you have a longer registration form, you may want to split it into steps, with wizard, including different validation rules.

In this case, we need to create our own Registration class and pass it to the Filament panel provider.

But first, for this demo, we prepare a few extra columns in the users table.

Migration:

Schema::table('users', function (Blueprint $table) {
$table->after('password', function (Blueprint $table) {
$table->string('github')->nullable();
$table->string('twitter')->nullable();
});
});

Also, Model fillable fields.

app/Models/User.php:

class User extends Authenticatable implements FilamentUser
{
protected $fillable = [
'name',
'email',
'password',
'github',
'twitter',
];

Now, we need to create our own Registration page class that would extend Filament\Pages\Auth\Register. And there are a few things we do inside it:

  1. We override the form with our own one, using the same internal functions for name, email, and password, but also add our own second wizard step with Github and Twitter fields.
  2. We remove the default Submit button by returning empty getFormActions() and add our own submitAction() to the Wizard, instead.
  3. We specify $maxWidth so that the wizard properly fits horizontally.

app/Filament/Pages/Registration.php:

namespace App\Filament\Pages;
 
use Filament\Forms\Form;
use Filament\Pages\Auth\Register;
use Illuminate\Support\HtmlString;
use Filament\Forms\Components\Wizard;
use Illuminate\Support\Facades\Blade;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\TextInput;
 
class Registration extends Register
{
protected ?string $maxWidth = '2xl';
 
public function form(Form $form): Form
{
return $form
->schema([
Wizard::make([
Wizard\Step::make('Contact')
->schema([
$this->getNameFormComponent(),
$this->getEmailFormComponent(),
]),
Wizard\Step::make('Social')
->schema([
$this->getGithubFormComponent(),
$this->getTwitterFormComponent(),
]),
Wizard\Step::make('Password')
->schema([
$this->getPasswordFormComponent(),
$this->getPasswordConfirmationFormComponent(),
]),
])->submitAction(new HtmlString(Blade::render(<<<BLADE
<x-filament::button
type="submit"
size="sm"
wire:submit="register"
>
Register
</x-filament::button>
BLADE))),
]);
}
 
protected function getFormActions(): array
{
return [];
}
 
protected function getGithubFormComponent(): Component
{
return TextInput::make('github')
->prefix('https://github.com/')
->label(__('GitHub'))
->maxLength(255);
}
 
protected function getTwitterFormComponent(): Component
{
return TextInput::make('twitter')
->prefix('https://x.com/')
->label(__('Twitter (X)'))
->maxLength(255);
}
}

Finally, we provide this Registration class as a parameter in the Filament provider.

app/Providers/Filament/AdminPanelProvider.php:

use App\Filament\Pages\Registration;
 
// ...
 
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login()
->registration(Registration::class)

A few of our Premium Examples: