filament icon indicating copy to clipboard operation
filament copied to clipboard

Numeric TextInput inside Repeater do not show value

Open jlucfarias opened this issue 9 months ago • 3 comments

Package

filament/filament

Package Version

v3.3.8

Laravel Version

v11.44

Livewire Version

v3.6.1

PHP Version

PHP 8.2

Problem description

When creating a resource with a Repeater component for a HasMany relationship with a model that have a decimal property and add a numeric input inside the Repeater, the value value of the decimal property is not showed

Expected behavior

The value is showed correctly

Steps to reproduce

  1. Clone the reproduction repository and follow the steps in README
  2. Log-in with the default user (it will be automatically filled)
  3. Open Products resource
  4. Create a Product with percentage discount of any value
  5. See that the value is not showed

Obs. 1: The above steps is the same as in the GIF in README at reproduction repository

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

https://github.com/jlucfarias/filament-input-number-repeater-bug

Relevant log output


jlucfarias avatar Apr 04 '25 22:04 jlucfarias

I think what's happening is that you're trying to have two fields with the same name at once:

TextInput::make('value')
    ->label('filament-panels::resources/product-resource.form.discounts.value.label')
    ->translateLabel()
    ->suffix('%')
    ->inputMode('decimal')
    ->rule('numeric')
    ->type('number')
    ->step(0.01)
    ->minValue(0)
    ->required(fn($get) => $get('type') !== null)
    ->hidden(fn($get) => !in_array($get('type'), [DiscountType::PERCENTAGE, DiscountType::PERCENTAGE->value])),
Money::make('value')
    ->label('filament-panels::resources/product-resource.form.discounts.value.label')
    ->translateLabel()
    ->default('0,00')
    ->required(fn($get) => in_array($get('type'), [DiscountType::FIXED, DiscountType::FIXED->value]))
    ->hidden(fn($get) => !in_array($get('type'), [DiscountType::FIXED, DiscountType::FIXED->value])),

Hiding an input doesn't remove it, it just hides it from the interface, if we remove the hidden you'll see that the value is actually there, It's just in the other input:

Image

A suggestion fix for you is to do something like this instead:

Group::make(function (Get $get) {
    if ($get('type') === DiscountType::PERCENTAGE->value) {
        return [
            TextInput::make('value')
                ->label('filament-panels::resources/product-resource.form.discounts.value.label')
                ->translateLabel()
                ->suffix('%')
                ->inputMode('decimal')
                ->numeric()
                ->step(0.01)
                ->minValue(0)
                ->required()
        ];
    } else {
        return [
            Money::make('value')
                ->label('filament-panels::resources/product-resource.form.discounts.value.label')
                ->translateLabel()
                ->default('0,00')
                ->required()
        ];
    }
}),

So it's not actually a bug with filament itself. Hope that helps!

fyi @danharrin

Saad5400 avatar Apr 21 '25 03:04 Saad5400

It'd be great to have something like exclude() / include() that works like hidden() / visible() but actually doesn't render the input at the first place. I usually do the solution above of using a group with a closure and conditional return ... but this should replace it.

Or notRendered(), discard(), omit() ... etc

Is it ok it open a PR for this?

Saad5400 avatar Apr 21 '25 03:04 Saad5400

Hmm no I don't think we should add a method like that to Filament to be honest, the dynamic schema is the correct way to go in this case.

danharrin avatar Apr 22 '25 19:04 danharrin

Sorry for the late response. You're right, @Saad5400, your suggestion solved my issue. Many thanks. Closing issue

jlucfarias avatar May 03 '25 20:05 jlucfarias