💬popover

… is a simple JavaScript module to create popover things. Mouse around this page to see it in action, or comb through the documentation below for more information.

Example:

<link rel="stylesheet" type="text/css" href="popover.css">
<script src="src/popover.js">
<script>
  var popover = new Popover();
  popover.on(
    'pop',
    function(target, popover) { window.console.log('pop', target, popover); }
  ).on(
    'unpop',
    function(target, popover) { window.console.log('unpop', target, popover); }
  );
</script>

#Configuring Popover Behaviour

Creating a Popover controller with no arguments passed to the initializer will initialize default behaviour. However, the class’ constructor accepts an optional argument with parameters to customize the following behaviour:

#Target Nodes

When creating a new Popover object all nodes under document.body are inspected. To restrict the search to a portion of the document pass an instance of HTMLNode or a query selector string to the initializer config:

// equivalent
new Popover({ root : '#doc' });
new Popover({ root : document.getElementById('doc') });

#Enabling/disabling

Once a controller is created, its popovers can be temporarily turned on and off by setting the `enabled` property to true or false, ex:

popover.enabled = false; // temporarily disable popovers
// ...
popover.enabled = true; // re-enable popovers

To permanently disable (& remove) popovers and clean up the listeners that have been attached to the relevant nodes, invoke the destroy method:

popover.destroy();

#Events

By default the popovers will appear and disappear when the mouse enters & leaves the node (or, in the case of touch interfaces, a touch starts and ends), respectively. To modify this behaviour, provide pop and unpop keys in the events property of the popover configuration object:

<input placeholder="textfield" type="text" name="" value="" data-popover='{"content":"This popover will appear/disappear on focus and blur, respectively","events":{"pop":"focus","unpop":"blur"}}'>
In action:

#Timing

By default the popovers will appear and disappear a brief period of time after the target element is hovered over or receives focus. This timing can be modified with the following options to the controller’s initializer:

delay.pop
the length of time between mouseenter (or focus) and when the popover will appear (in milliseconds)
delay.unpop
the length of time between mouseleave (or blur) and when the popover will appear (in milliseconds)
new Popover({
   delay : {
     pop : 1000, // wait one second before popover appears
     unpop : 0   // disappear immediately
  }
});

#Initialization via Node Attribute

By default popover content is retrieved from the target’s data-popover attribute, either as a simple string or a serialized JSON object, ex:

// equivalent
<span data-popover='{"content":"stuff"}'></span>
<span data-popover="stuff"></span>

In most instances, using a simple string attribute will be sufficient. However, in cases where you want to style a popover or add other hooks, it’s possible to apply a CSS class, for example:

<style type="text/css">
.rmr-popover.error { font-weight: bold; }
</style>
...
<em data-popover='{"content":"This is an error popover","class":"error"}'></em>

Similarly, it’s possible to add a visual clue to popover targets via CSS, ex:

*[data-popover]:after {
  content: "💬"
}

#Position & Color

Popovers will be positioned above their target elements unless a {"position" : "side"} is included in their data, and will be a very dark grey unless {"color" : "xxx"} is included.

By default popovers will appear immediately next to the target node in the special You are able to pass {"margin" : x} (where x is the number of pixels to offset).

# JavaScript Content

Rather than relying on node attributes to populate popovers, you may instead provide a factory method in the constructor’s options to programmatically generate popovers. The factory method receives the popover’s target node as its sole parameter. Much like data-popover attributes, the factory method can either return a simple string or an object containing the popover content and associated metadata:

var pop = new Popover({
  root : '#doc',
  attribute : 'data-name',
  factory : function(targetNode) {
    return { 'content' : popupLookup(targetNode.getAttribute('data-id')) }
  }
});

/*
 * Generate popover content based on an HTMLElement’s id attribute
 *
 * @param id {String} - value of target node’s id
 * @return {Object|String} - data for
 */
function popupLookup(id) {
  switch(id) {
    case "todo-label":
      return "Password must be 7 characters long";
      break;
    // ...
    default:
      return { "class" : "warning", content : "Field must be entered" };
  }
}

#Lifecycle

Popovers are controlled by mouse events (or touch events on mobile devices). However, the presence of a persist flag in the popover’s data will make the popover a permanent element in the page: created in the controller’s initialization and only removed if/when the controller’s destory method is invoked.

Caching Elements

Popover elements will be created when required and destroyed when no longer needed. Specifying a cache value of true in an individual field will create the popover element once and then toggle the visibility of the element if/when it is to be displayed in the future.

#Debugging

Add a debug field to the object’s constructor to make working with popovers easier while still in development. Information will be logged to the browser console and popovers will not be removed in debug mode.

new Popover({
   debug : true
});

#Release Notes

See the release notes.


#TODO