How to insert close button in popover for Bootstrap

151,905

Solution 1

You need to make the markup right

<button type="button" id="example" class="btn btn-primary">example</button>

Then, one way is to attach the close-handler inside the element itself, the following works :

$(document).ready(function() {
    $("#example").popover({
        placement: 'bottom',
        html: 'true',
        title : '<span class="text-info"><strong>title</strong></span>'+
                '<button type="button" id="close" class="close" onclick="$(&quot;#example&quot;).popover(&quot;hide&quot;);">&times;</button>',
        content : 'test'
    });
});  

Solution 2

I needed to find something that would work for multiple popovers and in Bootstrap 3.

Here's what I did:

I had multiple elements I wanted to have a popover work for, so I didn't want to use ids.

The markup could be:

<button class="btn btn-link foo" type="button">Show Popover 1</button>
<button class="btn btn-link foo" type="button">Show Popover 2</button>
<button class="btn btn-link foo" type="button">Show Popover 3</button>

The content for the save and close buttons inside the popover:

var contentHtml = [
    '<div>',
        '<button class="btn btn-link cancel">Cancel</button>',
        '<button class="btn btn-primary save">Save</button>',
    '</div>'].join('\n');

and the javascript for all 3 buttons:

This method works when the container is the default not attached to body.

$('.foo').popover({
    title: 'Bar',
    html: true,
    content: contentHtml,
    trigger: 'manual'
}).on('shown.bs.popover', function () {
    var $popup = $(this);
    $(this).next('.popover').find('button.cancel').click(function (e) {
        $popup.popover('hide');
    });
    $(this).next('.popover').find('button.save').click(function (e) {
        $popup.popover('hide');
    });
});

When the container is attached to 'body'

Then, use the aria-describedby to find the popup and hide it.

$('.foo').popover({
    title: 'Bar',
    html: true,
    content: contentHtml,
    container: 'body',
    trigger: 'manual'
}).on('shown.bs.popover', function (eventShown) {
    var $popup = $('#' + $(eventShown.target).attr('aria-describedby'));
    $popup.find('button.cancel').click(function (e) {
        $popup.popover('hide');
    });
    $popup.find('button.save').click(function (e) {
        $popup.popover('hide');
    });
});

Solution 3

I found other answers were either not generic enough, or too complicated. Here is a simple one that should always work (for bootstrap 3):

$('[data-toggle="popover"]').each(function () {
    var button = $(this);
    button.popover().on('shown.bs.popover', function() {
        button.data('bs.popover').tip().find('[data-dismiss="popover"]').on('click', function () {
            button.popover('toggle');
        });
    });
});

Then just add attribute data-dismiss="popover" in your close button. Also make sure not to use popover('hide') elsewhere in your code as it hides the popup but doesn't properly sets its internal state in bootstrap code, which will cause issues next time you use popover('toggle').

Solution 4

Previous examples have two main drawbacks:

  1. The 'close' button needs in some way, to be aware of the ID of the referenced-element.
  2. The need of adding on the 'shown.bs.popover' event, a 'click' listener to the close button; which is also not a good solution because of, you would then be adding such listener each time the 'popover' is shown.

Below is a solution which has not such drawbacks.

By the default, the 'popover' element is inserted immediately after the referenced-element in the DOM (then notice the referenced-element and the popover are immediate sibling elements). Thus, when the 'close' button is clicked, you can simply look for its closest 'div.popover' parent, and then look for the immediately preceding sibling element of such parent.

Just add the following code in the 'onclick' handler of the 'close button:

$(this).closest('div.popover').popover('hide');

Example:

var genericCloseBtnHtml = '<button onclick="$(this).closest(\'div.popover\').popover(\'hide\');" type="button" class="close" aria-hidden="true">&times;</button>';

$loginForm.popover({
    placement: 'auto left',
    trigger: 'manual',
    html: true,
    title: 'Alert' + genericCloseBtnHtml,
    content: 'invalid email and/or password'
});

Solution 5

enter image description here

The following is what i just used in my project .And hope it can help you

<a id="manualinputlabel" href="#" data-toggle="popover" title="weclome to use the sql quer" data-html=true  data-original-title="weclome to use the sql query" data-content="content">example</a>


$('#manualinputlabel').click(function(e) {
              $('.popover-title').append('<button id="popovercloseid" type="button" class="close">&times;</button>');
              $(this).popover();

          });

      $(document).click(function(e) {
         if(e.target.id=="popovercloseid" )
         {
              $('#manualinputlabel').popover('hide');                
         }

      });
Share:
151,905

Related videos on Youtube

Danglebz Highbreed
Author by

Danglebz Highbreed

Updated on July 05, 2022

