FilamentF
Filament10mo ago
morty

Is there a way in Filament to calculate a field on the client side without Livewire? AlpineJS?

I have a form as defined here:
->form([
    Forms\Components\TextInput::make('adjustment')
        ->live()
        ->helperText('Increase or decrease available quantity')
        ->integer()
        ->required()
        ->afterStateUpdated(function (Forms\Get $get, Forms\Set $set, Location $record): void {
            $set(
                'available_quantity',
                $record->pivot->available_quantity + $get('adjustment')
            );
        }),
    Forms\Components\TextInput::make('available_quantity')
        ->disabled(),
    Forms\Components\Textarea::make('comment')
        ->helperText('Reason for adjustment'),
])
->fillForm(
    function (Location $record): array {
        return [
            'available_quantity' => $record->pivot->available_quantity,
        ];
    }
)


The problem with this calculated field available_quantity is that the calculation requires the adjustment field to be live which causes debounce issues with the client as seen in the attached GIF. When updating the field that has already sent an ajax request to the server, the client side updates but then reverts if another client side update occurred before getting the ajax response.

In a non-Filament app I'd solve this by just doing the calculation through AlpineJS and never requiring a live field. However, I'm not sure how I'd do this in the context of a Filament app.
CleanShot_2025-02-27_at_08.53.58.gif
Solution
Actually what you want is to use AlpineJS to do it for you.. using extraAttributes I suspect? Roughly like:

Forms\Components\TextInput::make('adjustment')
    ->helperText('Increase or decrease available quantity')
    ->integer()
    ->required()
    ->extraAttributes(['x-model' => 'adjustment', '@input' => 'updateAvailableQuantity()']),
Forms\Components\TextInput::make('available_quantity')
    ->disabled()
    ->extraAttributes(['x-model' => 'available_quantity']),
Forms\Components\Textarea::make('comment')
    ->helperText('Reason for adjustment'),
])
->extraAttributes(fn($record) => ['x-data' => '{
    adjustment: 0,
    available_quantity: ' . $record->pivot->available_quantity . ',
    updateAvailableQuantity() {
        this.available_quantity = ' . $record->pivot->available_quantity . ' + parseInt(this.adjustment);
    }
}'])
->fillForm(
    function (Location $record): array {
        return [
            'available_quantity' => $record->pivot->available_quantity,
        ];
    }
)
Was this page helpful?