F
Filament4w ago
Anik

disable wizard next button

Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make('Customer')
->columns(2)
->schema(fn(): array => $this->getStepOneWizardFormSchema())
->afterValidation(fn() => $this->resolveCustomer()),

Forms\Components\Wizard\Step::make('Cart')
->schema(fn(): array => $this->getStepTwoWizardFormSchema())
->afterValidation(fn(Forms\Get $get) => $this->validateCartBeforeCheckout($get)),

Forms\Components\Wizard\Step::make('Checkout')
->schema(fn(): array => $this->getStepThreeWizardFormSchema()),
])
->contained(false)
->columnSpanFull()
->nextAction(
fn(Action $action): Action => $action
// hide the button until we have a $this->customer
->hidden(true)
->disabled(true)
->livewireTarget(null)
),

Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make('Customer')
->columns(2)
->schema(fn(): array => $this->getStepOneWizardFormSchema())
->afterValidation(fn() => $this->resolveCustomer()),

Forms\Components\Wizard\Step::make('Cart')
->schema(fn(): array => $this->getStepTwoWizardFormSchema())
->afterValidation(fn(Forms\Get $get) => $this->validateCartBeforeCheckout($get)),

Forms\Components\Wizard\Step::make('Checkout')
->schema(fn(): array => $this->getStepThreeWizardFormSchema()),
])
->contained(false)
->columnSpanFull()
->nextAction(
fn(Action $action): Action => $action
// hide the button until we have a $this->customer
->hidden(true)
->disabled(true)
->livewireTarget(null)
),

Hello, I noticed that I cannot hide/disable the next button with the wizard nextAction. Can anyone guide me on how to disable the next button until specific conditions are met.
9 Replies
Omar Alnabris
Omar Alnabris4w ago
You could do so in many ways 1. by writing your condition in disable function on next action like: ->disabled(fn (Get $get) => str_starts_with('O', $get('customer_name'))) but make sure to make the corresponding field or step component ->live() 2. Or halt the next action in validation level (when button clicked) as mention in the docs https://filamentphp.com/docs/3.x/forms/layout/wizard#preventing-the-next-step-from-being-loaded 3. You can also make to the button disabled by default and do your logic to enable it in the ->afterStateUpdated() on the step component
->live()
->afterStateUpdated(function ($livewire, Get $get) {
if ($get('customer_name') && str_starts_with('O', $get('customer_name'))) {
$livewire->form->getComponent('my-wizard')->getAction('next')->disabled(false);
}
})
->live()
->afterStateUpdated(function ($livewire, Get $get) {
if ($get('customer_name') && str_starts_with('O', $get('customer_name'))) {
$livewire->form->getComponent('my-wizard')->getAction('next')->disabled(false);
}
})
Add a key for your wizard so you can target it easily ->key('my-wizard')
Anik
AnikOP4w ago
wizard next action button cannot be hidden. I guess it's some kind of bug. Can you please confirm?
->nextAction(
fn(Action $action): Action => $action
// hide the button until we have a $this->customer
->hidden(fn() => true)
// ->disabled(true)
->livewireTarget(null)
),
->nextAction(
fn(Action $action): Action => $action
// hide the button until we have a $this->customer
->hidden(fn() => true)
// ->disabled(true)
->livewireTarget(null)
),
Also, the disabled works and sets the button to disabled css but the click is not disabled and the page mount is rerun. Can you please confirm this as well? It may be a bug with wizard? Thanks for the help. Much appreciated.
Omar Alnabris
Omar Alnabris4w ago
Next action button checks the disable status only and the disable status will effect by hidden status, that's mean the hidden will be considered as disabled. And yes, the disabled function is works as expected, no extra css/js needed.
Anik
AnikOP4w ago
the disabled button is still sending a livewire request on click can you confirm that
Omar Alnabris
Omar Alnabris4w ago
Inspect the next button it should not have x-on:click (alpine event listener) if it disabled check the wizard view component vendor/filament/forms/resources/views/components/wizard.blade.php I have already checked it. if the button is disabled nothing happened on click.
Anik
AnikOP4w ago
<span x-on:click="
$wire.dispatchFormEvent(
'wizard::nextStep',
'data',
getStepIndex(step),
)
" x-show="! isLastStep()">
<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<button style="--c-400:var(--primary-400);--c-500:var(--primary-500);--c-600:var(--primary-600);" class="fi-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus-visible:ring-2 pointer-events-none opacity-70 rounded-lg fi-color-custom fi-btn-color-primary fi-color-primary fi-size-md fi-btn-size-md gap-1.5 px-3 py-2 text-sm inline-grid shadow-sm bg-custom-600 text-white hover:bg-custom-500 focus-visible:ring-custom-500/50 dark:bg-custom-500 dark:hover:bg-custom-400 dark:focus-visible:ring-custom-400/50 fi-ac-action fi-ac-btn-action" disabled="disabled" type="button" wire:loading.attr="disabled">
<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<span class="fi-btn-label">
Next
</span>

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--> <!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->
<!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->
</button>

