F
Filament15mo ago
Fally

Dynamically created form schema setting other field value ignores what user changes as value

I'm going to try to explain this. I have a form in a relation manager. Based on a dropdown selection I build some extra fields using Forms\Components\Group::make()->schema(function ($get, $set, $context) {} For instance, in my case, i have a product selector and then i build some dropdowns with choices based on that product. These choices affect price so I use $set('unit_price', $price) in the form schema that i mentioned above to set the field value. unit_price is a normal defined form field, it's not dynamically created or anything. Problem is, if i edit the field value, manually, afterwards the data that is passed to the update function is what i set with $set, it ignores the actual current user inputed field value. I will attach a video where I will demonstrate that for entries where I don't have to use $set to set price, the data changes. https://share.cleanshot.com/fxkZdXxn
CleanShot Cloud
CleanShot 2023-09-13 at 10.35.09
Video uploaded to CleanShot Cloud
23 Replies
Hugo
Hugo15mo ago
Hi, can you show me your code pls ?
Fally
FallyOP15mo ago
Hi @hugomyb , here's the dynamic form schema i'm creating
Forms\Components\Group::make()->schema(function ($get, $set, $context) {
$productId = $get('product_id');
if ($context === 'edit' && $get('type') !== OrderDetail::TYPE_PRODUCT) {
return [];
}
if ($productId) {
$product = Product::find($productId);
if (empty($product)) {
return [];
}


$set('unit_price', ListingHelper::getProductNumericPrice($product));

/* a lot of logic that builds the fields */
return $fields;
}
return [];
})
Forms\Components\Group::make()->schema(function ($get, $set, $context) {
$productId = $get('product_id');
if ($context === 'edit' && $get('type') !== OrderDetail::TYPE_PRODUCT) {
return [];
}
if ($productId) {
$product = Product::find($productId);
if (empty($product)) {
return [];
}


$set('unit_price', ListingHelper::getProductNumericPrice($product));

/* a lot of logic that builds the fields */
return $fields;
}
return [];
})
The problem is with the $set() line. I can't show all the code because discord has a character limit Here's where I check the data for updating.
Tables\Actions\EditAction::make()
->mutateFormDataUsing(function (array $data): array {
if (isset($data['variation'])) {
$data['product_id'] = $data['variation'];
$data['attributes'] = null;
}

return $data;
})
Tables\Actions\EditAction::make()
->mutateFormDataUsing(function (array $data): array {
if (isset($data['variation'])) {
$data['product_id'] = $data['variation'];
$data['attributes'] = null;
}

return $data;
})
Hugo
Hugo15mo ago
So the problem is that when you change the price manually, you don't get the new value of the price you've just changed? It keeps the $set value, right ?
Fally
FallyOP15mo ago
Yes
Hugo
Hugo15mo ago
I may have an idea, but I'm not sure. Try to add the ->afterStateUpdated() method, something like that, what does the dd return? :
->afterStateUpdated(function ($context, $get, $set) {
if ($context == 'edit') {
dd($get('unit_price'));
}
})
->afterStateUpdated(function ($context, $get, $set) {
if ($context == 'edit') {
dd($get('unit_price'));
}
})
Fally
FallyOP15mo ago
Unfortunately it still shows the initial value
Hugo
Hugo15mo ago
Where did you put the afterStateUpdated?
Fally
FallyOP15mo ago
Forms\Components\TextInput::make('unit_price')
->afterStateUpdated(function ($context, $get, $set) {
if ($context == 'edit') {
dd($get('unit_price'));
}
})
Forms\Components\TextInput::make('unit_price')
->afterStateUpdated(function ($context, $get, $set) {
if ($context == 'edit') {
dd($get('unit_price'));
}
})
Hugo
Hugo15mo ago
Try on Group::make Or, what does return dd here :
Forms\Components\TextInput::make('unit_price')
->afterStateUpdated(function ($state) {
if ($context == 'edit') {
dd($state);
}
})
Forms\Components\TextInput::make('unit_price')
->afterStateUpdated(function ($state) {
if ($context == 'edit') {
dd($state);
}
})
Fally
FallyOP15mo ago
on group it doesn't trigger it's the initial value as well
Hugo
Hugo15mo ago
It's weird, in the afterStateUpdated, the dd($state) should return the live modified value
Fally
FallyOP15mo ago
my point exactly, i even updated to the latest version but this seems like a bug to me
Hugo
Hugo15mo ago
Acutally I've no idea what the problem is, sorry...
Fally
FallyOP15mo ago
thanks for your help anyway i'm sorry to tag you in this @Dan Harrin but is there anyway you can help here? I've tried everything, i don't know if this is a bug or not.
awcodes
awcodes15mo ago
you need to also use ->live() if you are going to use afterStateUpdated()
Fally
FallyOP15mo ago
Sorry but where do i need to use live() ? I can't find any reference in the docs and i tried it on the unit_price form field and the group
Fally
FallyOP15mo ago
im using v2 not v3
awcodes
awcodes15mo ago
It’s the same in v2 expect it’s ->reactive() instead of live.
Fally
FallyOP15mo ago
If i use reactive on the field as soon as i change anything in it it gets overriden by the $set value. I’ve tried it before
Fally
FallyOP15mo ago
So i managed to fix this by setting the product search dropdown to reactive and adding to it afterStateUpdated where I use $set() to set the unit price. For some reason, using $set() inside the Group schema triggers that weird read only problem.
Want results from more Discord servers?
Add your server