7

I'd like to dynamically change the popover placement (left/right, top/bottom) depending on where the element is located on the screen.

//get_popover_placement(dom_el) returns 'left', 'right', 'top', or 'bottom'
    function set_popover(dom_el) {
    var the_placement = get_popover_placement(dom_el);
    $(dom_el).popover({
        offset: 10,
        placement: the_placement
    }).popover('show');
}

//set the placement on every hover
$('a[data-rel=popover]').hover(function(){
        set_popover(this);
    }, function(){});

It works the first time, but if the position of the element changes (when the window is resized, for example), the placement is not updated with subsequent calls to set_popover.

I added a little bit of code to get_popover_placement that adds a different color border to the element, depending on the placement. The border color gets updated every time, indicating the code is being called and the calculations are being done correctly, but the placement does not get updated.

It appears as though the placement option can only be set one time. How can I get around this limitation? Is there a variable somewhere that can be cleared to reset popovers?

BryanH
  • 5,826
  • 3
  • 34
  • 47
jeremiahs
  • 3,985
  • 8
  • 25
  • 30
  • 1
    My answer to a similar question may be useful to you: http://stackoverflow.com/questions/10238089/how-can-you-ensure-twitter-bootstrap-popover-windows-are-visible/10937083#10937083 – Cymen Jun 07 '12 at 17:56

2 Answers2

17

Try this change, using the .on() function in jQuery to attach an event listener:

Changed this reply by updating Kevin Ansfield's - added code to the placement function.

    $('a[data-rel=popover]').popover({
      placement: get_popover_placement
    });

    function get_popover_placement(pop, dom_el) {
      var width = window.innerWidth;
      if (width<500) return 'bottom';
      var left_pos = $(dom_el).offset().left;
      if (width - left_pos > 400) return 'right';
      return 'left';
    }
Calle
  • 1,690
  • 1
  • 17
  • 34
  • The effective result is the same as jeremiahs original code. The only difference is that he is using the .hover() shortcut function. – Kevin Ansfield Feb 13 '12 at 19:40
  • @KevinAnsfield You're right, after testing I updated the code to the same as yours, adding a usage scenario to the placement function. Thanks. – Calle Feb 14 '12 at 08:23
  • I tweaked this slightly because it was popping below the bottom of the window. `function get_popover_placement(pop, dom_el) { var width = window.innerWidth; var height = window.innerHeight; var top_pos = $(dom_el).offset().top; if (height - top_pos < 400) { return 'top'; } if (width < 500) { return 'bottom'; } var left_pos = $(dom_el).offset().left; if (width - left_pos > 400) { return 'left'; } return 'left'; }` – wsams Nov 05 '13 at 03:36
  • I used this one, but with the "right" option selected by "if (left_pos < width / 2) return 'right';". This way it tends to popover towards the middle of the page, or down if it's narrow. Excellent work. – Andrew Larned Dec 04 '13 at 20:06
6

I just checked the bootstrap source again and realised that functions passed to the placement property get passed arguments. I managed to achieve a similar thing to what you were attempting, try the following and see if it works for you:

$('a[data-rel=popover]').popover({
  offset: 10,
  placement: get_popover_placement
});

function get_popover_placement(pop, dom_el) {
  // your placement function code here
}
Kevin Ansfield
  • 2,343
  • 1
  • 19
  • 20
  • You just saved my day! Nice that the placement is nowhere documented, especially the fact that it receives arguments... – awendt Apr 08 '13 at 15:18