skip to Main Content

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

2

Answers


  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]");
    
    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search