F
Filament2mo ago
nowak

When using the Tabs layout in custom page, how can I make an action react to tab changes?

I have a form with a tab layout, with 3 tabs and 3 action buttons. Now I want to make sure that only one action shows for each tab. This is my Tabs layout schema:
protected function getFormSchema(): array
{
return [
Tabs::make('Settings')
->tabs([
Tabs\Tab::make('Business Hours')
->schema($this->businessHoursSchema())
->columns(1),
Tabs\Tab::make('General')
->schema($this->generalSchema())
->columns(1),
Tabs\Tab::make('Billing')
->schema($this->billingSchema())
->columns(1),
])
->persistTabInQueryString()
->id('settings-tabs'),
];
}
protected function getFormSchema(): array
{
return [
Tabs::make('Settings')
->tabs([
Tabs\Tab::make('Business Hours')
->schema($this->businessHoursSchema())
->columns(1),
Tabs\Tab::make('General')
->schema($this->generalSchema())
->columns(1),
Tabs\Tab::make('Billing')
->schema($this->billingSchema())
->columns(1),
])
->persistTabInQueryString()
->id('settings-tabs'),
];
}
Where I attempted to fetch the current tab from the url parameter and hide my actions conditionally like this:
public function getFormActions(): array
{

$currentTab = request()->query('tab', 'settings-tabs-business-hours-tab');
return [
Action::make('saveBusinessHours')
->label('Save Business Hours')
->action(fn () => $this->saveBusinessHours())
->hidden(fn () => $currentTab !== 'settings-tabs-business-hours-tab'),
Action::make('saveGeneralSettings')
->label('Save General Settings')
->action(fn () => $this->saveGeneralSettings())
->hidden(fn () => $currentTab !== 'settings-tabs-general-tab'),
Action::make('saveBillingSettings')
->label('Save Billing Settings')
->action(fn () => $this->saveBillingSettings())
->hidden(fn () => $currentTab !== 'settings-tabs-billing-tab'),
];
}
public function getFormActions(): array
{

$currentTab = request()->query('tab', 'settings-tabs-business-hours-tab');
return [
Action::make('saveBusinessHours')
->label('Save Business Hours')
->action(fn () => $this->saveBusinessHours())
->hidden(fn () => $currentTab !== 'settings-tabs-business-hours-tab'),
Action::make('saveGeneralSettings')
->label('Save General Settings')
->action(fn () => $this->saveGeneralSettings())
->hidden(fn () => $currentTab !== 'settings-tabs-general-tab'),
Action::make('saveBillingSettings')
->label('Save Billing Settings')
->action(fn () => $this->saveBillingSettings())
->hidden(fn () => $currentTab !== 'settings-tabs-billing-tab'),
];
}
This only works on page load, but not when I change the tabs dynamically. How can I make this work when switching tabs dynamically?
9 Replies
nowak
nowak2mo ago
bump
dissto
dissto2mo ago
Curious, can you not just use $this->activeTab ?
nowak
nowak2mo ago
No because it's not the same tabs, unless I am mistaken. The activeTab is set by the getTabs() method, not by the Tab layout
awcodes
awcodes2mo ago
You can probably inject $livewire in the hidden() callback and check the active tab directly off the livewire component.
nowak
nowak2mo ago
You mean adding $livewire directly to the hidden() callback like this:
Action::make('saveBusinessHours')
->label('Save Business Hours')
->action(fn () => $this->saveBusinessHours())
->hidden(function ($livewire, $currentTab) {
\Log::info("Hiding Tab Actions", ['livewire' => $livewire]);

return $currentTab !== 'settings-tabs-business-hours-tab';
}),
Action::make('saveBusinessHours')
->label('Save Business Hours')
->action(fn () => $this->saveBusinessHours())
->hidden(function ($livewire, $currentTab) {
\Log::info("Hiding Tab Actions", ['livewire' => $livewire]);

return $currentTab !== 'settings-tabs-business-hours-tab';
}),
The log output gives me this:
{
"App\\Filament\\Pages\\ManageSettingsNew": {
"mountedActions": [],
"mountedActionsArguments": [],
"mountedActionsData": [],
"defaultAction": null,
"defaultActionArguments": null,
"componentFileAttachments": [],
"mountedFormComponentActions": [],
"mountedFormComponentActionsArguments": [],
"mountedFormComponentActionsData": [],
"mountedFormComponentActionsComponents": [],
"mountedInfolistActions": [],
"mountedInfolistActionsData": [],
"mountedInfolistActionsComponent": null,
"mountedInfolistActionsInfolist": null,
"data": {
"business_hours": {
"c4b9ae01-7ade-4095-8405-305823da07cc": {
"day": "Monday",
"opens_at": "14:00",
"closes_at": "19:00",
"is_closed": false
},
},
"site_name": "My Awesome Site",
"billing_cycle": "bimonthly"
},
"savedDataHash": "88f37a53dd2b0b9626b2b0098ede5a62"
}
}
{
"App\\Filament\\Pages\\ManageSettingsNew": {
"mountedActions": [],
"mountedActionsArguments": [],
"mountedActionsData": [],
"defaultAction": null,
"defaultActionArguments": null,
"componentFileAttachments": [],
"mountedFormComponentActions": [],
"mountedFormComponentActionsArguments": [],
"mountedFormComponentActionsData": [],
"mountedFormComponentActionsComponents": [],
"mountedInfolistActions": [],
"mountedInfolistActionsData": [],
"mountedInfolistActionsComponent": null,
"mountedInfolistActionsInfolist": null,
"data": {
"business_hours": {
"c4b9ae01-7ade-4095-8405-305823da07cc": {
"day": "Monday",
"opens_at": "14:00",
"closes_at": "19:00",
"is_closed": false
},
},
"site_name": "My Awesome Site",
"billing_cycle": "bimonthly"
},
"savedDataHash": "88f37a53dd2b0b9626b2b0098ede5a62"
}
}
I couldn't find anything about the tab info, should I use $livewire differently? I don't know if it changes anything, but I am doing this in a custom page class ManageSettingsNew extends Page
awcodes
awcodes2mo ago
Well, yea. That’s kinda what I was getting at, but in a custom page the tabs are probably not tied to the page which is the livewire component.
nowak
nowak2mo ago
But the url parameters still update, is there no way to tap into that and react to the change from my custom page? Or do I have to write my own blade view for this?
awcodes
awcodes2mo ago
If it’s in the query, livewire should still have knowledge of it. Check the livewire docs for reading the query string.
nowak
nowak2mo ago
I can't seem to get it to work with the query parameters :/ I think I might have to use ->persistTab() instead of ->persistTabInQueryString() , as it seems this would store the tab in memory. I am just trying to figure out how to tab into this as well.