cusejuice
cusejuice

Reputation: 10691

Extend Bootstrap Popover Plugin

I'm using Bootstrap 3's popover js file and by default when you hover/click the popover trigger (I only care about the left/right placement), the popover is vertically aligned in the middle from where the element is.

See this:enter image description here

However, I'd like to modify this default positioning regardless of the height of the popover.

Like this:

enter image description here

I tried the following, but because the popover's heights can be different I don't get exactly where I want it, which is like the second image above.

$('.trigger').popover({
   trigger: 'hover',
   container: 'body'
}).hover(function(){
   var off = $('.popover').offset(),
       delta = 50,
       newY = parseInt( off.top ) + delta + 'px';

   $('.popover').css({top: newY });
});

Any help?

EDIT: Is there a way to extend the Bootstrap tooltip js? I ended up having to change the source code by changing the Tooltip.prototype.getCalculatedOffset function. All I did was change the left/right placement to not subtract the actualHeight

Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
    // return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
    //        placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
    //        placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
    //     /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }

    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
       placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
       placement == 'left'   ? { top: pos.top + pos.height / 2, left: pos.left - actualWidth } :
       /* placement == 'right' */ { top: pos.top + pos.height / 2, left: pos.left + pos.width   }
  }

Is there a way that I could create my own placement type - like placement == 'custom-left' and placement = 'custom-right' ??

Upvotes: 2

Views: 2313

Answers (3)

user1752225
user1752225

Reputation: 21

theNeoteric has the correct answer. I also added the following to top align the popover arrow.

$.fn.popover.Constructor.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
    var intOffset = 32;
    if (delta != 0) { intOffset = intOffset - (delta / 2) } ;
    this.arrow()
    .css(isHorizontal ? 'left' : 'top', intOffset + 'px')
    .css(isHorizontal ? 'top' : 'left', '')
}

Upvotes: 1

theNeoteric
theNeoteric

Reputation: 41

This did the trick for me (for popovers, not toolips)

$.fn.popover.Constructor.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
    return  placement == 'bottom'? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 }:
            placement == 'top'? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 -actualWidth / 2 }:
            placement == 'left'? { top: pos.top + pos.height / 2, left: pos.left - actualWidth }:
            { top: pos.top + pos.height / 2, left: pos.left + pos.width };
};

Upvotes: 3

Pawel Uchida-Psztyc
Pawel Uchida-Psztyc

Reputation: 3838

Maybe this will help? (not tested). In short: wait until "shown" event fired and the setup position.

$('.popover').on('shown.bs.popover', function () {
  var off = $(this).offset(),
       delta = 50,
       newY = parseInt( off.top ) + delta + 'px';

   $(this).css({top: newY });
})

Upvotes: 0

Related Questions