Skip to content

Dynamic Tabs with Repeater having return null item #15444

Open
@billydekid

Description

@billydekid

Package

filament/filament

Package Version

v3.2.135

Laravel Version

v11.40.0

Livewire Version

No response

PHP Version

v8.3.6

Problem description

I have a dynamic Tabs component which will generate Tab base on db query. Inside the Tab there's a form structure which only differentiated based on the value one of the input field material_usage_id. This MaterialUsage value is defined by a checkbox value (is_total).

The problem was when the checkbox is unchecked the new Tab is generated but the Repeater displayed with null item. Different from the previous option (if checked) where 1 item appears on each tab.

Code

class InventorySvac11Resource extends Resource
{
    protected static ?string $model = InventorySvac11::class;

    protected static ?string $navigationIcon = 'bi-fuel-pump';


    public static function form(Form $form): Form
    {
        return $form
            ->schema([

                /* TODO: When is_total is unchecked on create, the repeater item is null AND is still able to save */
                Forms\Components\Section::make()
                    ->schema([
                        Forms\Components\Hidden::make('id'), // Ensure the ID field is included

                        Forms\Components\Checkbox::make('is_total')
                            ->visibleOn('create')
                            ->label('We measure the volume of mobile and stationary combustion sources')
                            ->live()

                            /* default() value on view/edit is created by mutateFormDataBeforeFill() function on EditInventorySvac11.php */

                            ->default(true),

                        Forms\Components\Tabs::make('Fuels Tabs')
                            ->tabs(function (Forms\Get $get) {
                                // Get the value of the 'is_total' checkbox
                                $isTotal = $get('is_total');

                                // Log::debug('is_total: ' . $isTotal);

                                // Define the classifications
                                $filter = $isTotal ?? true
                                    ? ['MOBILE-FUELS', 'STATIONARY-FUELS'] // Classification 1: Mobile and Stationary Fuels
                                    : ['TOTAL-FUELS'];                    // Classification 2: Total Fuels

                                // Query MaterialUsage based on the classification
                                return MaterialUsage::whereIn('code', $filter)
                                    ->get()
                                    ->map(function ($usage) {
                                        Log::debug('Tab usage: ' . $usage);
                                        return Forms\Components\Tabs\Tab::make($usage->name)
                                            ->schema([
                                                Forms\Components\Repeater::make($usage->name . ' Consumptions')
                                                    ->label($usage->name . ' Consumptions')
                                                    ->defaultItems(1)
                                                    ->relationship('svac11Fuels', function (Builder $query) use ($usage) {
                                                        return $query->where('material_usage_id', $usage->id);
                                                    })
                                                    ->dehydrated() // put after relationship()
                                                    ->columns(3)
                                                    ->minItems(1)
                                                    ->schema([
                                                        Forms\Components\Hidden::make('material_usage_id')
                                                            ->default(fn() => $usage->id),
                                                        Forms\Components\TextInput::make('consumption')
                                                            ->label('Consumption')
                                                            ->required()
                                                            ->numeric()
                                                            ->regex('/^(?!0(\.0+)?$)\d{1,8}(\.\d+)?$/')
                                                            ->validationMessages([
                                                                'regex' => 'The :attribute value and field format is invalid.',
                                                            ])
                                                            ->extraAttributes(['step' => '0.01', 'inputmode' => 'decimal'])
                                                            ->formatStateUsing(fn($state) => $state ? number_format((float) $state, 2, '.', '') : null),
                                                    ]),
                                            ]);
                                    })->toArray();
                            })
                            ->columnSpanFull(),
                    ]),
            ]);
    }

}

Expected behavior

When is_total checkbox is unchecked, the generated Tab appears and having minimum 1 item inside Repeater.

Image

Steps to reproduce

  1. Default is_total checkbox is true and two tabs are generated with 1 item inside Repeater
  2. When unchecked the new Tab ("Total") is generated but with null item (of Repeater). Hence we should click "Add item" of repeater to add a new item.

Image

Reproduction repository (issue will be closed if this is not valid)

https://github.com/billydekid/bwcarbon

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    • Status

      Todo

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions