@fzoltan87 You can use Tabs Layout to organize your forms by placing related fields under different tabs.
Nov 22, 2024
4
Level 1
Filament 3 Custom Page with multi form in tabs
How can I make my three different forms appear under three separate tabs? Where should I place the tabs and the forms associated with each tab?
They would like to achieve this appearance: Tab1 -> $this->settingForm Tab2 -> $this->emailForm Tab3 -> $this->themeForm
My Code: class PageSettings extends Page implements HasForms { use InteractsWithForms;
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.page-setting';
public function getTitle(): string | Htmlable
{
return __('module_names.page_setting_label');
}
// public static function getNavigationGroup(): string
// {
// return __('module_names.navigation_groups.pagesfix');
// }
public static function getNavigationLabel(): string
{
return __('module_names.page_setting_label');
}
public function getHeading(): string
{
return __('module_names.page_setting_label');
}
public ?array $data_setting = [];
public ?array $data_setting_email = [];
public ?array $data_setting_theme = [];
public function mount(): void
{
// $this->form->fill($this->getSetting());
$this->fillForms();
}
protected function getForms(): array
{
return [
'settingForm',
'emailForm',
'themeForm',
];
}
public function settingForm(Form $form): Form
{
return $form
->schema([
TextInput::make('app_name')
->label(__('fields.settings.app_name'))
->required(),
Fieldset::make('Google Analytics')->schema([
Select::make('google_analytic_status')
->label(__('fields.settings.google_analytic_status'))
->placeholder('Selected'),
TextInput::make('google_analytic_id')
->label(__('fields.settings.google_analytic_id'))
->required(),
])->columns(3),
Fieldset::make('Social')->schema([
TextInput::make('social_link_fc')
->label(__('fields.settings.social_link_fc'))
->prefix('https://')
->suffixIcon('heroicon-m-globe-alt')
->required(),
TextInput::make('social_link_insta')
->label(__('fields.settings.social_link_insta'))
->prefix('https://')
->suffixIcon('heroicon-m-globe-alt')
->required(),
TextInput::make('social_link_tiktok')
->label(__('fields.settings.social_link_tiktok'))
->prefix('https://')
->suffixIcon('heroicon-m-globe-alt')
->required(),
])->columns(3),
])
->model($this->getSetting())
->statePath('data_setting');
}
public function emailForm(Form $form): Form
{
return $form
->schema([
TextInput::make('email_host')
->label(__('fields.settings.email_host'))
->required(),
TextInput::make('email_email')
->label(__('fields.settings.email_email'))
->required(),
TextInput::make('email_smtp_user')
->label(__('fields.settings.email_smtp_user'))
->required(),
TextInput::make('email_smtp_password')
->label(__('fields.settings.email_smtp_password'))
->required(),
TextInput::make('email_port')
->label(__('fields.settings.email_port'))
->required(),
])
->model($this->getEmailSetting())
->statePath('data_setting_email');
}
public function themeForm(Form $form): Form
{
return $form
->schema([
Grid::make()->schema([
ColorPicker::make('cookie_consent_bg_color')
->label(__('fields.settings.cookie_consent_bg_color'))
->required(),
ColorPicker::make('cookie_consent_b_color')
->label(__('fields.settings.cookie_consent_b_color'))
->required(),
ColorPicker::make('cookie_consent_btn_color')
->label(__('fields.settings.cookie_consent_btn_color'))
->required(),
ColorPicker::make('cookie_consent_btn_text_color')
->label(__('fields.settings.cookie_consent_btn_text_color'))
->required(),
ColorPicker::make('cookie_consent_text_color')
->label(__('fields.settings.cookie_consent_text_color'))
->required(),
])->columns(5),
Grid::make()->schema([
TextInput::make('cookie_consent_link_text')
->label(__('fields.settings.cookie_consent_link_text'))
->required(),
TextInput::make('cookie_consent_btn_text')
->label(__('fields.settings.cookie_consent_btn_text'))
->required(),
])->columns(2),
Textarea::make('cookie_consent_msg')
->label(__('fields.settings.cookie_consent_msg'))
->rows(5)
->columnSpanFull(),
Fieldset::make('Lapozás')->schema([
TextInput::make('pagination_blog')
->label(__('fields.settings.pagination_blog'))
->suffix(new HtmlString(__('fields.quantity')))
->required(),
TextInput::make('pagination_comment')
->label(__('fields.settings.pagination_comment'))
->suffix(new HtmlString(__('fields.quantity')))
->required(),
TextInput::make('pagination_property')
->label(__('fields.settings.pagination_property'))
->suffix(new HtmlString(__('fields.quantity')))
->required(),
])->columns(3),
Fieldset::make('Lábléc')->schema([
TextInput::make('footer_email')
->label(__('fields.settings.footer_email'))
->required(),
TextInput::make('footer_phone')
->label(__('fields.settings.footer_phone'))
->required(),
TextInput::make('footer_address')
->label(__('fields.settings.footer_address'))
->required(),
])->columns(3),
])
->model($this->getThemeSetting())
->statePath('data_setting_theme');
}
protected function getFormActions(): array
{
return [
Action::make('save')->label('Save data')->submit('save'),
];
}
public function save(): void
{
try {
$data_tt = $this->settingForm->getState();
$data_ee = $this->emailForm->getState();
$data_thth = $this->themeForm->getState();
$this->handleRecordUpdate($this->getSetting(), $data_tt);
$this->handleRecordUpdate($this->getEmailSetting(), $data_ee);
$this->handleRecordUpdate($this->getThemeSetting(), $data_thth);
} catch (Halt $exception) {
return;
}
Notification::make()
->success()
->title(__('Successfully data updated'))
->send();
}
protected function getSetting()
{
$setting = Setting::where('id', 1)->first();
return $setting;
}
protected function getEmailSetting()
{
$setting_email = SettingEmail::where('id', 1)->first();
return $setting_email;
}
protected function getThemeSetting()
{
$setting_theme = SettingTheme::where('id', 1)->first();
return $setting_theme;
}
protected function fillForms(): void
{
$data_s = $this->getSetting()->attributesToArray();
$data_e = $this->getEmailSetting()->attributesToArray();
$data_t = $this->getThemeSetting()->attributesToArray();
$this->settingForm->fill($data_s);
$this->emailForm->fill($data_e);
$this->themeForm->fill($data_t);
}
protected function handleRecordUpdate(Model $record, array $data): Model
{
$record->update($data);
return $record;
}
}
Level 32
@Fzoltan87 You can use the Filament Tabs Blade component to add your forms to your custom page Blade file, like in the example below.
<x-filament-panels::page x-data="{ activeTab: 'settingForm' }">
<x-filament::tabs>
<x-filament::tabs.item
icon="heroicon-o-cog-6-tooth"
alpine-active="activeTab === 'settingForm'"
x-on:click="activeTab = 'settingForm'">
Setting Form
</x-filament::tabs.item>
<x-filament::tabs.item
icon="heroicon-o-inbox"
alpine-active="activeTab === 'emailForm'"
x-on:click="activeTab = 'emailForm'">
Email Form
</x-filament::tabs.item>
<x-filament::tabs.item
icon="heroicon-o-document"
alpine-active="activeTab === 'themeForm'"
x-on:click="activeTab = 'themeForm'">
Theme Form
</x-filament::tabs.item>
</x-filament::tabs>
<template x-if="activeTab === 'settingForm'">
<x-filament-panels::form wire:submit="submit">
{{ $this->settingForm }}
<div>
<x-filament::button type="submit" size="sm">
Submit
</x-filament::button>
</div>
</x-filament-panels::form>
</template>
<template x-if="activeTab === 'emailForm'">
<x-filament-panels::form wire:submit="submit">
{{ $this->emailForm }}
<div>
<x-filament::button type="submit" size="sm">
Submit
</x-filament::button>
</div>
</x-filament-panels::form>
</template>
<template x-if="activeTab === 'themeForm'">
<x-filament-panels::form wire:submit="submit">
{{ $this->themeForm }}
<div>
<x-filament::button type="submit" size="sm">
Submit
</x-filament::button>
</div>
</x-filament-panels::form>
</template>
</x-filament-panels::page>
1 like
Please or to participate in this conversation.