Bootstrap popover content cannot changed dynamically
Asked Answered
I

16

67

I use the code as follows:

$(".reply").popover({
  content: "Loading...",
  placement: "bottom"
});

$(".reply").popover("toggle");

which creates the popover and its content correctly. I want to load a new data into the popover without closing the popover.

I've tried the following:

var thisVal = $(this);
$.ajax({
  type: "POST",
  async: false,
  url: "Getdes",
  data: { id: ID }
}).success(function(data) {
  thisVal.attr("data-content", data);
});

After this call the data in the element is changed but not in the popover which is shown.

How should i do this?

Ironlike answered 26/11, 2012 at 12:23 Comment(1)
you can also access the popover's inner element and change the content there via jQuery, e.g. $(".popover-content").html(my_new_content)Ronn
R
86

If you grab the popover instance like this:

var popover = $('.reply').data('bs.popover');

Then, to redraw the popover, use the .setContent() method:

popover.setContent();

I found out browsing the source: https://github.com/twitter/bootstrap/blob/master/js/popover.js

So, in your example, try:

thisVal.attr('data-content',data).data('bs.popover').setContent();

Update

The setContent() method also removes the placement class, so you should do:

var popover = thisVal.attr('data-content',data).data('bs.popover');
popover.setContent();
popover.$tip.addClass(popover.options.placement);

Demo: http://jsfiddle.net/44RvK

Renferd answered 26/11, 2012 at 12:47 Comment(11)
ya it works but the design of the popover changed after redrawing is there any way to keep the existing designIronlike
Yea, it seems to remove the placement class too, so just add the class again. See demo: jsfiddle.net/44RvKRenferd
The popover is not re-positioned after changing the content to something that takes up more space: jsfiddle.net/g4kZS - only when it is closed and opened again.Beall
This way have too many side effect, see my answer below, much easier and better in my opinionConfidence
the source file is github.com/twitter/bootstrap/blob/master/js/popover.jsEngulf
recently the data tag for popover was changed, so you need to use .data('bs-popover') instead of .data('popover')Engulf
.data('bs.popover') instead of .data('popover') in the latest versionGargantuan
Updated this to bs.popover.Thirtyone
If you need to reposition the offset calculated_offset = popover.getCalculatedOffset( popover.options.placement, popover.getPosition(), popover.$tip[0].offsetWidth, popover.$tip[0].offsetHeight); popover.applyPlacement(calculated_offset, popover.options.placement); A little bit messy...Wapentake
Using bootstrap 4, there is no problem with the placement being lost but you need to call popover.update() after popover.setContent() to reposition the popover according to the content.Spathe
real heroes don't wear capes.Levey
C
77

Yes you can, in fact the easiest way haven't been suggested yet.

Here's my way ->

    var popover = $('#example').data('bs.popover');
    popover.options.content = "YOUR NEW TEXT";

popover is an object if you want to know more about it, try to do console.log(popover) after you define it to see how you can use it after !

EDIT

As of Bootstrap 4 alpha 5, the data structure is a bit different. You'll need to use popover.config.content instead of popover.options.content

Thanks to @kfriend for the comment

Confidence answered 25/7, 2013 at 17:27 Comment(6)
it's working fine, just set content as Yann specified then call popover.show(). that's the best answer "short, no side effects to counter like some of other answers"Welldefined
I used this for popover.options.placement = 'bottom', thanks Yann!Madder
.data('bs.popover') instead of .data('popover') in the latest versionGargantuan
Worked for me in BS3; quick n' easy. I think it's the best answer here.Ethnarch
This should be the accepted answer, no messing around with classes or anything - simples.Monserratemonsieur
As of Bootstrap 4 alpha 5, the data structure is a bit different. You'll need to use popover.config.content instead of popover.options.content.Pandemic
P
22

In bootstrap 3:

if($el.data('bs.popover')) {
    $el.data('bs.popover').options.content = "New text";
}
$el.popover('show');
Pastrami answered 20/2, 2014 at 17:53 Comment(0)
N
17

This answer from 2012 does not work with Bootstrap 3 popovers. I extracted a working solution from this question:

$("#popover").attr('data-content', 'new content');

Ninepins answered 15/2, 2017 at 18:35 Comment(2)
This is absolutely the only way I got this to work on a specific popover with bootstrap 3. For some reason, $("#popover").data('content', 'new content'); does not work so I originally ignored this solution. Thanks!Sharenshargel
yup, on bs3, this was my only option on dynamic changes - thanksMedusa
I
10

Most of these solutions actually seem hacky to me. Bootstrap standard docs have a method destroy that can be used. So, on change of content via some event you can simply destroy and then recreate content.

.popover('destroy')

This properly dynamically loads, refreshes and re-renders the content of the popover.

Idioblast answered 15/1, 2015 at 2:25 Comment(2)
Creating the popover isn't that complicated and I have also had good luck with using destroy and then re-creating the popover.Confetti
Here's a fiddle that can load dynamic data, but its flashes the popover. jsfiddle.net/dbuj2Lnt/1Saipan
J
4

SIMPLE SOLUTION

You can try with this :

//Bootstrap v3.3.7 var popoverEl = $("#popover"); popoverEl.attr("data-content", "NEW CONTENT"); popoverEl.popover("show");

Thanks.

