1

i am quite new with this delegate thing for dynamic elements. so today i tested again with a generated dynamic template from some example in stackover for popover.

here is my dynamic html content.

<a id="testpop" class="btn btn-primary" data-placement="top" data-popover-content="#a1" data-toggle="popover" data-trigger="focus" href="#" tabindex="0">Popover Example</a>

  <!-- Content for Popover #1 -->
<div class="hidden" id="a1">
<div class="popover-heading">
This is the heading for #1
</div>

<div class="popover-body">
This is the body for #1
</div>
</div>

and then, i have this script on my js

$('#resultContent').on('click','#testpop', function(e) { //use on if jQuery 1.7+
// Enables popover #2

$("[data-toggle=popover]").popover({
    html : true,
    content: function() {
      var content = $(this).attr("data-popover-content");
      return $(content).children(".popover-body").html();
    },
    title: function() {
      var title = $(this).attr("data-popover-content");
      return $(title).children(".popover-heading").html();
    }
});
});

resultContent is the div here where i add .html all my html codes.

i manage to attached the delegate event (i think) but is acting strange as my 1st click on the testpop button, the popover won't show. Until i press the 2nd and 3rd time only it will pop up. Am i doing this delegating wrong?

credits for this test code: HTML inside Twitter Bootstrap popover

Community
  • 1
  • 1
user1897151
  • 493
  • 2
  • 9
  • 28
  • can you give us the code your working on instead of specific pieces? It would be easier to understand a working jsfiddle or codepen links. – Sreekanth Oct 15 '16 at 04:03

2 Answers2

1

You forgot to add a trigger in the popover options. The data-trigger in the element doesn't do too much when you really only initialize the popover() once you click the element. In fact, your JS code would propably work better like so:

$("[data-toggle=popover]").popover({
    html : true,
    trigger: 'click',
    content: function() {
      var content = $(this).attr("data-popover-content");
      return $(content).children(".popover-body").html();
    },
    title: function() {
      var title = $(this).attr("data-popover-content");
      return $(title).children(".popover-heading").html();
    }
});

EDIT

Popover should generally be initialized on page load:

$("[data-toggle=popover]").popover();

Putting it inside a click event will not enable popover on the element until you click it first.

Removing the click event from your original JS code should enable it on page load. If however, the element you mean to attach the popover to is dynamically added to the DOM after page load, you should reinitalize the popover after adding it. Wrapping the popover in a function would make that much easier.

function addPopover(selector){
$(selector).popover({
        html : true,
        trigger: 'click',
        content: function() {
            var content = $(this).attr("data-popover-content");
            return $(content).children(".popover-body").html();
        },
        title: function() {
            var title = $(this).attr("data-popover-content");
            return $(title).children(".popover-heading").html();
        }
    });
}

And whenever you add an element to the page that should have a popover, you simply call the function, with a selector for the element. Example for the element you have in your code:

addPopover("[data-toggle=popover]");
  • i added that trigger, but i am still facing the same issue whereby my 1st click is not showing the popup and i need to refocus and reclick the button only the popup shows – user1897151 Oct 15 '16 at 04:09
  • Did you remove the `$('#resultContent').on('click','#testpop', function(e) {` part? – Thor Juhasz Oct 15 '16 at 04:12
  • My answer here is meant to be the **full** js code, replacing your entire js code in the question. – Thor Juhasz Oct 15 '16 at 04:18
  • nope, totally not working at all if i remove the .on part. I need that if not mistaken since my content and title is dynamic populated. – user1897151 Oct 15 '16 at 04:20
  • The content and title function take care of reading from elements. The contents of those elements can well be dynamic. But you must initialize the popover on page load if you want it to be triggered you click, focus or hover over it. – Thor Juhasz Oct 15 '16 at 04:27
  • The way you have it is `when I click it, then initialize popover`, so subsequent clicks will work, but not the first one. – Thor Juhasz Oct 15 '16 at 04:28
  • Perfect for my usage. I'm using handlebars.js to dynamically load content. Since the popover is init'd before the content is loaded, the popovers were not binding to the new content. Using the function is a +1. Using the function approach, I simply run the function for any handlebar template loaded and viola, it works perfectly. Many of the other solutions I found (not in this SO question) would flicker/double flash but not this solution. – HPWD Sep 20 '18 at 01:19
0

In your code, you are configuring the popover on click event of the button.

So, this is how it happens.

  • Click the anchor link
  • Initialize the popover with options. (This doesnt mean it displays the popover, it is just a initialization)
  • Click on the popover again (Popover is already bound because of the earlier call and then it shows)

Also, you need to ensure the popover is not bound to the element again and again to avoid repeated popover bindings.

$('#resultContent').on('click', '#testpop', function(e) { //use on if jQuery 1.7+
  // Enables popover #2

  $("[data-toggle=popover]").popover({
    html: true,
    content: function() {
      var content = $(this).attr("data-popover-content");
      return $(content).children(".popover-body").html();
    },
    title: function() {
      var title = $(this).attr("data-popover-content");
      return $(title).children(".popover-heading").html();
    }
  }).popover('show');
  // Explicitly show the popover.
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div id="resultContent">
  <a id="testpop" class="btn btn-primary" data-placement="bottom" data-popover-content="#a1" data-toggle="popover" data-trigger="focus" href="#" tabindex="0">Popover Example</a>
</div>

<!-- Content for Popover #1 -->
<div class="hidden" id="a1">
  <div class="popover-heading">
    This is the heading for #1
  </div>

  <div class="popover-body">
    This is the body for #1
  </div>
</div>
Sreekanth
  • 3,110
  • 10
  • 22