Skip to main content
Figuration v4.4 is now available!
Widgets

Bring interactivity to your site with a selection of jQuery widgets (plugins) all built with accessibility and usability in mind.

Popover popover.js

A more robust version of a tooltip, that allows for larger pieces of content or interactive functionality.

Widget Dependencies

Popover requires the following:

Page Contents

Overview

Important notes about using the popover widget:

  • Specify container: 'body' to avoid rendering problems in more complex components (like our input groups, button groups, etc).
  • Triggering popovers on hidden elements will not work.
  • Popovers for .disabled or disabled elements must be triggered on a wrapper element.
  • When triggered from anchors that wrap across multiple lines, popovers will be centered between the anchors' overall width. Use white-space: nowrap; on your <a>s to avoid this behavior.

Examples

Static Popover

Four options are available: top, forward( right), bottom, and reverse (left) aligned.

Heads up! When using the right-to-left, rtl, variant of Figuration all horizontal directions will be reversed. Meaning left becomes right, and vice-versa.

Popover top

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

Forward popover

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

Popover bottom

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

Reverse popover

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

Four Directions

<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="top" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on top
</button>

<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="forward" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Forward popover
</button>

<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="bottom" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on bottom
</button>

<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="reverse" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Reverse popover
</button>

Default Toggle Example

<button type="button" class="btn btn-info" data-cfw="popover" title="Click Popover Example" data-cfw-popover-content="Click the trigger or close button to close me." data-cfw-popover-placement="forward">Click to toggle popover</button>

Hover Example

<button type="button" class="btn btn-info" id="cf-example-hover-popover" data-cfw="popover" title="Hover Popover Example" data-cfw-popover-content="Stop hovering over the trigger or the popover to auto-close." data-cfw-popover-placement="forward" data-cfw-popover-trigger="hover focus">Hover/focus to show popover</button>

Draggable Example

Allow users to move popovers around the screen by enabling the drag option. Drag support mouse, keyboard (with arrow keys), and touch movement.

<button type="button" class="btn btn-info" data-cfw="popover" title="Draggable Popover Example" data-cfw-popover-content="Click the trigger or close link to close me." data-cfw-popover-placement="forward" data-cfw-popover-drag="true">Draggable popover</button>

Popover with HTML

<button type="button" class="btn btn-info" data-cfw="popover" data-cfw-popover-html="true" data-cfw-popover-placement="forward" data-cfw-popover-content="<em>Popover</em> <u>with</u> <b>HTML</b>" title="<em>Popover</em> <u>with</u> <b>HTML</b>">Popover with HTML</button>

If using more complex HTML, using a data attribute might not be optimal. A better option would be to use the Javascript options, or with a pre-generated popover, as shown in the following example.

<button type="button" class="btn btn-info" id="html-popover">Popover with HTML</button>

<script>
$('#html-popover').CFW_Popover({
html: true,
title: '<em>Popover</em> <u>with</u> <b>HTML</b>',
content: '<span aria-hidden="true">&middot;</span> <em>Popover</em> <u>with</u> <b>HTML</b>'
});
</script>

Pre-generated Popover

Have a complex content that you would like to show in a popover, or one that is updated dynamically? Create the popover and then link to it with the target option.

Popover title

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

Sample image
Sample image caption.
<button type="button" class="btn btn-info" data-cfw="popover" data-cfw-popover-target="#popoverExample0" data-cfw-popover-placement="forward">Show Popover</button>

<div class="popover" id="popoverExample0">
<h3 class="popover-header">Popover title</h3>
<div class="popover-body">
<p>Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p>
<figure class="figure">
<img src="/assets/3.0/img/test.gif" class="figure-img img-fluid" alt="Sample image">
<figcaption class="figure-caption">Sample image caption.</figcaption>
</figure>
</div>
<div class="popover-arrow"></div>
</div>

Custom Placement

Locate a popover anywhere you need with the placement option.

<button type="button" class="btn btn-info" id="cf-example-placed-popover" title="Custom placed popover" data-cfw-popover-content="Look, I am way over here!">Custom Placement Popover</button>
<script>
$('#cf-example-placed-popover').CFW_Popover({
placement : function(tip, trigger) {
var $trigger = $(trigger);
var loc = {};
var pos = $trigger.offset();
loc.top = pos.top;
loc.left = pos.left + $trigger.parent().width() - $trigger.outerWidth();
return loc;
}
});
</script>

Viewport Constrainment

Keep popovers in their place with the viewport option.

Viewport constraints for popovers.

