I'm having some problems getting the value price
from the useState products when I'm using a Form.Select
.
The idea is that with the Form.Select
you're able to select a product by its name and then onChangeProduct
will set the state of data
with the given product name and the price property of that product. I'm just not sure how to fetch the price
value without the user needing to manually selecting a price in a Form.Select
too.
The code is a simple illustration of the code I got so fare.
If you have any component that would make this easier than I'll be glad to hear about it.
Hope that makes sense.
const [data, setData] = useState([]);
const [product, setProduct] = useState([
{ name: "TV", price: 1000 },
{ name: "Phone", price: 3000 },
]);
const onChangeProduct = (name, value) => {
setData((prevValue) => {
const newValues = [...prevValues];
newValues = Object.assign({}, newValues, {[name]: value });
return newValues;
});
};
return (
<Form>
<Form.Select
onChange={(event) => {onChangeProduct("name", event.target.value);}}
value={product.name}
name="product"
>
{product.map((item) => {
return <option value={item.name}>{item.name}</option>;
})}
</Form.Select>
</Form>
);
EDIT
I've decided to go another way to make this work. I may need to set the products to an array/state as I want to be able to catch both the price and product later on.
The idea is to make the system work with add/remove product to a card where you'll be able to check the checkout with the productname and price. Therefore you're able to pick a list of products and in that way see the price property of that product.
I used the same functions I got help with here: onChange, onProductRemove and add function
CardForm.jsx -> ModalEditProducts.jsx -> ProductEdit.jsx
In CardForm.jsx
I check if there's a ID and if there's a ID I'll fetch all the products already selected by this user.
CardForm.jsx
const CardForm = () => {
const [data, setData] = useState({});
const { id } = useParams();
const [products, setProducts] = useState([]);
useEffect(() => {
if (id) {
const fetchData = async () => {
const docRef = doc(db, "user", id);
try {
const docSnap = await getDoc(docRef);
setData(docSnap.data());
} catch (error) {
console.log(error);
}
};
fetchData().catch(console.error);
}
}, []);
const handleProductChanged = (product) => {
setData((data) => ({ ...data, product }));
};
return (
<>
<Container className="mb-3 content_container_primary">
<Row>
<Col xs={12} md={12} lg={8} className="">
<Form>
<div className="box content_pa">
<Col xs={12} md={12} lg={12}>
<div>
<ModalEditProducts
onProductChanged={handleProductChanged}
data={data.product ?? []}
title="Edit products"
/>
</div>
</Col>
</div>
</Form>
</Col>
</Row>
</Container>
</>
);
};
ModalEditProducts.jsx
const ModalEditProducts = ({ title, data, onProductChanged }) => {
const [show, setShow] = useState(false);
const [newData, setNewData] = useState([]);
useEffect(() => {
setNewData(data);
}, [data, show]);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const handleProductChange = (index, name, value) => {
setNewData((prevValues) => {
const newValues = [...prevValues];
newValues[index] = Object.assign({}, newValues[index], { [name]: value });
return newValues;
});
};
const handleProductAdded = () => {
setNewData((prevValues) => [...prevValues, { product: "", price: 0 }]);
};
const handleProductRemoved = (index) => {
setNewData((prevValues) => {
const newValues = [...prevValues];
newValues.splice(index, 1);
return newValues;
});
};
const handleSubmitProducts = (e) => {
e.preventDefault();
onProductChanged(newData);
setShow(false);
};
return (
<>
<div className="content_header">
<div className="content_header_top">
<div className="header_left">Products</div>
<div className="header_right">
<Button className="round-btn" onClick={handleShow}>
<i className="fa-solid fa-pencil t-14"></i>
</Button>
</div>
</div>
</div>
{show && (
<Modal show={show} onHide={handleClose} size="">
<Modal.Header closeButton>
<Modal.Title>{title}</Modal.Title>
</Modal.Header>
<Modal.Body>
<ProductEdit
data={newData}
onProductChanged={handleProductChange}
onProductAdded={handleProductAdded}
onProductRemoved={handleProductRemoved}
/>
</Modal.Body>
<Modal.Footer>
<Form>
<Button
className="btn-skill-complete"
onClick={handleSubmitProducts}
>
Save
</Button>
</Form>
</Modal.Footer>
</Modal>
)}
</>
);
};
ProductEdit.jsx
const ProductEdit = ({ data, onProductChanged, onProductRemoved, onProductAdded }) => {
const [products, setProducts] = useState([]);
useEffect(() => {
GetProducts(setProducts);
});
return (
{data.length > 0 ? (
<Row>
<Col xs={9} md={9}>
<div className="product-modal-title mb-3">Pick a new product</div>
</Col>
<Col xs={3} md={3}>
<div className="product-modal-title mb-3 text-center">
Remove/add
</div>
</Col>
</Row>
) : null}
{data.length === 0 ? (
<Col xs={12} md={12}>
<Button
className="btn-st-large t-16 "
type="button"
onClick={onProductAdded}
>
Add a product
</Button>
</Col>
) : (
<>
{data?.map((inputField, index) => (
<div key={index}>
<Row>
<Col xs={9} md={9}>
<Form.Select
as={Col}
className="mb-3"
onChange={(event) => {
onProductChanged(index, "product", event.target.value);
}}
id="product"
name="product"
value={inputField.product}
>
<option>Choose product</option>
{products.map((item) => {
return (
<option key={item.id} value={item.name}>
{item.name} ({item.price} kr.)
</option>
);
})}
</Form.Select>
</Col>
<Col xs={3} md={3}>
<div className="btn-section">
<button
type="button"
className="round-btn"
onClick={onProductAdded}
>
<i className="fa-solid fa-plus"></i>
</button>
<button
type="button"
className="round-btn"
onClick={() => onProductRemoved(index)}
>
<i className="fa-solid fa-minus"></i>
</button>
</div>
</Col>
</Row>
</div>
))}
</>
)}
</Form>
);
};