Raythe
Raythe

Reputation: 472

React Hook Form with MUI Toggle Group

I'm trying to use the MUI toggle group with React Hook Form however I can't get the value to post when submitting the form. My toggle group component looks like this:

import FormatAlignCenterIcon from '@material-ui/icons/FormatAlignCenter';
import FormatAlignLeftIcon from '@material-ui/icons/FormatAlignLeft';
import FormatAlignRightIcon from '@material-ui/icons/FormatAlignRight';
import FormatAlignJustifyIcon from '@material-ui/icons/FormatAlignJustify';
import ToggleButton from '@material-ui/lab/ToggleButton';
import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';
import React from 'react';
import {Controller} from "react-hook-form";

export default function TestToggleGroup(props) {
  const {control} = props;
  const [alignment, setAlignment] = React.useState('left');

  const handleAlignment = (event) => {
    setAlignment(event[1]);
  };

  return (
      <Controller
          name="ToggleTest"
          as={
            <ToggleButtonGroup
                value={alignment}
                exclusive
                onChange={handleAlignment}
                aria-label="text alignment"
            >
              <ToggleButton value="left" aria-label="left aligned" key="left">
                <FormatAlignLeftIcon/>
              </ToggleButton>
              <ToggleButton value="center" aria-label="centered" key="center">
                <FormatAlignCenterIcon/>
              </ToggleButton>
              <ToggleButton value="right" aria-label="right aligned" key="right">
                <FormatAlignRightIcon/>
              </ToggleButton>
              <ToggleButton value="justify" aria-label="justified" disabled key="justify">
                <FormatAlignJustifyIcon/>
              </ToggleButton>
            </ToggleButtonGroup>
          }
          value={alignment}
          onChange={(e) => {
            handleAlignment(e);
          }}
          valueName={"alignment"}
          control={control}
      />
  );
}

Not sure exactly what I'm doing wrong but any assistance would be greatly appreciated.

Upvotes: 1

Views: 4690

Answers (3)

graned
graned

Reputation: 53

The above approach worked like a charm for me :) My code is the following, hope it helps

export function RHFToogleButtonGroup({
  name,
  native,
  maxHeight,
  helperText,
  sx,
  children,
  ...other
}: RHFToogleButtonGroupProps) {
  const { control, setValue } = useFormContext()

  return (
    <Controller
      name={name}
      control={control}
      render={({ field, fieldState: { error } }) => (
        <FormControl sx={sx}>
          <ToggleButtonGroup
            {...field}
            onChange={(event: React.MouseEvent<HTMLElement>, values: string[]) => {
              setValue(field.name, values)
            }}
          >
            {children}
          </ToggleButtonGroup>

          {(!!error || helperText) && (
            <FormHelperText error={!!error}>{error ? error?.message : helperText}</FormHelperText>
          )}
        </FormControl>
      )}
    />
  )
}

Upvotes: 0

Ganesh Munisifreddy
Ganesh Munisifreddy

Reputation: 380

react-hook-form's change event won't work with ToggleButtonGroup because the event.target.value is undefined as it is a button group, not an input group. So, we can either use setValue from the useForm() hook or bind a value to ToggleButtonGroup's onChange event.

Here are my two solution's,

1.Using setValue from the useForm() hook.

const { control, setValue } = useForm<Inputs>({
  defaultValues: { alignment: "left" }
});

 

<Controller
      name="alignment"
      control={control}
      render={({ field }) => {
        return (
          <ToggleButtonGroup
            {...field}
            onChange={(
              event: React.MouseEvent<HTMLElement>,
              value: string
            ) => {
              setValue(field.name, value);
            }}
            exclusive
            aria-label="text alignment"
          >
            <ToggleButton value="left" aria-label="left aligned">
              <FormatAlignLeftIcon />
            </ToggleButton>
            <ToggleButton value="center" aria-label="centered">
              <FormatAlignCenterIcon />
            </ToggleButton>
            <ToggleButton value="right" aria-label="right aligned">
              <FormatAlignRightIcon />
            </ToggleButton>
            <ToggleButton value="justify" aria-label="justified">
              <FormatAlignJustifyIcon />
            </ToggleButton>
          </ToggleButtonGroup>
        );
      }}
    />

2.Binding value to ToggleButtonGroup's onChange event.

onChange={(
  event: React.MouseEvent<HTMLElement> | any,
  value: string
) => {
  event.target.value = value;
  field.onChange(event);
}}

Edit React Hook Form with MUI Toggle Group

Upvotes: 5

David
David

Reputation: 26

My workaround was using an effect to manually set the value using setValue and then using getValues() inside your handleSubmit function to get the values.

const { control, setValue } = props;

//Effect
React.useEffect(() => {
  setAlignment('ToggleTest', alignment);
}, [alignment, setAlignment]);

Upvotes: 1

Related Questions