<div class="container-viewport" id="viewport-popover">
<p class="viewport-text">Viewport constraints for popovers.</p>
<button type="button" class="btn btn-info popover-viewport-bottom" title="This should be shifted to the right">Shift Right</button>
<button type="button" class="btn btn-info popover-viewport-right" title="This should be shifted down">Shift Down</button>
<button type="button" class="btn btn-info float-end popover-viewport-bottom" title="This should be shifted to the left">Shift Left</button>
<button type="button" class="btn btn-info popover-viewport-right btn-bottom" title="This should be shifted up">Shift Up</button>
<button type="button" class="btn btn-info popover-viewport-drag btn-drag" title="This should be confined to the viewport box">Drag Test (click)</button>
</div>
<script>
$('.popover-viewport-right').CFW_Popover({
placement: 'forward',
viewport: '#viewport-popover',
padding: 2
});
$('.popover-viewport-bottom').CFW_Popover({
placement: 'bottom',
viewport: '#viewport-popover',
padding: 2
});
$('.popover-viewport-drag').CFW_Popover({
drag: true,
viewport: '#viewport-popover',
padding: 2
});
</script>

Disabled Elements

Elements with the disabled attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper <div> or <span> and override the pointer-events on the disabled element.

For disabled popover triggers, you may also prefer data-cfw-popover-trigger="hover" so that the popover appears as immediate visual feedback to your users as they may not expect to click on a disabled element.

<span class="d-inline-block" data-cfw="popover" data-cfw-popover-content="Popover for disabled item">
<button class="btn btn-primary" style="pointer-events: none;" type="button" disabled>Disabled button</button>
</span>

Usage

The popover widget, by default, generates content and markup on demand, and by default places popovers after their trigger element.

Via Data Attributes

The required markup for a popover is only a data-cfw="popover" attribute and title or a data-cfw-popover-content="" on the HTML element you wish to have a popover. The generated markup of a popover is rather simple, though it does require a position (by default, set to top by the widget).

If the popover item is already created, you can link to it using data-cfw-popover-target="#somePopover", or href="#somePopover". The proper role and aria- attributes will be automatically created to link the trigger and target elements.

Via JavaScript

Enable manually with:

$('#myPopover').CFW_Popover();

Close Triggers

Any element with a data attribute of data-cfw-dismiss="popover" within the popover element will act as a close trigger for the popover. There can be multiple close triggers, such as a header/titlebar close and a cancel button in the footer.

Draggable Popovers

The added functionality from the Drag widget allows for touch and mouse dragging to be available.

The drag event handlers will auto-enable when a data-cfw-drag="popover" trigger item is found within the popover item. The drag option will insert a drag trigger into the popover element, resulting in invoking the drag handlers.

Draggable popovers will force the following settings:

  • container: 'body'
  • trigger: 'click'

Options

Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-cfw-popover, as in data-cfw-popover-placement="forward".

Name Type Default Description
target string null The selector (jQuery style) of the target popover.
animate boolean true If popover items should fade in and out.
placement string | object | function 'top'

string:
How to position the popover - top | bottom | reverse | forward | auto.
When "auto" is specified, it will dynamically reorient the popover. For example, if placement is "auto reverse", the popover will display to the left when possible, otherwise it will display right. (Opposite horizontal directions apply for rtl mode.)

object:
This is a way to custom position a popover in a specific place not handled by the standard placement locations. A custom positioned popover is forced to using the <body> as the container to make positioning easier. Object structure is: placement: { top: 5, left: 10 }, the same as jQuery offset.

function:
A function call can return either a string or object placement type. The function allows access to the complete popover data-api, as well as passing the popover target and trigger as arguments.

function myPopoverAlign(tip, trigger) {
  // this - popover data-api
  // tip -> popover target
  // trigger -> popover trigger
}
trigger string 'hover focus' How popover is triggered - click | hover | focus | manual. You may pass multiple triggers; separate them with a space. manual cannot be combined with any other trigger.
delay number| object show:0, hide:250

Delay showing and hiding the popover (ms) - does not apply to manual trigger type.

If a number is supplied, delay is applied to both hide/show.

Object structure is: delay: { show: 500, hide: 100 }
container string | false false Appends the popover to a specific element. Example: container: 'body'
viewport string | function 'body'

Keeps the popover within the bounds of this element. Example: viewport: '#viewport'.

If a function is given, it is called with the triggering element DOM node as its only argument. The this context is set to the popover instance.

