Joe W
Joe W

Reputation: 1890

react-bootstrap ButtonGroup as radio buttons

I'm trying to make a group of react-bootstrap buttons into a radio button set. I can easily do this with bootstrap with <input type="radio"> elements, but can't figure out how to do this with react-bootstrap. The following code allows the user to select every button, instead of just one.

JS:

const operationButtons = (    
  <ButtonGroup>
    <Button active>Radio 1</Button>
    <Button>Radio 2</Button>
  </ButtonGroup>
);

React.render(operationButtons, document.getElementById('operationButtonsDiv'));

HTML:

<div name="operationButtonsDiv" id="operationButtonsDiv" data-toggle="buttons"/>

Upvotes: 19

Views: 51788

Answers (6)

ZiCode
ZiCode

Reputation: 49

This is in 2022, so the library has moved.

Here is how yo would create a yes/no radio:

<Form>
    <Form.Check 
      type="radio"
      name="group1"
      id={`default-radio`}
      label={`Yes!`}
    />
    <Form.Check 
      type="radio"
      name="group1"
      id={`default-radio`}
      label={`No`}
      />
</Form>

The name="group1" makes the buttons TOGGLE. If you don't want to toggle, give them different names or no names.

Hope this helps someone who might stumble across this question like I did.

Upvotes: 0

Daneesha
Daneesha

Reputation: 425

Some of the answers on this page don't work. Maybe things have changed since then.

I put together this with the help of React Bootstrap website.

<Col>
    <InputGroup>
        <InputGroup.Prepend>
            <InputGroup.Radio  name="group1"/>
            <InputGroup.Text >London</InputGroup.Text>
        </InputGroup.Prepend>
        <FormControl/>
    </InputGroup> 
    <InputGroup>
        <InputGroup.Prepend>
            <InputGroup.Radio  name="group1"/>
            <InputGroup.Text >New York</InputGroup.Text>
        </InputGroup.Prepend>
        <FormControl/>
    </InputGroup> 
    <InputGroup>
        <InputGroup.Prepend>
            <InputGroup.Radio  name="group1"/>
            <InputGroup.Text >Colombo</InputGroup.Text>
        </InputGroup.Prepend>
        <FormControl/>
    </InputGroup> 

To make the radio button set function as a single group you have to give them a name (so that only one radio button is selected at any given time).

Adding a form control makes the edges of the input nicely rounded off but it also makes the radio button label editable. If this is a problem you can leave out the form control.

If you want a different look and feel you can try this.

<Form.Check
    type="radio"
    label="London"
    name="group2"
    id="radio1"
/> 
<Form.Check
    type="radio"
    label="New York"
    name="group2"
    id="radio2"
/> 
<Form.Check
    type="radio"
    label="Colombo"
    name="group2"
    id="radio3"
/> 

However with these getting the value and handling onChange was difficult. Eventually I used another control.

This is a npm package called react-radio-group. You have to install it by running this line on the command.

npm install react-radio-group

Then import it in your file.

import { Radio, RadioGroup} from 'react-radio-group'

Here's the code for the button group.

<RadioGroup name="fruits" onChange={(e) => handleOnChange(e)}>
   <div className="radio-button-background">
       <Radio value="Apple" className="radio-button" />Apple
   </div>
   <div className="radio-button-background">
       <Radio value="Orange" className="radio-button" />Orange
   </div>
   <div className="radio-button-background">
       <Radio value="Banana" className="radio-button" />Banana
   </div>
</RadioGroup>

classNames are where I have given the styles.

Upvotes: 6

Joshua Goldstein
Joshua Goldstein

Reputation: 297

Just using the tags worked for me. Make sure they all have the same name="radio-group-value-here". To get one of the buttons to be selected on render use checked={bool}. I also used disabled={bool} to show but disallow some choices. I settled on using onClick which seems to be working. Lastly, this is all in a dialog and the offset was needed to keep the radio buttons from smushing up against the left edge.


<Row>
    <Col sm={11} smOffset={1} >
        <Radio name="changeset-chooser"
               checked={this.state.checked === 'current'}
               disabled={this.props.changeset.status === "pending"}
               onClick={ (e) => { /* event handler */ } } >
            Current Data
        </Radio>
    </Col>
</Row>
<Row>
    <Col sm={3} smOffset={1} >
        <Radio name="changeset-chooser"
               onClick={ (e) => { /* event handler */ } } >
            History
        </Radio>
    </Col>
    <Col sm={7}  >
          <NotPartOfSample />
    </Col>
</Row>

Upvotes: 1

Alexandra
Alexandra

Reputation: 4843

The framework has changed since the accepted answer and they have now replicated the option group behavior of Bootstrap framework. All you need to do now is to add a group name to each option in the group:

<Radio name="groupOptions">Option 1</Radio>
<Radio name="groupOptions">Option 2</Radio>
<Radio name="groupOptions">Option 3</Radio>

Upvotes: 23

Joe W
Joe W

Reputation: 1890

So I ended up nesting a radio Input in the Button like you would normally do in Bootstrap.

render() {
  return (
    <ButtonGroup>
      <Button active>Radio 1
        <Input ref="input1" type="radio" name="radioButtonSet" value='input1' standalone defaultChecked/>
      </Button>
      <Button>Radio 2
        <Input ref="input2" type="radio" name="radioButtonSet" value='input2' standalone/>
      </Button>
    </ButtonGroup>
  )
}

I also overrode the default .radio css to fix how it's displayed.

.radio {
  margin-top: 0;
  margin-bottom: 0;
}

React-bootstrap has plans to implement RadioGroup eventually: https://github.com/react-bootstrap/react-bootstrap/issues/342

Upvotes: 6

user276289
user276289

Reputation: 1539

I've just encountered the same problem and solved it by using the the component's state:

_onOptionChange(option) {
    this.setState({
        option: option
    });
}

render() {
    render (
        <ButtonGroup>
            <Button onClick={this._onOptionChange.bind(this, 'optionA')} active={this.state.option === 'optionA'}>Option A</Button>
            <Button onClick={this._onOptionChange.bind(this, 'optionB')} active={this.state.option === 'optionB'}>Option B</Button>
        </ButtonGroup>
    );
}

Upvotes: 5

Related Questions