'Bootstrap popover repeats an action/ event twice?

Why Bootstrap's popover repeats an action twice? For instance, I want to submit a form inside the popover's data-content via ajax. It repeats all the form data twice and the posts form twice.

Any idea what I can do about it?

jquery + bootstrap,

$('.bootstrap-popover-method').popover({
    placement: 'bottom',
    container: 'body',
    html:true,
    content: function () {
        var p = $(this);
        var data = $('#popover-content').html();
        $('#popover-content').remove();
        p.attr("data-content", data);
        p.popover('show');
    }
});

$('.bootstrap-popover-method').on('shown.bs.popover', function () {
    // do something…
    console.log(this); // I get twice of the button element <button class="btn btn-default bootstrap-popover-method"...>
    console.log($(".btn-submit").length); // I get twice of '1'.

    $(".link").click(function(){
        console.log($(this).attr("href")); // I get once of 'test.html'.
        return false;
    });

    $(".btn-submit").click(function(){

        console.log($(this).closest("form").attr("action")); // I get twice of '1.php'

        var form = $(this).closest("form");
        console.log(form.serialize()); // I get twice of 'username=hello+world!'

        $.ajax({ // it posts twice to 'POST https://localhost/test/2014/css/bootstrap/1.php'

            type: "POST",
            url: form.attr("action"),
            data: $(this).serialize(), // serializes the form's elements.
            success: function(data){
                //alert(data); // show response from the php script.
            }
          });

        return false;
    });


});

bootsrap + html,

<button type="button" class="btn btn-default bootstrap-popover-method" data-title="body" data-container="body" data-toggle="popover" data-placement="bottom">
  Popover on bottom
</button>

<div id="popover-content">
    <a href='test.html' class="link">hello</a> 
    <form action="1.php" class="myform">
       <input type="text" name="username" value="hello world!"/>
       <input type="submit" value="submit" class="btn-submit"/> 
    </form>
</div>


Solution 1:[1]

This happens because popover.content checks if the tooltip is empty or not.

A simple fix would be to add a title attribute to popover.

$('.bootstrap-popover-method').popover({
    placement: 'bottom',
    container: 'body',
    html:true,
    title: "New Title",
    content: function () {
        var p = $(this);
        var data = $('#popover-content').html();
        $('#popover-content').remove();
        p.attr("data-content", data);
        p.popover('show');
    }
});

https://github.com/twbs/bootstrap/issues/12563#issuecomment-56813015

Solution 2:[2]

I think you need to prevent the default event of the submit button

$(".btn-submit").click(function(e){
    e.preventDefault();
    console.log($(this).closest("form").attr("action")); // I get twice of '1.php'

    var form = $(this).closest("form");
    console.log(form.serialize()); // I get twice of 'username=hello+world!'

    $.ajax({ // it posts twice to 'POST https://localhost/test/2014/css/bootstrap/1.php'

        type: "POST",
        url: form.attr("action"),
        data: $(this).serialize(), // serializes the form's elements.
        success: function(data){
            //alert(data); // show response from the php script.
        }
    });

    return false;
});

Solution 3:[3]

This might be an old post, but i'm gonna leave here my work around.

I'm using bootstrap 3.3.5.

So the buggy behavior is that on every execution of "popover('show')", Bootstrap calls the rendering function twice, and only the second call is the one that actually renders the popup.

My fix is to return a short html string for the first call, and for the second call i let run the whole rendering function:

jQuery('.bootstrap-popover-method').popover({
    html: true,
    trigger: 'manual',
    content: function(){//This is our rendering function for the popup's content
        var __G_bs_popover_shown= jQuery.data(jQuery('body')[0], '__G_bs_popover_shown');

        //Create a global variable, attached to the body element, to keep track of the repeating calls.
        __G_bs_popover_shown= (typeof __G_bs_popover_shown == 'undefined') ? 1 : (__G_bs_popover_shown + 1) % 2;
        //Update the global var
        jQuery.data(jQuery('body')[0], '__G_bs_popover_shown', __G_bs_popover_shown);
        //return a short string on every first call (this will not be rendered, anyway)
        if(__G_bs_popover_shown == 1) return '<div>BLANK</div>';//==>this should not be an empty string!

        //PLACE YOUR CODE HERE, E.G. AJAX CALLS, ETC..
        //DON'T FORGET TO RETURN THE HTML FOR THE POPUP'S CONTENT!
    }
  });

Solution 4:[4]

$('.bootstrap-popover-method').off('shown.bs.popover')
                                      .on('shown.bs.popover', function (e) {
      e.preventDefault();
    }

// unbind your submit button click

$(".btn-submit").off('click').on('click',function(){

        console.log($(this).closest("form").attr("action")); // I get twice of '1.php'

        var form = $(this).closest("form");
        console.log(form.serialize()); // I get twice of 'username=hello+world!'

        $.ajax({ // it posts twice to 'POST https://localhost/test/2014/css/bootstrap/1.php'

            type: "POST",
            url: form.attr("action"),
            data: $(this).serialize(), // serializes the form's elements.
            success: function(data){
                //alert(data); // show response from the php script.
            }
          });

        return false;
    });

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Songtham T.
Solution 2 danio
Solution 3 enger
Solution 4