padding integer 0 Spacing, in pixels, to keep the popover away from the viewport edge.
html boolean false Insert HTML into the popover. If false, jQuery's text method will be used to insert content into the DOM. Use text if you're worried about XSS attacks.
closetext string '<span aria-hidden="true" >&times;</span>' Visible text for close links when using option trigger: 'click'
closesrtext string 'Close' Screen reader only text alternative for close links when using option trigger: 'click'
title string | function '' Default title value if title attribute isn't present.
content string | function '' Default title value if data-cfw-popover-content attribute isn't present.
unlink boolean false If the unlink method should be called when the popover is hidden. This leaves the popover behind in the DOM.
dispose boolean false If the dispose method should be called when the popover is hidden. This will remove the popover from the DOM.
drag boolean false If the popover should have a drag handle inserted.
dragtext string '<span aria-hidden="true" >+</span>' Visible text for the auto-inserted drag handle.
dragsrtext string 'Drag' Screen reader only text alternative for the auto-inserted drag handle.
dragstep integer 10 Pixel increment to move the popover when using arrow keys on a drag handle.
show boolean false Show the popover automatically at the end of initialization. This will force the trigger option to a setting of 'click'.

Methods

.CFW_Popover(options)

Activates a popover on a given element. Accepts an optional options object.

$('#myPopover').CFW_Popover({
placement: 'forward'
});

.CFW_Popover('toggle')

Toggles a popover item to be shown or hidden.

.CFW_Popover('show')

Shows an element's popover.

.CFW_Popover('hide')

Hides an element's popover.

Hides the popover, removes events and attributes from both trigger and popover.

.CFW_Popover('dispose')

Calls the unlink method, and then removes the popover from the DOM.

Events

Event callbacks happen on the toggle/trigger element.

Event Type Description
init.cfw.popover This event fires after the popover item is initialized.
beforeShow.cfw.popover This event is fired immediately when the show method is called. If the popover container is not present, it is created just after this event is called.
afterShow.cfw.popover This event is fired when a popover has been made visible to the user (will wait for CSS transitions to complete).
beforeHide.cfw.popover This event is fired immediately when the hide method is called.
afterHide.cfw.popover This event is fired when a popover has been hidden from the user (will wait for CSS transitions to complete).
inserted.cfw.popover This event is fired after the beforeShow.cfw.popover event when the popover has been added to the DOM.
dragStart.cfw.popover This event is fired at the start of the drag action.
dragEnd.cfw.popover This event is fired at the end of the drag action.
beforeUnlink.cfw.popover This event is fired immediately when the unlink method is called. This event can occur after the beforeHide event if set to automatically unlink, or before if called via method.
afterUnlink.cfw.popover This event is fired when a popover item has been unlinked from its trigger item and the data-api removed. This event can occur after the afterHide event when invoked from the unlink method, or before if set to automatically unlink.
dispose.cfw.popover This event is fired immediately before the popover item is removed from the DOM.
$('#myPopover').on('afterHide.cfw.popover', function () {
// do something...
});

Server-side Apps

Popovers are designed to hopefully work with server side applications, such as Apache Wicket, and other instances where the server-side application might need to create or update the popover content after the initial page load.

A quick example:

  1. An item with an event handler that makes a callback to create a new popover is interacted with.
  2. Call as needed:
    • $('#myPopover').CFW_Popover('hide');
    • or $('#myPopover').CFW_Popover('unlink');
    • or $('#myPopover').CFW_Popover('dispose');
  3. Update/create the popover object and insert into DOM.
  4. Initialize the popover: $('#myPopover').CFW_Popover(options); with desired options.
  5. Show popover: $('#myPopover').CFW_Popover('show');

Accessibility

Key Commands

The following key commands are handled when focus is inside the popover:

  • Esc - Close the popover

Focus Handling

Popovers have additional focus handling when using keyboard navigation.

If navigating from above the popover's trigger (typically with the tab key), the trigger becomes focused, the next forward focus will move from the trigger to the first focusable item inside the popover.

If navigating from below the popover's trigger (typically with the shift-tab key combination), when the trigger is focused, focus will be moved from the trigger to the last focusable item inside the popover.

When navigating forward, out the bottom of the popover, the focus will be moved to the next focusable item in the document relative to the trigger. This is done so that if the container option is used, the focus will move to next logical item. Otherwise, when using container: body, the focus will potentially drop off the end of the HTML document, leaving a keyboard user in an akward situation.

When navigating backward, out the top of the popover, the focus will be moved to the trigger.

This will not necessarily work with some assistive technologies reading modes.