Jonas answered 29/9, 2016 at 0:36 Comment(4)
This is the correct answer for Bootstrap 3.x. No need to use setContent().This works with a string or HTML content.Follicle
Yes, I agree with this for Bootstrap 3.xJonas
calling popoverEl.popover("show") makes my already visible popover go away :-(. I just wanted it to rerender correctly in the right location with the new data. I'm using bootstrap 3.3.7.Embodiment
it should be add with #19975059. Thanks :)Loop
B
3

I solved the problem using @David and @Sujay sreedhar's answer, but if the popover is visible during the new content is loaded, the popover needs to be repositioned:

var popover = thisVal.attr('data-content',data).data('popover');
popover.setContent();
popover.$tip.addClass(popover.options.placement);
// if popover is visible before content has loaded
if ($(".reply").next('div.popover:visible').length){
    // reposition
    popover.show();
}

If it is not repositioned and the new content has e.g. a different height, the popover will expand downwards and the arrow will be off target!

Also, when the button is clicked afterwards it will re-open the popover instead of closing it. The above code solves, that problem too.

Demo http://jsfiddle.net/whFv6/

(My edit was rejected, so I thought I'd post it here..)

Beall answered 6/6, 2013 at 10:49 Comment(0)
C
1

After the popover has been correctly initialized, you can directly use jquery to replace the class="popover-content" element:

$(".popover-content").html('a nice new content')
Chimb answered 10/2, 2015 at 15:51 Comment(1)
I like the idea but how would you update the content of a specific popover, if you have several initialized on a page?Capitalist
E
1

you can just pass the title as function

var content = 'Loading...'

function dynamicContent(){
  return content
}
$(".reply").popover({
  content: dynamicContent,
  placement: "bottom"
});

$(".reply").popover("toggle");

and then change the variable content dynamically.

Enschede answered 23/8, 2016 at 11:58 Comment(0)
B
1
<button data-toggle="popover" data-html="true" data-content='<div id="myPopover">content</div>'>click</button>
$('#myPopover').html('newContent')

This is a very clean way.

Berget answered 18/12, 2017 at 17:44 Comment(1)
+1 That totally made my day, used within the $( 'a[data-toggle="popover"]' ).on('inserted.bs.popover', function () {}); thing.Cainozoic
M
0

I wrote an async popover for bootstrap 3.1.1. I just called it popoverasync. Here is a demonstration:

async popover demo

You can download the source of the demo here:

demo source

The trick, for me, was to write the getContent method of this async popover so the user's javascript function to retrieve the content will be invoked, but getContent will return a wait animation, synchronously, back to the caller of getContent. This way, the popover has content either way. First, while the user waits, and finally when the content arrives. What I am referring to can be found within extensions.js in the demo source:

Hope this helps you!

Dan

Margarettamargarette answered 7/3, 2014 at 15:57 Comment(2)
I used the async pop-over and found out that if I am using ajax, the ajax is fired two times. First during .hasContent() check and second during .setContent(). Is there anyway to stop this?Epicycloid
Please create a Github repo to log issues.Epicycloid
C
0

HTML

<a data-toggle="popover" popover-trigger="outsideClick" title="Indicadores" data-content="" data-html="true" class="Evaluar" id="alun codigo"><span><i class="fa fa-check"></i>algun nombre</span></a>

JQUERY

$('a.Evaluar').on('click', function () {
    var a=$(this);//.attr('data-content', "mañana");
    $.ajax({
        url: "../IndicadorControlador?accion=BuscarPorProceso&cP=24",
        type: 'POST',
        dataType: 'json'
    })
            .done(function (response) {
                //alert("done. ");
                var ind = "";
                $(response).each(function (indice, elemento) {
                    //alert(elemento.strIdentificador);
                    //console.log('El elemento con el índice ' + indice + ' contiene ' + elemento.strIdentificador.toString());
                    ind += '<a href=#>'+elemento.strIdentificador.toString()+'</a>';
                });
              $(a).attr('data-content', ind);
            })
            .fail(function () {
                sweetAlert("ERROR!", " Algo salió mal en el controlador!", "error");
            })
            .complete(function () {
            });

    $('[data-toggle="popover"]').popover();
});
Circumjacent answered 1/8, 2016 at 22:33 Comment(0)
D
0

When a popover is enabled, it retains its previous version(if it was created already) even if the data is change. You need to destroy the previous version to allow for the new popover to be created again. In Bootstrap 4.x do it by

.popover('dispose')

do it whenever there is a change in data through an ajax call.

Disorder answered 4/1, 2019 at 7:24 Comment(0)
P
0

For Boostrap v4.3

The following code update the popover content just before it is displayed:

// When the popover is show
$('.my-popover').on('show.bs.popover', function () {
  // Update popover content
  $(this).attr('data-content', 'New content');
})

Test online on this JSFiddle.

Piane answered 22/12, 2019 at 8:54 Comment(2)
Popover doesn't even toggle in the fiddle & this will not update it realtime, it will work when the popover is closed & open again.Saipan
Here's a solution I'm using. https://mcmap.net/q/226261/-how-to-update-bootstrap-popover-textSaipan
F
0

With bootstrap 4.6 I am using this code to update it:

$("#disk-usage-details").attr("data-content", "your new content to here");

all others did not work for me.

Forbore answered 27/3, 2021 at 8:44 Comment(1)
Last solution on the page - of course :) For me this also was the only solution I could get to work with BS 4.6Draughtboard
C
0

Bootstrap v5

var element = document.getElementById('popElement');
var popover = bootstrap.Popover.getOrCreateInstance(element, { trigger: 'hover' });
element.addEventListener('shown.bs.popover', () => {
   // call your api, then:
   popover.setContent({ '.popover-body': 'updated content' });
}, {once : true});
Copycat answered 21/6, 2023 at 7:45 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.