1

i can't get values of checkbox array

const schema = yup.object().shape({
  modules: yup.array(),
});

component

{role === "user" &&
                divisions.map((division, i) => (
                  <Box key={division.name}>
                    <Typography variant='h6'>{division.name}</Typography>
                    {division.modules.map((m, j) => (
                      <Controller
                        key={m.name}
                        name={`modules[${i}][${j}]`}
                        control={control}
                        defaultValue={[division.name, m.name, false]}
                        render={({ field }) => (
                          <FormControlLabel
                            {...field}
                            label={m.name}
                            control={
                              <Checkbox
                                onChange={(e) => (e.target.value = "chen")}
                                color='primary'
                              />
                            }
                          />
                        )}
                      />
                    ))}
                  </Box>
                ))}

when i submit the form without checking anything i got a result like this

{//userinfo,  modules: [
//array per division and a nested array for modules access
 [ ["Admin-tools", "admin",false ],  ["Admin-tools", "Backup",false ] ] 
...other divisions and modules
 ]   }

this is the result i expect when i check fields and submit the form

 {//userinfo,  modules: [
    //array per division and a nested array for modules access
     [ ["Admin-tools", "admin",true],  ["Admin-tools", "Backup",true
 ] ] 
    ...other divisions and modules
     ]   }

but i got

{//userinfo,  modules: [
//array per division and a nested array for modules access
 [ [true],  [true] ] 
...other divisions and modules
 ]   }

2 Answers 2

2

You need to pass checked and onChange to your checkbox and append/remove from the form array.

Steps:

  1. Create FromCheckboxes that'll serve as a container to a checkbox array
  2. Loop through your divisions and render a FromCheckbox for each division

Form.js

 <form onSubmit={handleSubmit(onSubmit)}>
      {divisions.map((division) => (
        <Box key={division.name}>
          <Typography variant="h6">{division.name}</Typography>
          <FormCheckboxes
            name="modules"
            control={control}
            parent={division.name}
            options={division.modules}
          />
        </Box>
      ))}
      <Button type="submit">Submit</Button>
    </form>

FormCheckboxes.js

import { useController } from "react-hook-form";
import { Checkbox, FormControlLabel } from "@material-ui/core";

const FormCheckBoxes = ({ options, ...rest }) => {
  const { field } = useController(rest);
  const { value, onChange } = field;

  return options.map((option) => {
    return (
      <FormControlLabel
        key={option.name}
        value={option.name}
        label={option.name}
        control={
          <Checkbox
            checked={value.some((formOption) => formOption[1] === option.name)}
            onChange={(e) => {
              const valueCopy = [...value];
              if (e.target.checked) {
                valueCopy.push([rest.parent, option.name, true]); // append to array
              } else {
                const idx = valueCopy.findIndex(
                  (formOption) => formOption[1] === option.name
                );
                valueCopy.splice(idx, 1); // remove from array
              }
              onChange(valueCopy); // update form field with new array
            }}
          />
        }
      />
    );
  });
};

export default FormCheckBoxes;

Updated Sandbox

Note that you'll still need to figure out how to tie them all in one form field. Now it won't work with multi-divisions.

Sign up to request clarification or add additional context in comments.

Comments

1

if you want the values of the checkbox in order to go to the form values and get it. you have to give each check box a name property. ex:

<FormControlLabel
   {...field}
   label={m.name}
   control={
    <Checkbox
     onChange={(e) => (e.target.value = "chen")}
     color='primary'
     name='name-one'
    />
   }
/>

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.