Comments

  • Danglebz Highbreed
    Danglebz Highbreed almost 2 years

    JS:

    $(function(){
      $("#example").popover({
        placement: 'bottom',
        html: 'true',
        title : '<span class="text-info"><strong>title</strong></span> <button type="button" id="close" class="close">&times;</button>',
        content : 'test'
      })
      $('html').click(function() {
        $('#close').popover('hide');
      });
    });
    

    HTML:

    <button type="button" id="example" class="btn btn-primary" ></button>
    

    i'm write your code isn't show your popup.

    anyone come across this problem?

  • davidkonrad
    davidkonrad over 11 years
    Sry, but that will never work. #close only exists when the popover is active, click is never bound. Try alert($("#close").length); (it alerts 0)
  • smonff
    smonff over 11 years
    It works! Wonder why this is not core-integrated into Bootstrap ?
  • davidkonrad
    davidkonrad over 11 years
    @Sebf, bootstrap is intended to be as light as possible, many issues is meant to be solved on the implementation layer. Yeah, some "missing" parts is baffling ;-)
  • jonschlinkert
    jonschlinkert over 11 years
    It should be noted that this solution doesn't use the native data-dismiss feature that is already included in bootstrap's code. It creates new code to solve a problem that is already solved. I use the native code in my answer below.
  • Hengjie
    Hengjie over 11 years
    @jonschlinkert data-dismiss="popover" inplace of the onclick doesn't work. This is a well documented problem.
  • wheresmycookie
    wheresmycookie about 11 years
    Works, but not great style. For those in a production workflow, I would recommend using underscore.js template function. Keep your html out of your javascript
  • Mario Fink
    Mario Fink almost 11 years
    Using inline HTML and JavaScript events in the popover title is a pretty bad practice. It might work, but it will give you headaches later on.
  • davidkonrad
    davidkonrad almost 11 years
    @Mario Fink (and Robert Kotcher) - totally agree off course. But this was how you could implement the desired functionality in twitter bootstrap 2.x, now the intended way fails. I simply answer the question.
  • Swashata Ghosh
    Swashata Ghosh over 10 years
    I just noticed that doing $(elm).popover('hide') sometimes (I am not sure if all the time) leaves the popup where it is and just adds a .fade class which makes opacity 0. This would cause users not being able to select text etc. A finer solution is to use $(elm).popover('toggle').
  • davidkonrad
    davidkonrad over 10 years
    Hey @SwashataGhosh, what version of bootstrap? This is an "old" answer, targeting bootstrap 2.x - havent tested it on boostrap 3.0
  • Swashata Ghosh
    Swashata Ghosh over 10 years
    @davidkonrad Yes, I tested it on bootstrap 3.0. You can see the implementation on this theme I made github.com/swashata/ipt-knowledgebase-theme-wp
  • Renato Gama
    Renato Gama over 10 years
    Hey, thanks for your anwser! Would you know how to vertically center the &times; symbol within the h3.popover-title object?
  • Ruut
    Ruut almost 10 years
    For me the example above only worked by replacing the double quotes (&quot;) with single quotes (&#39;)
  • Richard Marskell - Drackir
    Richard Marskell - Drackir over 9 years
    This is a really interesting solution. Because I have 350 of these on the same page, I used onclick="$(this).parents(&quot;div.popover&quot;).siblings(&‌​quot;a.popover-link&‌​quot;).popover(&quot‌​;hide&quot;);" (where .popover-link represents the class used to toggle the popover) to generically close the specific popover. This may not work if you change the container.
  • Bernhard Döbler
    Bernhard Döbler over 9 years
    I guess it must be $cur_pop.popover('hide');
  • bart
    bart almost 9 years
    Small improvement: popup.find('button.cancel').on('click',function(e) {...}
  • hvaughan3
    hvaughan3 over 8 years
    For some reason, using Bootstrap 3, .popover('toggle'); never does anything for me, where as .popover('hide'); does work. Other than that, this solution is my favorite. Thank you!
  • pdu
    pdu over 8 years
    Wouldn't that bind the click event on every popover-show-event, resulting in multiple bindings?
  • youen
    youen over 8 years
    @pduersteler this is old code, but it's used in production, so I'm pretty sure it works. I guess bootstrap creates a new popover, and therefore a new close button, each time the button is clicked. If there was multiple events on the close button, it would toggle multiple times, and I would have noticed the bug (hopefully). Let me know if you can confirm an issue though. On second thought, maybe that's why I had an issue with popover('hide') that would not destroy the popover but just hide it?
  • Nizam Kazi
    Nizam Kazi almost 8 years
    when I click on cancel link, it closes the popover. But I have to click twice on popover-trigger link as it does not open popover in first click.
  • Ashot
    Ashot almost 8 years
    Worked for me best, just need to update BS names: 'shown' -> 'shown.bs.popover' data('popover') -> data('bs.popover')
  • lubosdz
    lubosdz over 7 years
    There's predefined class .close with hover effect, so inserting close button into title or content is as easy as <span class=close>&times;</span>.
  • dading84
    dading84 over 7 years
    Worked well, but I had the same issue with vertical alignment. I added my own class to the close button with line-height: 0.7 !important; and looked good
  • Ed J
    Ed J over 7 years
    Does this solution require 2 clicks to re-open the popover for you? Then add the following fix: $('body').on('hidden.bs.popover', function (e) { $(e.target).data("bs.popover").inState.click = false; }); github.com/twbs/bootstrap/issues/16732#issuecomment-16522903‌​7
  • davidkonrad
    davidkonrad over 7 years
    Hey @EdJ, that is an very important detail! I am pretty sure inState.click is added to BS3 after 2012.
  • Adrian Enriquez
    Adrian Enriquez over 6 years
    Wow, nice and simple solution. Works for me.
  • Shurvir Mori
    Shurvir Mori almost 6 years
    when I click on cancel link, it closes the popover. But I have to click twice on popover-trigger link as it does not open popover in first click
  • Mike Campbell
    Mike Campbell about 5 years
    this should be $(button.data('bs.popover').tip).find('[data-dismiss="popove‌​r"]') in modern bootstrap (>= 4?)
  • Nico
    Nico about 5 years
    With Bootstrap 4.3 I had to add sanitize: false to the popover options
  • Chandresh Mishra
    Chandresh Mishra almost 5 years
    why the cross button is not getting navigated with tab ?
  • TetraDev
    TetraDev over 4 years
    This will requiring clicking the trigger element twice to popup again. Use my solution below to solve that: stackoverflow.com/a/58923567/5376813
  • TetraDev
    TetraDev over 4 years
    @NizamKazi Use my solution below to solve that: stackoverflow.com/a/58923567/5376813