How to create dynamic MUI Radio in Formik React form

Viewed 244

Well... I have a Formik form that deals with product's images; each product has different element in which a collection of images and each image has an id, a path and a boolean:

product: { ...,  images: { id , path , isMain } }

Each product can have only one image with isMain === true.

As I am using the same form to create and update a product, I pass a prop { product } that can be null... So I am initializing my values like this:

<Formik
    initialValues={{
      name: product && product.name ? product.name : "",
      description: product && product.description ? product.description : "",
      price: product && product.price ? product.price : "",
      quantityInStock: product && product.quantityInStock ? product.quantityInStock : "",
      images: product && product.images ? product.images : []
    }}
    onSubmit={(values) => {
      console.log(values);
    }}
    enableReinitialize={true}
  >

I would like to render the main image bigger than the others in the form and the user should be able to change which of these image is the main one;

So, I'm creating dynamically the images from the list and adding a MUI Radio to each of them:

{values.images.map((image, index) => {
  <Box key={index} order={image.isMain ? -1 : ""} width={image.isMain ? "100%" : "20%"}>
    <Image src={image.path} alt={"image"} fluid /> 
    <Radio
      checked={values.images[index].isMain}
      onChange={handleChange}
      value={true} //values.images[index].isMain ??? 
      name="is-main-radio-buttons"
    />
  </Box>
}

The radio of the main image is checked correctly at render but I'm unable to check another button and to update the values of the form... Nothing is happening...

If someone could kindly have a look and send me to the right path, it would be greatly appreciated!

1 Answers

ok... I made it worked with some jedi trick using checkboxes:

{values.images.map((image, index) => {
  <Checkbox
    key={index}
    name={name}
    checked={values.images[index].isMain}
    onChange={() => {
      values.images.map((img, idx) => img.isMain = idx === index ? true :  false);
      setFieldValue("images[index].isMain", true);}
    }
  />
 }

Far to be the cleanest but i does the job... if someone has a better approach, I will take it with pleasure!

Related