Ad

React-Bootstrap Trouble W/ ButtonGroup OR Where To Put Modals?

In react-bootstrap, I'm trying to create a reusable button class that will show a modal when clicked. Ultimately, the Modal will contain an "edit" form simple for modifying one-of-many entries in a table/list.

Here I've reduced the problem to a simple "confirm" dialog to try to get a minimally complete example.

The trouble I'm having is embedding a Modal inline with a Button within a ButtonGroup is breaking the formatting for the button group. Specifically, the custom ConfirmActionButton will shown as a stand-alone button, not part of the group.

I know I could solve the layout problem by moving the Modal outside the ButtonGroup entirely (and maybe that's the right thing to do?), but that seems less well-encapsulated / modular.

Is there a way to make this render like a normal button group? Or is rearranging where the Modal lives the only real way forward?

Here's what I have in jsfiddle as an example:

/* A bunch of var 'X = ReactBootstrap.X' lines ommitted here */

var ConfirmActionButton = React.createClass({
  getInitialState : function(){
    return {show : false};
  },
  ok : function(){ 
    this.setState({showModal:false}); 
    this.props.onClick();
  },
  cancel : function(){ 
    this.setState({showModal:false}); 
  },
  show : function(){ 
    this.setState({showModal:true}); 
  },
  render : function() {
    return (
      <span>
        <Button onClick={this.show} >
          {this.props.children}
        </Button>
        <Modal show={this.state.showModal} >
          <ModalHeader>Confirm</ModalHeader>
          <ModalBody>{this.props.confirmMessage}</ModalBody>
          <ModalFooter>
            <Button onClick={this.cancel}>Ok</Button>
            <Button onClick={this.ok}>Ok</Button>
          </ModalFooter>
        </Modal>
      </span>
    );
  }
});

var MyToolbar = React.createClass({

  render: function(){
    return (
      <ButtonToolbar>
        <ButtonGroup>
          <Button>Click Here</Button>
          <Button>No, Here</Button>
          <ConfirmActionButton confirmMessage="Are you sure?" 
                               onClick={this.someAction}
          >
            Do Something
          </ConfirmActionButton>
        </ButtonGroup>
      </ButtonToolbar>
    );
  },

  someAction : function()
  {
    alert("you did it");
  },
});

ReactDOM.render(
    <div>
      <MyToolbar />
    </div>,
    document.getElementById('example')
);
Ad

Answer

You can just put <Modal /> inside the <Button /> of <ConfirmActionButton /> and remove the <span> which is breaking the btn-grp layout.

    <Button onClick={this.show} >
      {this.props.children}
      <Modal show={this.state.showModal} >
        <ModalHeader>Confirm</ModalHeader>
        <ModalBody>{this.props.confirmMessage}</ModalBody>
        <ModalFooter>
          <Button onClick={this.cancel}>Cancel</Button>
          <Button onClick={this.ok}>Ok</Button>
        </ModalFooter>
      </Modal>
    </Button>
Ad
source: stackoverflow.com
Ad