4

I am trying to use UI-Material Select with multiple options inside react-hook-form without success.

I had this working before trying to do it with multiple options

            <form onSubmit={handleSubmit(onSubmit)}>
                <Row className="mb-2">
                    <Col sm={6}>
                        <FormControl className="select-language">
                            <InputLabel> {t('Languages')}</InputLabel>
                            <Controller
                                as={
                                    <Select>
                                        {Config.languages.map(m => <MenuItem key={m.code} value={m.text}> {t(m.text)} </MenuItem>)}
                                    </Select>
                                }
                                defaultValue={user.language}
                                name="language"
                                control={control}
                            >
                            </Controller>

                        </FormControl>

                    </Col>
                </Row>
         </form>

I tried to add multiple to the Select element which lead me to another error.

I tried also to keep only the Select element without the Controller wrapper, but then I can't get the language value in onSubmit

Very simple codeSandBox that shows that I can't get value from Select when submitting the form: https://codesandbox.io/s/react-hook-form-example-s7h5p?file=/src/index.js

I would appreciate any help Thanks

2

3 Answers 3

7

If anyone looking for a easy solution, this might come in handy. Multiple select options become very easy now with Select Component. If you look at the Select component, you just have to set the default value to an array and pass the "multiple" prop.

import {
  Button,
  FormControl,
  InputLabel,
  MenuItem,
  Select
} from "@mui/material";
import { Controller, useForm } from "react-hook-form";

const FCWidth = {
  width: "20rem"
};

export default function App() {
  const { control, handleSubmit } = useForm();
  const formSubmitHandler = (formData) => {
    console.log(formData);
  };

  const ages = ["10", "20", "30"];

  return (
    <div className="App">
      <form onSubmit={handleSubmit(formSubmitHandler)}>
        <Controller
          name="age"
          control={control}
          type="text"
          defaultValue={[]}
          render={({ field }) => (
            <FormControl sx={FCWidth}>
              <InputLabel id="age">Age</InputLabel>
              <Select
                {...field}
                labelId="age"
                label="age"
                multiple
                defaultValue={[]}
              >
                {ages.map((age) => (
                  <MenuItem value={age} key={age}>
                    {age}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          )}
        />
        <FormControl sx={FCWidth}>
          <Button
            type="submit"
            variant="contained"
            fullWidth
            sx={{ marginTop: ".75rem", fontWeight: "bold" }}
          >
            Submit
          </Button>
        </FormControl>
      </form>
    </div>
  );
}

Here is the code sandbox link https://codesandbox.io/s/select-multiple-option-with-mui-and-react-hook-form-2kv2o

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

Comments

2

I know that this old but someone may need it later, maybe this one would work for you, just check the render Controller props

import React from "react";
import {
  TextField,
  ListItemText,
  Checkbox,
  MenuItem,
  makeStyles
} from "@material-ui/core";
import { useForm, Controller } from "react-hook-form";

const useStyles = makeStyles({
  root: {
    width: "200px"
  },
  center: {
    textAlign: "center"
  }
});

export default function SelectTextField() {
  const classes = useStyles();
  const { handleSubmit, control } = useForm();

  const nums = [1, 2, 3, 4];

  const onSubmit = (e) => {
    console.log(e);
  };

  return (
    <form className={classes.center} onSubmit={handleSubmit(onSubmit)}>
      <Controller
        control={control}
        name="selectedNumbers"
        defaultValue={[]}
        render={({ onChange, value }) => {
          console.log(value);
          return (
            <TextField
              classes={{ root: classes.root }}
              select
              id="Numbers"
              variant="outlined"
              label="Numbers"
              SelectProps={{
                multiple: true,
                value: value,
                renderValue: (selected) => selected.join(", "),
                onChange: onChange
              }}
            >
              {nums.map((n) => (
                <MenuItem key={n} value={n}>
                  <Checkbox checked={value.includes(n)} />
                  <ListItemText primary={n} />
                </MenuItem>
              ))}
            </TextField>
          );
        }}
      />
      <div>
        <button type="submit">Submit</button>
      </div>
    </form>
  );
}

also, you can and play with it here https://codesandbox.io/s/multi-select-input-u0cr3?file=/demo.js

also can check this on the docs https://react-hook-form.com/get-started#ReactNative

Comments

1

First of all, i think your version is on v3, so you may want to upgrade: https://codesandbox.io/s/react-hook-form-example-5lrij?file=/src/index.js

import React from "react";
import ReactDOM from "react-dom";
import { useForm, Controller } from "react-hook-form";
import { Select, MenuItem } from "@material-ui/core";

import "./styles.css";

const languages = [
  {
    code: "en-US",
    text: "English"
  },
  {
    code: "zu",
    text: "Another Language"
  }
];

export default function App() {
  const { register, handleSubmit, control } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <div className="container">
      <div className="col-sm-12">
        <h3>Client Profile</h3>
      </div>
      <div className="col-sm-12">
        <form onSubmit={handleSubmit(onSubmit)}>
          <div className="form-group">
            <input
              className="form-control"
              type="text"
              placeholder="Name"
              name="Name"
              ref={register}
            />
          </div>

          <div className="form-group">
            <Controller
              name="Language"
              control={control}
              as={
                <Select>
                  {languages.map(m => (
                    <MenuItem key={m.code} value={m.text}>
                      {" "}
                      {m.text}{" "}
                    </MenuItem>
                  ))}
                </Select>
              }
              defaultValue={languages[0].text}
            />
          </div>
          <div className="form-group">
            <input className="btn btn-primary" type="submit" />
          </div>
        </form>
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

here is the fixed version by using Controller

1 Comment

Hi @Bill, I had this working before. I need working example with multiple options in the Select

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.