When I select a product, the other AutoComplete
for colors
should filter based on the available variations of colors where the quantity is not equal to 0. For example, if I'll select the product Tumbler
, the colors should be Black, pink, and green. And if I'll select the product Notebook
, the color should be Green, Red, and Black.
The list of the products shows in the AutoComplete
as options (working)
According to the what product was selected, it shows the available colors whose quantity is not equal to 0
for that selected product. For example, I chose Tumbler, this will show the list of colors the tumbler has which are Black, Pink, and Green. And if I'll choose the product Shirt, the list of colors that will display are Blue and Black. (Not working)
Pass the data that contains the available colors of the selected product to the NestedArray
component and show up as options
of the AutoComplete
. (Not working)
How can I do this? Thank you.
I have recreated the problem in codesandbox:
FieldArray Component
const FieldArray = ({ products }) => {
const options = products.map(
(object) =>
object.prodName +
" - " +
object.size +
);
console.log(fields, "f");
const selectedProduct = fields.map((object) => object.product);
console.log(selectedProduct, "selectedProduct");
return (
<div>
<ul>
{fields.map((item, index) => {
return (
<li key={item.id} style={{ listStyleType: "none" }}>
<Controller
control={control}
name={`order.${index}.product`}
render={({ field: { onChange, value = "", ...rest } }) => (
<Autocomplete
{...rest}
onInputChange={(e, newValue) => {
onChange(newValue);
}}
inputValue={value}
options={options}
isOptionEqualToValue={(option, value) =>
option?.value === value?.value
}
renderInput={(params) => (
<TextField
{...params}
label="Product"
variant="outlined"
fullWidth
/>
)}
/>
)}
/>
<NestedArray
nestIndex={index}
{...{ control, register, products }}
/> //pass the corresponding colors here of the selected product (AutoComplete) in the above component
</li>
);
})}
</ul>
<section>
//button to add more product
</section>
</div>
);
};
export default FieldArray;
NestedArray Component:
To show the corresponding colors
here according to what Product (AutoComplete) was selected in the above component
const NestedArray = ({ nestIndex, control, register, products }) => {
const { fields, remove, append } = useFieldArray({
control,
name: `order[${nestIndex}].variation`,
});
return (
<div>
{fields.map((item, k) => {
return (
<div key={item.id} style={{ marginLeft: 20 }}>
<label>{k + 1}</label>
//the quantity input here
<Controller
control={control}
name={`order[${nestIndex}].variation[${k}].color`}
render={({ field: { onChange, value = "", ...rest } }) => (
<Autocomplete
{...rest}
onInputChange={(e, newValue) => {
onChange(newValue);
}}
inputValue={value}
options={options}
isOptionEqualToValue={(option, value) =>
option?.value === value?.value
}
renderInput={(params) => (
<TextField
{...params}
label="Color"
variant="outlined"
fullWidth
/>
)}
/>
)}
/>
</div>
);
};
export default NestedArray;
I did not dig in to see how react-hook-form
works, so you can probably come up with a nicer solution.
Here is my solution in codesandbox: https://codesandbox.io/s/react-hook-form-wizard-form-from-reddit-with-data-setting-up-a-setproduct-forked-wyo8i2?file=/src/index.js
To describe the changes I made:
FieldArray
to hold the currently selected product. (you probably incorporate this better using your form library). The value is then passed to NestedArray
.<Autocomplete>
props in FieldArray
to include onChange
instead of onInputChange
(used onChange instead of onInputChange to get the product object instead of the generated label as an argument to the function).I aslo had to map the colors of the product object to an array similar to the one you had created.
const options = Object.keys(product.colorMap).map((color) => ({
label: color,
value: color
}))
Ok Pennie, for building a dynamic options (if I understood what you are tring to develop here).
I think you should pass the options as props into the nestedFieldsArray.js,
fieldsArray.js->
<NestedArraynestIndex={index}
{...{ control, register, options }}
/>
and in the nestedFieldsArray.js->
const NestedArray = ({ nestIndex, control, register, options }) => {
const { fields, remove, append } = useFieldArray({
control,
name: `order[${nestIndex}].variation`
});
and remove the hard coded options-
const options = [ //should be delete
{ label: "red", value: "red" },
{ label: "green", value: "green" },
{ label: "blue", value: "blue" }
];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.