Author avatar

Gaurav Singhal

How to Dismiss a React-Bootstrap Popover on Click Outside

Gaurav Singhal

  • May 21, 2020
  • 7 Min read
  • 144 Views
  • May 21, 2020
  • 7 Min read
  • 144 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

The React community has always made integrating open-source libraries easy for developers. React-Bootstrap provides great UI elements that can be used right out of the box as React Components. One of the most useful such components is a popover used to display additional content with an enhanced visual effect on the page. This guide explains how to dismiss a popover when a user clicks outside of it anywhere on the page.

Popovers

Popovers can be used in several ways, such as calculating the price of an inventory item in an e-commerce web app, displaying details of a new car model, etc. However, when using a UI component, be sure it is conveniently handled on the user's end. Attractive UI elements seem easy to use, but their complete use case should be correctly anticipated before implementing it in code. The basic feature that any modal, tooltip, or popover should have is easy opening and closing. Since popovers are triggered using a click event through a button, closing the same popover should be more customized in terms of end-user experience.

The default dismissing action of React Bootstrap popover is the same button that triggers it. The button that opens the popover on click acts like a toggle. The user, however, expects the popover to close when they click anywhere outside the page, just like modals, due to their similar interfaces.

Set up a Popover

Create a Project

Make sure you have Nodejs and npm installed in your machine (at least version 8 or higher) along with a code editor and a web browser (preferably Chrome or Firefox).

Create a new project using create-react-app:

1
npx create-react-app react-bootstrap-popover
shell

Instal React Bootstrap

Inside the root directory run the following command to install React Bootstrap library

1
npm install react-bootstrap bootstrap

This will install both Bootstrap and React Bootstrap inside the project.

Clean up the Template

For brevity, let's put all the code inside App.js . Remove the logo, App.css, and all their imports from App.js. Clean out the starter template inside the App component. Your App.js should look like this.

1
2
3
4
5
6
7
8
9
10
11
import React from 'react';

function App() {
  return (
    <div className="App">
      <h2>Hello</h2>
    </div>
  );
}

export default App;
jsx

Add the Popover Component

For regular Bootstrap styles to work correctly, import the Bootstrap styles on top.

1
import 'bootstrap/dist/css/bootstrap.min.css';
jsx

Above is equivalent to adding Bootstrap CDN in your index.html file. Now import three things; Popover, OverlayTrigger and Button from react-bootstrap

1
2
3
import Popover from 'react-bootstrap/Popover';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Button from 'react-bootstrap/Button';
jsx

To create a popover inside the Popover Component, render the Popover.Title component to indicate the title of the popover and Popover.Content Component to indicate it's content. Store this popover in a constant variable and output it inside the JSX template.

1
2
3
4
5
6
7
8
9
10
...
 const popover = (
    <Popover id="popover-basic">
      <Popover.Title as="h3">Popover title</Popover.Title>
      <Popover.Content>
        Popover content <strong>some strong content</strong> Normal content again
      </Popover.Content>
    </Popover>
  );
...
jsx

Output the popover inside an overlay and use the trigger prop to set the type of event the overlay listens for.

1
2
3
4
5
6
7
8
9
 ....
 return (
    <div className="App">
    <OverlayTrigger trigger="click" placement="right" overlay={popover}>
      <Button variant="success">Click to trigger popover</Button>
    </OverlayTrigger>
    </div>
  );
....
jsx

Finally, your App.js rendering the bootstrap popover should look like this .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Popover from 'react-bootstrap/Popover';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Button from 'react-bootstrap/Button';


function App() {
  const popover = (
    <Popover id="popover-basic">
      <Popover.Title as="h3">Popover title</Popover.Title>
      <Popover.Content>
        Popover content <strong>some strong content</strong> Normal content again
      </Popover.Content>
    </Popover>
  );
  
 
  return (
    <div className="App">
    <OverlayTrigger trigger="click" placement="right" overlay={popover}>
      <Button variant="success">Click to trigger popover</Button>
    </OverlayTrigger>
    </div>
  );
}

export default App;
jsx

To see the popover inside the root directory, run the following:

1
npm start

This will spin up a local development server (usually on port 3000) and you can see the popover button and the popover itself when you click the button. Clicking the same button again dismisses the popover.

Dismiss Popover on Outside Click

Let's look at the two simplest ways of dismissing the popover.

Use rootClose Prop

You can pass the additional prop rootClose to your OverlayTrigger component to dismiss the popover when on an outside click.

1
2
3
...
    <OverlayTrigger trigger="click" rootClose placement="right" overlay={popover}>
...
jsx

In the absence of this prop, a false Boolean value is taken by default by the parent component. When you pass this prop, the value is set to true and the onHide method is fired when the user clicks outside the overlay. The onHide method is just a callback invoked by the overlay when it wishes to be hidden and is required if rootClose is specified.

Use Focus Trigger to Dismiss Popover

Another method to dismiss the popover is by using a different trigger event. You can use the hover or focus trigger instead of the click trigger to achieve this. The hover trigger isn't the correct solution since it removes the clicking action on the popover, rendering it a tooltip. Use the focus trigger instead.

1
2
3
...
<OverlayTrigger trigger="focus" placement="right" overlay={popover}>
...
jsx

This will close the popover when the user clicks outside of it.

If you get any depreciated warnings or errors, you can use the exact version of react-bootstrap as this guide by updating your package.json file and running the command npm i .

1
2
3
4
....
"bootstrap": "^4.4.1",
"react-bootstrap": "^1.0.1",
....
json

Conclusion

Using attractive UI elements enhances the look of your app and makes the design more appealing. However, while using any UI element you must make sure that you're giving some flexibility to the end-user. A layman expects popovers to work like any popup and hence any similar functionalities should be implemented if they're not implemented by the default library. Using the rootClose prop is the safest, cleanest, and most accurate method, whereas using a different trigger than click could lead to inhomogeneity in your app. Both hover and focus triggers aren't handled well by devices, such as mobiles and tablets. Use the second method when your app is not catering to mobile-like devices.

0