Updating parent form state from a child component in Filament's Repeater

I have a Repeater component that contains a Select component. The Select component's value change should affect another field (days_taken) that resides in the parent form, outside the Repeater component. I have attached relevant portion of my form schema. In the afterStateUpdated callback for day_part, I want to update the days_taken field based on the selected value, but it seems the $set function doesn't have the scope to change this. Is there a way to update the state of the days_taken from inside the afterStateUpdated callback of day_part? If not, could you suggest an alternative approach to achieve this functionality?
9 Replies
toeknee
toeknee2y ago
$set('../../../days_taken') I beleive should do it or remove a ../. Essentially you can traverse the structure
Naren
NarenOP2y ago
Thank you for your suggestion. I tried using $set('../../../days_taken') to traverse the structure, but unfortunately, it doesn't seem to work in this case. The $set function doesn't seem to affect the state of fields outside the current component scope. Is there another way to update the state of a parent component from within a child component in Filament? I would appreciate any alternative approaches or workarounds you might suggest.
toeknee
toeknee2y ago
What if you get() and dd on that? I am 99% sure we allow set outsite. Try: $set('../../days_taken') or $set('../../../../days_taken')
Naren
NarenOP2y ago
Thank you for your help. After testing your suggestion further, I found that by using $set('../../days_taken', 1), I'm able to traverse the structure and successfully update the state of the parent component from within the child component. This solution works perfectly for my use case. Thank you again for your valuable input. Your assistance helped me resolve the issue.
toeknee
toeknee2y ago
Perfect, I always struggle with how deep we go from reference as it depends which elements set states. Welcome!
Naren
NarenOP2y ago
Thank you for the help so far. Building on the current discussion, I've managed to update the days_taken value when the day_part state is updated. However, I'm now trying to tackle a similar issue but with the Repeater component. Specifically, I want to update the days_taken value each time an item is created or deleted within the Repeater component. I've been looking into using Filament's event listeners for this. According to the documentation, it seems that I should be able to register listeners for repeater::createItem and repeater::deleteItem events in the setUp() method of my form. I've implemented it like attached image: Is this the correct approach for what I'm trying to accomplish? How can I access and modify the parent's days_taken state within these event handlers? Any advice would be much appreciated!
WrkL
WrkL2y ago
seems you are going to calculate the days_taken based on the repeater value right ? dont know if i am doing it wrong but it work in my case
Repeater::make('sales')
->schema([
Select::make('item')
->options(MdPriceList::pluck('material_number', 'id'))
->reactive()
->required()
->afterStateUpdated(fn ($state, callable $set) => $set('price', number_format(MdPriceList::find($state)?->amount) ?? 0))
->searchable(),
TextInput::make('price')
->reactive(),
])
->disableItemMovement()
->columns(2),
Placeholder::make('total')
->content(function ($get) {
$contet = collect($get('sales'))->map(function ($item) {
return [
'price' => $item['price'] ? Str::remove(',', $item['price']) : 0,
];
})->sum('price');
return number_format($contet, 2);
}),
Repeater::make('sales')
->schema([
Select::make('item')
->options(MdPriceList::pluck('material_number', 'id'))
->reactive()
->required()
->afterStateUpdated(fn ($state, callable $set) => $set('price', number_format(MdPriceList::find($state)?->amount) ?? 0))
->searchable(),
TextInput::make('price')
->reactive(),
])
->disableItemMovement()
->columns(2),
Placeholder::make('total')
->content(function ($get) {
$contet = collect($get('sales'))->map(function ($item) {
return [
'price' => $item['price'] ? Str::remove(',', $item['price']) : 0,
];
})->sum('price');
return number_format($contet, 2);
}),
Naren
NarenOP2y ago
I noticed that for the Placeholder component, I can use the content function to achieve this, but I don't see a similar function for the TextInput component. Please check attached image
WrkL
WrkL2y ago
not sure if there's cleaner way to achieve this but it work if do as attached image
Want results from more Discord servers?
Add your server