Execute an action on checkbox toggle

I would like to reset the password and password_confirmation fields when I check or uncheck the checkbox button, so the passwords start from a clean slate all the time. I am not sure if it can be done via Livewire or Alpine somehow or there is an inbuilt functionality inside Filament. My code:
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->live(),

TextInput::make('password')
->dehydrated(fn(Get $get): bool => $get('password') != '')
->live()
->afterStateUpdated(
function (
Forms\Contracts\HasForms $livewire,
Forms\Components\TextInput $component
) {
$livewire->form->getState();
})
->confirmed()
->required()
->label('Password')
->visibleOn('edit')
->hidden(fn(Get $get): bool => !$get('password_change_checkbox')),

TextInput::make('password_confirmation')
->dehydrated(false)
->live()
->afterStateUpdated(
function (
Forms\Contracts\HasForms $livewire,
Forms\Components\TextInput $component
) {
$livewire->form->getState();
})
->required()
->label('Repeat password')
->visibleOn('edit')
->hidden(fn(Get $get): bool => !$get('password_change_checkbox'))
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->live(),

TextInput::make('password')
->dehydrated(fn(Get $get): bool => $get('password') != '')
->live()
->afterStateUpdated(
function (
Forms\Contracts\HasForms $livewire,
Forms\Components\TextInput $component
) {
$livewire->form->getState();
})
->confirmed()
->required()
->label('Password')
->visibleOn('edit')
->hidden(fn(Get $get): bool => !$get('password_change_checkbox')),

TextInput::make('password_confirmation')
->dehydrated(false)
->live()
->afterStateUpdated(
function (
Forms\Contracts\HasForms $livewire,
Forms\Components\TextInput $component
) {
$livewire->form->getState();
})
->required()
->label('Repeat password')
->visibleOn('edit')
->hidden(fn(Get $get): bool => !$get('password_change_checkbox'))
Perhaps adding afterStateUpdated() to Checkbox::make() ? But how to target password and password_confirmation fields only? And make them clear up both when clicking on the checkbox (for both show and hide states)?
3 Replies
Wirkhof
Wirkhof6mo ago
It seems I can add:
->afterStateUpdated(function ($state, callable $set) {
$set('password', null);
$set('password_confirmation', null);
})
->afterStateUpdated(function ($state, callable $set) {
$set('password', null);
$set('password_confirmation', null);
})
to my Checkbox like:
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->afterStateUpdated(function ($state, callable $set) {
$set('password', null);
$set('password_confirmation', null);
})
->live(),
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->afterStateUpdated(function ($state, callable $set) {
$set('password', null);
$set('password_confirmation', null);
})
->live(),
and it seems to clear the content of both password fields. However, the problem is the error message "The passwords didn't match" stays there for some reason when I show the two password fields via toggling of the Checkbox again. Why is the error message not disappearing as well? Can I perhaps $set that specific error message to null as well? Or there is some more Filament-y solotion of this problem of dangling errror messages? Do you think I could perhaps access the error bag via Livewire and remove the error like that, because it seems I can do:
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->afterStateUpdated(function ($state, callable $set) {
$livewire->data['password'] = '';
$livewire->data['password_confirmation'] = '';
})
->live(),
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->afterStateUpdated(function ($state, callable $set) {
$livewire->data['password'] = '';
$livewire->data['password_confirmation'] = '';
})
->live(),
and it will delete the content of password and password_confirmation on toggle. But, again, the red error message about passwords not matching will be there eventhough both fields will be emptied. How to remove that error message as well? I am dd($livewire) but I can't seem to find any error arrays or something. I see $livewire->data but no $livewire->errors. I tried $livewire->clearValidation('password'); $livewire->clearValidation('password_confirmation'); after setting $livewire->data to an empty string, but the error message is still there.
awcodes
awcodes6mo ago
Laravel
Validation | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
Wirkhof
Wirkhof6mo ago
OK, so the issue was in the fact that I didn't call those fields via data.something but just something in the resetErrorBag or perhaps clearValidation. This one is now working perfectly:
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->afterStateUpdated(function ($state, callable $set) {
$livewire->data['password'] = '';
$livewire->data['password_confirmation'] = '';
$livewire->resetErrorBag('data.password');
$livewire->resetErrorBag('data.password_confirmation');
})
->live(),
Checkbox::make('password_change_checkbox')
->label('Change your password')
->visibleOn('edit')
->afterStateUpdated(function ($state, callable $set) {
$livewire->data['password'] = '';
$livewire->data['password_confirmation'] = '';
$livewire->resetErrorBag('data.password');
$livewire->resetErrorBag('data.password_confirmation');
})
->live(),