I have a relation field which link to product collection and this product collection contains of the price of each product. What I am trying to achieve is to populate the price of the product to a read only field after the product is selected. I've attach a screenshot for better understanding.
Hey @jasonkw9,
I've done this before for a project where I need to calculate some field based on sibling data changes. To do it I used the useWatchForm
hook to calculate the updates in a useEffect
. Here is an example:
const ProviderFee: React.FC<{ path: string }> = ({ path }) => {
const { getDataByPath } = useWatchForm();
const { value, setValue } = useField({ path });
const type: string = getDataByPath('type');
const amount: number = getDataByPath('amount');
const feePercentage: number = getDataByPath('feePercentage');
useEffect(() => {
if (typeof amount === 'number' && typeof feePercentage === 'number') {
setValue((feePercentage / 100) * Math.abs(amount));
} else if (value !== 0 && value !== undefined) {
setValue(0);
}
}, [value, type, amount, feePercentage, setValue]);
return (
<div>
<span>
<TextInput
path="fee"
name="providerFee"
value={`${value}`}
label="Fee"
readOnly
/>
</span>
</div>
);
};
Then the field is used in the config:
// collection
const orders = {
slug: 'orders',
fields: [
/* ... */
{
name: 'providerFee',
type: 'number',
defaultValue: 0,
admin: {
condition: (data) => (data.type === 'withdrawal'),
components: {
Field: ProviderFee,
},
},
},
],
}
Hi @DanRibbens,
Thank you so much for your suggestion but I have one more question. Since my products relation field only returning the ID of the product, how do I get the price of the selected product instead? I've tried to use getDataByPath('items') which return me an array of the products I selected but price is not included inside the array.
Here's my sample code:
{
name: "items",
type: "array",
label: "Products",
fields: [
{
type: "row",
fields: [
{
name: "orderItem",
type: "relationship",
relationTo: "products",
required: true,
admin: {
width: "50%",
},
},
{
name: "productPrice",
type: "number",
defaultValue: 0,
admin: {
readOnly: true,
components: {
Field: ProductPrice,
},
},
},
{
name: "quantity",
type: "number",
required: true,
admin: {
width: "10%",
},
},
],
},
],
},
Oh gotcha, I overlooked the relationship piece. You can do an async call out to fetch the product in your useEffect. Try this in your component:
const orderItem: string = getDataByPath('orderItem');
const { value, setValue } = useField({ path });
useEffect(() => {
const setPrice = async () => {
if (orderItem) {
const result = await fetch(`/api/products/${orderItem}`);
if (result.ok) {
const data = await result.json();
setValue(data.price);
}
}
}
setPrice();
}, [orderItem, setValue]);
Hey @DanRibbens , thank you so much for your help! I manage to achieve what I want