6 var Drupal = Drupal || {};
8 (function ($, Drupal, Bootstrap) {
12 * Extend the Bootstrap Popover plugin constructor class.
14 Bootstrap.extendPlugin('popover', function (settings) {
17 animation: !!settings.popover_animation,
18 html: !!settings.popover_html,
19 placement: settings.popover_placement,
20 selector: settings.popover_selector,
21 trigger: settings.popover_trigger,
22 triggerAutoclose: !!settings.popover_trigger_autoclose,
23 title: settings.popover_title,
24 content: settings.popover_content,
25 delay: parseInt(settings.popover_delay, 10),
26 container: settings.popover_container
34 * @todo This should really be properly delegated if selector option is set.
36 Drupal.behaviors.bootstrapPopovers = {
37 attach: function (context) {
40 if ($.fn.popover.Constructor.DEFAULTS.triggerAutoclose) {
41 var $currentPopover = null;
43 .on('show.bs.popover', '[data-toggle=popover]', function () {
44 var $trigger = $(this);
45 var popover = $trigger.data('bs.popover');
47 // Only keep track of clicked triggers that we're manually handling.
48 if (popover.options.originalTrigger === 'click') {
49 if ($currentPopover && !$currentPopover.is($trigger)) {
50 $currentPopover.popover('hide');
52 $currentPopover = $trigger;
55 .on('click', function (e) {
56 var $target = $(e.target);
57 var popover = $target.is('[data-toggle=popover]') && $target.data('bs.popover');
58 if ($currentPopover && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) {
59 $currentPopover.popover('hide');
60 $currentPopover = null;
66 var elements = $(context).find('[data-toggle=popover]').toArray();
67 for (var i = 0; i < elements.length; i++) {
68 var $element = $(elements[i]);
69 var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data());
71 // Store the original trigger.
72 options.originalTrigger = options.trigger;
74 // If the trigger is "click", then we'll handle it manually here.
75 if (options.trigger === 'click') {
76 options.trigger = 'manual';
79 // Retrieve content from a target element.
80 var $target = $(options.target || $element.is('a[href^="#"]') && $element.attr('href')).clone();
81 if (!options.content && $target[0]) {
82 $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden');
83 options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || '';
86 // Initialize the popover.
87 $element.popover(options);
89 // Handle clicks manually.
90 if (options.originalTrigger === 'click') {
91 // To ensure the element is bound multiple times, remove any
92 // previously set event handler before adding another one.
94 .off('click.drupal.bootstrap.popover')
95 .on('click.drupal.bootstrap.popover', function (e) {
96 $(this).popover('toggle');
104 detach: function (context) {
105 // Destroy all popovers.
106 $(context).find('[data-toggle="popover"]')
107 .off('click.drupal.bootstrap.popover')
113 })(window.jQuery, window.Drupal, window.Drupal.bootstrap);