React Bootstrap Modal Form
Tags: react, bootstrap, form
Published: 2020-12-29 20:59:44

##**Introduction**
During my Phase 4 at Flatiron School, I encountered React for the first time and was mind-blown by the variety and how functional it is. Similar to Vanilla Javascript with Bootstrap to help with styling, React also has React-Bootstrap, which generates components from scratch as a true React component. React-Bootstrap Modal Forms are pretty commonly used in front-end applications. In this tutorial, I will show you how to: 
* Install React-Bootstrap.
* Import React-Bootstrap Components.
* Show/Hide a Modal Form.
* Apply basic CSS on a Modal Form.

Now let's get started!

##**Install React-Bootstrap**
There are two ways to install React-Bootstrap, but I'd prefer using the first one:
```
npm i react-bootstrap bootstrap
# or
yarn add react-bootstrap bootstrap
```
##**Import React-Bootstrap Components**
First of all, what is a Modal Component? You can think of Modal as a pop-up notification with confirmation/input form/etc.

<img src="https://media.giphy.com/media/jfRjj10Gcdru72n17a/giphy.gif" alt="modal demonstration" >

Now let's import our Modal Component from React-Bootstrap:
```javascript
import 'bootstrap/dist/css/bootstrap.min.css'
import Modal from 'react-bootstrap/Modal'
```
A Modal has 3 basic sections: *Header*, *Body*, *Footer*. Each section (or sub-component) holds the information we want to show on our DOM. 

To declare a specific sub-component of Modals, we can use `Modal.<section>`:
```react
class ModalForm extends Component {
  return(
    <Modal show={true} onHide={handleClose}>
      <Modal.Header closeButton>
        <Modal.Title>Modal heading</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        Woohoo, you're reading this text in a modal!
      </Modal.Body>
      <Modal.Footer>
        <Button variant="primary" onClick={handleSubmit}>
          Submit 
        </Button>
      </Modal.Footer>
    </Modal>
  )
}
```

Or we can also declare each sub-component by importing them separately from React-Bootstrap:

```javascript
import 'bootstrap/dist/css/bootstrap.min.css'
import Modal from 'react-bootstrap/Modal'
import ModalBody from "react-bootstrap/ModalBody";
import ModalHeader from "react-bootstrap/ModalHeader";
import ModalFooter from "react-bootstrap/ModalFooter";
import ModalTitle from "react-bootstrap/ModalTitle";
```

Our ModalForm component will be altered to this:

```react
class ModalForm extends Component {
  return(
    <Modal show={true} onHide={handleClose}>
      <ModalHeader closeButton>
        <ModalTitle>Modal heading</ModalTitle>
      </ModalHeader>
      <ModalBody>
        Woohoo, you're reading this text in a modal!
      </ModalBody>
      <ModalFooter>
        <Button variant="primary" onClick={handleSubmit}>
          Submit 
        </Button>
      </ModalFooter>
    </Modal>
  )
}
```

So we're done with the basic skeleton of a Modal Component. Time to make it more interactive!
![alt text](https://media.giphy.com/media/xUOwG5IshvzNMdzR72/giphy.gif "Basic")

##**Show/Hide a Modal Form**
A modal form is shown/hidden from UI by using `show` property. Initially, I hard-coded the value to `true` but in a real react application, we would need to add logic to toggle our `show` property.

In our `App.js`:

```javascript
class App extends React.Component {
 state = {
    isOpen: true
 }
}
```
Setting the initial state of isOpen to false indicates our ModalForm is not activated yet and true for an activated form.

```react
import ModalForm from './component/ModalForm';
class App extends React.Component {
  state = {
    isOpen: true
  }

  openModal = () => this.setState({ isOpen: true });
  closeModal = () => this.setState({ isOpen: false });
  handleSubmit(name) => //some code

  render(){
    return(
      <div>
        {/* other components */}

        <button onClick={this.openModal}>Display Modal Form</button>

        { this.state.isOpen ? 
          <ModalForm 
            closeModal={this.closeModal} 
            isOpen={this.state.isOpen} 
            handleSubmit={this.handleSubmit}
          /> 
          : 
          null 
        }
      </div>
    )
  }
}
```

I declared 3 functions: `openModal` to set isOpen to true when modal form is activated, `closeModal` to close modal form and also include a ternary to conditionally rendering modal form on App component. 

Now let's add our Form sub-components to ModalForm to make it a form inside our modal:

```react
import Form from 'react-bootstrap/Form'
import Modal from 'react-bootstrap/Modal'
import Button from 'react-bootstrap/button'

export default class ModalForm extends Component {

  state={ name: null }

  handleChange = (e) => this.setState({name: e.target.value})

  render(){
    return(
      <Modal 
        show={this.props.isOpen} 
        onHide={this.props.closeModal}
      >
      <Modal.Header closeButton>
        <Modal.Title>Modal Form Title</Modal.Title>
      </Modal.Header>
      <Modal.Body>
          <Form.Group >
              <Form.Label>Name: </Form.Label>
              <Form.Control type="text" onChange={this.handleChange} value={this.state.name} placeholder="name input"/>           
          </Form.Group>
      </Modal.Body>
      <Modal.Footer>
          <Button variant="primary" type="submit" onClick={() => this.props.handleSubmit(this.state.name)}>
              Submit
          </Button>
      </Modal.Footer>
    </Modal>
    )
  }
}
```

In ModalForm component, I added an initial state of name and set it to null, our form's input value is stored in this state. Our `show` property is now linked to `isOpen` state, inherited from App. The new `onHide` property is necessary if you want to exit modal form by pressing **esc key** or clicking on **non-static backdrop**.

For our newly added Form sub-components, I added `handleChange` and `value` property to create a controlled form (read more about controlled/uncontrolled form [here](https://reactjs.org/docs/forms.html)). In `Modal.Footer`, I also added a `handleSubmit` function to handle form's input value and send it back to App.

##**Apply basic CSS on a Modal Form**

Applying basic styling for our modal form:

```javascript
render(){
  return(
    <>
      <div
      className="d-flex align-items-center justify-content-center"
      style={{ height: "100vh" }}
      >
      </div>

      <Modal 
        show={isOpen} 
        onHide={closeModal}
        backdrop="static"
      >
      <Modal.Header closeButton>
        <Modal.Title>Modal Form Title</Modal.Title>
      </Modal.Header>
      <Modal.Body>
          <Form.Group >
              <Form.Label>Name: </Form.Label>
              <Form.Control type="text" onChange={this.handleChange} value={this.state.name} placeholder="name input"/>           
          </Form.Group>
      </Modal.Body>
      <Modal.Footer>
          <Button variant="primary" type="submit" onClick={() => handleSubmit(this.state.name)}>
              Submit
          </Button>
      </Modal.Footer>
    </Modal>
  </>
  )
}
```
`<>` and `</>` is a shorter syntax to declare fragments in react. I also added `backdrop` property in our Modal component ad set it to `static`. This way, our modal form will not be closed on pressing **esc key** or clicking on non-static backdrop.

##**Conclusion**
React-Bootstrap is a very powerful tool for developer, you are getting the best of both worlds technically. For Modal, besides making a modal form, there can be so many varieties of modals (ex: grid modal, centered modal, optional size, etc). 

Thank you for making it this far, I hope this tutorial is helpful and stay tune for more! :)

####**Helpful Links:**
* [React Bootstrap Modal](https://react-bootstrap.github.io/components/modal/) 
* [Modal Events](https://www.pluralsight.com/guides/working-with-bootstraps-modals-react)