</span>
<span x-on:click="
$wire.dispatchFormEvent(
'wizard::nextStep',
'data',
getStepIndex(step),
)
" x-show="! isLastStep()">
<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<button style="--c-400:var(--primary-400);--c-500:var(--primary-500);--c-600:var(--primary-600);" class="fi-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus-visible:ring-2 pointer-events-none opacity-70 rounded-lg fi-color-custom fi-btn-color-primary fi-color-primary fi-size-md fi-btn-size-md gap-1.5 px-3 py-2 text-sm inline-grid shadow-sm bg-custom-600 text-white hover:bg-custom-500 focus-visible:ring-custom-500/50 dark:bg-custom-500 dark:hover:bg-custom-400 dark:focus-visible:ring-custom-400/50 fi-ac-action fi-ac-btn-action" disabled="disabled" type="button" wire:loading.attr="disabled">
<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<span class="fi-btn-label">
Next
</span>

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--> <!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->
<!--[if ENDBLOCK]><![endif]-->

<!--[if BLOCK]><![endif]--><!--[if ENDBLOCK]><![endif]-->
</button>

</span>
I just notice the x-on is on the span and not the button. That's why the click is not being disabled and the wizard next step is being called. you can check the livewire call with laravel debugbar.
toeknee
toeknee4w ago
Does $ get work if passed in i.e.
Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make('Customer')
->columns(2)
->schema(fn(): array => $this->getStepOneWizardFormSchema())
->afterValidation(fn() => $this->resolveCustomer()),

Forms\Components\Wizard\Step::make('Cart')
->schema(fn(): array => $this->getStepTwoWizardFormSchema())
->afterValidation(fn(Forms\Get $get) => $this->validateCartBeforeCheckout($get)),

Forms\Components\Wizard\Step::make('Checkout')
->schema(fn(): array => $this->getStepThreeWizardFormSchema()),
])
->contained(false)
->columnSpanFull()
->nextAction(
fn(Action $action, $get): Action => $action
// hide the button until we have a $this->customer
->hidden(true)
->disabled(fn($get) => empty($get('my_field')))
->livewireTarget(null)
),

Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make('Customer')
->columns(2)
->schema(fn(): array => $this->getStepOneWizardFormSchema())
->afterValidation(fn() => $this->resolveCustomer()),

Forms\Components\Wizard\Step::make('Cart')
->schema(fn(): array => $this->getStepTwoWizardFormSchema())
->afterValidation(fn(Forms\Get $get) => $this->validateCartBeforeCheckout($get)),

Forms\Components\Wizard\Step::make('Checkout')
->schema(fn(): array => $this->getStepThreeWizardFormSchema()),
])
->contained(false)
->columnSpanFull()
->nextAction(
fn(Action $action, $get): Action => $action
// hide the button until we have a $this->customer
->hidden(true)
->disabled(fn($get) => empty($get('my_field')))
->livewireTarget(null)
),

Omar Alnabris
Omar Alnabris4w ago
Yes, this is how the next button works x-on:click placed in span tag, and should not exist if you disable the next action. Please check vendor/filament/forms/resources/views/components/wizard.blade.php you may have overwritten it, and if not try to update forms package.
Anik
AnikOP4w ago
Hi, upgrading the forms package solved the issue. It seems it was bug that was fixed
- Upgrading filament/forms (v3.2.115 => v3.3.14): Extracting archive
- Upgrading filament/forms (v3.2.115 => v3.3.14): Extracting archive
disabled() now correctly removes x-on from button span hidden() however still triggered disabled() and doesn't hide the button

Did you find this page helpful?