Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting a customised radio button component inside a Radio Group in Material UI

I want to have a list of radio buttons, with one option being a freestyle 'Other' text box that lets the user enter their own text.

Here I have a working sandbox of everything I want to do:

https://codesandbox.io/s/r4oo5q8q5o

handleChange = event => {
    this.setState({
      value: event.target.value
    });
  };

  selectItem = item => {
    this.setState({
      selectedItem: item
    });
  };

  handleOtherChange = event => {
    this.setState({
      otherText: event.target.value
    });

    this.selectItem(
      //Todo put in right format
      this.state.otherText
    );
  };
  focusOther = () => {
    this.setState({
      value: "Other"
    });

    this.selectItem(this.state.otherText);
  };

  render() {
    const { classes, items } = this.props;
    const { value } = this.state;

    return (
      <div className={classes.root}>
        <Typography>
          {" "}
          Selected item is: {JSON.stringify(this.state.selectedItem)}
        </Typography>

        <FormControl component="fieldset" fullWidth>
          <RadioGroup value={this.state.value} onChange={this.handleChange}>
            {items.map(v => (
              <FormControlLabel
                value={v.name}
                control={<Radio />}
                label={v.name}
                key={v.name}
                onChange={() => this.selectItem(v)}
              />
            ))}

            <FormControlLabel
              value="Other"
              control={<Radio />}
              label={
                <TextField
                  placeholder="other"
                  onChange={this.handleOtherChange}
                  onFocus={this.focusOther}
                />
              }
              onChange={() => this.selectItem(this.state.otherText)}
            />
          </RadioGroup>
        </FormControl>
      </div>
    );
  }
}

Now what I want to do is make the 'Other' text box its own component.

Here's my attempt:

https://codesandbox.io/s/ryomnpw1o

export default class OtherRadioButton extends React.Component {
  constructor() {
    super();

    this.state = {
      text: null
    };
  }

  handleTextChange = event => {
    this.setState({
      text: event.target.value
    });
    this.props.onChange(this.state.text);
  };
  focusOther = () => {
    this.props.onFocus(this.props.value);
    this.props.onChange(this.state.text);
  };

  render() {
    return (
      <FormControlLabel
        value={this.props.value}
        control={<Radio />}
        label={
          <TextField
            placeholder="other"
            onChange={this.handleTextChange}
            onFocus={this.focusOther}
          />
        }
        onChange={this.focusOther}
      />
    );
  }
}

Used with:

   <OtherRadioButton
      value="Other"
      onFocus={v => this.setState({ value: v})}
      onChange={v => this.selectItem(v)}
    />

As you can see - the value of the free text is propagating back fine - but the RadioGroup seems like it's not aware of the FormGroupLabel's value.

Why is this, and how would I solve this?

like image 290
dwjohnston Avatar asked Oct 08 '18 00:10

dwjohnston


People also ask

How do I get the value of a material UI radio button?

Use the onChange prop of your <RadioGroup> to hook in to when the selection changes, store it in your state and use this in the value prop of your containing <RadioGroup> . You should add an event listener and then update your state based on the value you can get from the event.

How do you reduce the space between radio button and text in flutter?

The easiest way to achieve this is by wrapping the Radio without any padding, in a Container and then setting your custom Margin and Padding as(if) required. This did the trick.

How do I make a radio group in React?

Using a Radio Button Group with a FormSet up a form with a radio button group like this. As you can see in the above example, in the form there are three different radio buttons along with the submit button, and each radio button is attached with one onChange function, called onValueChange() .

What is the name of the object a developer would use to create a group of Radiobuttons in which only one radio button can be selected at a time?

To create each radio button option, create a RadioButton in your layout. However, because radio buttons are mutually exclusive, you must group them together inside a RadioGroup . By grouping them together, the system ensures that only one radio button can be selected at a time.


1 Answers

You can check the RadioGroup source code here. And I have written my own code to better illustrate how it can be fixed. See here: https://codesandbox.io/s/mz1wn4n33j

RadioGroup creates some props to its FormControlLabel/RadioButton children. By creating your own customized radio button in a different component, these props are not passed to FormControlLabel/RadioButton.

You can fix these by passing the props to your FormControlLabel in your custom RadioButton.

<FormControlLabel
    value={this.props.value}       //Pass this
    onChange={this.props.onChange} //Pass this one too
    checked={this.props.checked}   //Also this
    control={<Radio name="gender" />}
    label={
      <TextField
        id="standard-bare"
        defaultValue={this.props.defaultValue}
        margin="normal"
        onChange={this.props.onTextChange}
      />
    }
/>
like image 81
Ramil Amparo Avatar answered Nov 15 '22 21:11

Ramil Amparo