Zakk
Zakk

Reputation: 766

React - Material-UI - How to use Select with multiple values inside react-hook-form

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

Upvotes: 4

Views: 16086

Answers (3)

ArkaBarua
ArkaBarua

Reputation: 91

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

Upvotes: 7

Mohammed
Mohammed

Reputation: 133

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

Upvotes: 2

Bill
Bill

Reputation: 19328

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

Upvotes: 1

Related Questions