Filament Form Wizard: Auto-Save Draft After First Step

2024-10-24

When having a wizard form, you might want to save a "draft" record to the DB immediately after the first step. Then the user may come back later to finish editing it. Let me show you how to do it in Filament.


First, all your fields in the migration must be nullable. Next, only the wizard's first step can have the required fields to have at least some data in the form.

Now, to create a record after the first step, we need to use afterValidation() lifecycle hook. In the hook, we will get the data from the form and create a new record. This new record must be saved to a public property so that we would know which record to update later.

If you use panels, all the code goes to the create page class.

Step::make('Personal information')
->schema([
// your form fields
])
->afterValidation(function () {
$data = $this->form->getState();
 
$this->record = new ($this->getModel())($data);
 
$this->record->save();
}),

We update the record on all other steps using the same afterValidation() lifecycle hook.

Step::make('General Information')
->schema([
// your form fields
])
->afterValidation(function () {
$data = $this->form->getState();
 
$this->record->update($data);
}),

The last step is to overwrite the create() page. Of course, Filament creates the record, which we no longer need. We need to update the record instead.

use Filament\Support\Facades\FilamentView;
use function Filament\Support\is_app_url;
 
public function create(bool $another = false): void
{
$data = $this->form->getState();
 
$this->record->update($data);
 
$redirectUrl = $this->getRedirectUrl();
 
$this->redirect($redirectUrl, navigate: FilamentView::hasSpaMode() && is_app_url($redirectUrl));
}

A few of our Premium Examples: