38

I hope someone can help.

I'm trying to hide the tooltip when another tooltip icon is clicked. It works but when I decide to click the last tooltip again it 'flashes' the tooltip.

var Hastooltip = $('.hastooltip');
HasTooltip.on('click', function(e) {
     e.preventDefault();
     HasTooltip.tooltip('hide');
}).tooltip({
     animation: true
}).parent().delegate('.close', 'click', function() {
     HasTooltip.tooltip('hide');
});

HTML

<a href="#" class="hastooltip" data-original-title="Lorem ipsum dolor sit amet, consectetur adipisicing elit.">
    <h3>Info 1</h3>
</a>

<a href="#" class="hastooltip" data-original-title="Lorem ipsum dolor sit amet, consectetur adipisicing elit.">
    <h3>Info 2</h3>
</a>

If it helps a following markup is added to the DOM when the user clicks on the button to display the tooltip.

<div class="tooltip"</div>
4
  • can't getting your question..tooltip or popover? becouse tooltip is disappear on mouse leave Commented Jun 24, 2013 at 11:19
  • Using tooltips. twitter.github.com/bootstrap/javascript.html#tooltips - I want it so if the tooltip is visable and another tooltip is clicked; the visable tooltip will hide. Commented Jun 24, 2013 at 11:29
  • Can you post your HTML too? Commented Jun 24, 2013 at 13:50
  • Sure, added that for you. Commented Jun 24, 2013 at 14:19

10 Answers 10

57

This can be handled more easily than the above answers indicate. You can do this with a single line of javascript in your show handler:

$('.tooltip').not(this).hide();

Here's a complete example. Change 'element' to match your selector.

$(element).on('show.bs.tooltip', function() {
    // Only one tooltip should ever be open at a time
    $('.tooltip').not(this).hide();
});

The same technique is suggested for closing popovers in this SO thread:

How can I close a Twitter Bootstrap popover with a click from anywhere (else) on the page?

Sign up to request clarification or add additional context in comments.

5 Comments

This is genius and ought to be the new accepted answer! Thanks!
Exactly what I've been looking for. $('.tooltip').tooltip('hide'); didn't work but $('.tooltip').not(this).hide(); did it !
This should be the answer.
Unfortunately this has some problems when using both hover and click as the trigger.
This works for me except that once a tooltip has been hidden, to show it again I have to click it twice
15

You need to check if the tooltip is showing and toggle its visibility manually. This is one way of doing it.

$(function() {
  var HasTooltip = $('.hastooltip');
  HasTooltip.on('click', function(e) {
    e.preventDefault();
    var isShowing = $(this).data('isShowing');
    HasTooltip.removeData('isShowing');
    if (isShowing !== 'true')
    {
      HasTooltip.not(this).tooltip('hide');
      $(this).data('isShowing', "true");
      $(this).tooltip('show');
    }
    else
    {
      $(this).tooltip('hide');
    }

  }).tooltip({
    animation: true,
    trigger: 'manual'
  });
});

3 Comments

You could have done it simply by removing the animation, but that would change the look.
Is it possible to toggle the tooltips? so if I clicked the same tooltip that is already set to true, it would be set to hidden.
What a mess! Seems like a classic example of swatting flies with a sledgehammer.
6

I slightly modified the code of kiprainey

const $tooltip = $('[data-toggle="tooltip"]');
 $tooltip.tooltip({
   html: true,
   trigger: 'click',
   placement: 'bottom',
 });
 $tooltip.on('show.bs.tooltip', () => {
   $('.tooltip').not(this).remove();
 });

I use remove() instead of hide()

2 Comments

remove() is better especially if you are attempting to get rid of the tooltip on a dynamically replaced element.
Great. It works fine. hide() actually hide but won't show again. But remove() doesn't have that problem. I have used both tooltip and confirmation together in an element and it is very useful with this remove()
3

I went into the same problem for regular tooltips. On an iPhone, they do not go away when clicking on the body (i.e. somewhere else).

My solution is that when you click on the tooltip itself, it hides. IMHO, this should be integrated in bootstrap distribution, because it is few code with a big effect.

When you have access to bootstrap sources, add

this.tip().click($.proxy(this.hide, this))

as the last line in method Tooltip.prototype.init in file tooltip.js:

Tooltip.prototype.init = function (type, element, options) {
this.enabled  = true
this.type     = type
this.$element = $(element)
this.options  = this.getOptions(options)

var triggers = this.options.trigger.split(' ')

for (var i = triggers.length; i--;) {
  var trigger = triggers[i]

  if (trigger == 'click') {
    this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
  } else if (trigger != 'manual') {
    var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focus'
    var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'

    this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
    this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
  }
}

this.options.selector ?
  (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
  this.fixTitle()

 // Hide tooltip when clicking on it. Useful for mobile devices like iPhone where eventOut
 // (see above) on $element is not triggered and you don't get rid of the tooltip anymore.
 this.tip().click($.proxy(this.hide, this))
  }

If you do not have the sources at hand, you can achieve the same effect with the following:

    $(function()
    {
        // Apply tooltips
        var hasTooltip = $("[data-toggle='tooltip']").tooltip();

        // Loop over all elements having a tooltip now.
        hasTooltip.each(function()
           {
               // Get the tooltip itself, i.e. the Javascript object
               var $tooltip = $(this).data('bs.tooltip');

               // Hide tooltip when clicking on it
               $tooltip.tip().click($.proxy($tooltip.hide, $tooltip))
           }
        );
    });

For me, that makes a good user experience on an iPhone: Click on the element to see the tooltip. Click on the tooltip that it goes away.

Comments

3

Re kiprainey’s answer, there is an issue in that once a tooltip has been hidden, it needs to be clicked twice to be shown again. I got around this by using tooltip('hide') instead of hide():

$(element).on('show.bs.tooltip', function() {
    // Only one tooltip should ever be open at a time
    $('.tooltip').not(this).tooltip('hide');
});

Comments

1

I was looking for a solution to this problem as well and it seems to me that $('.tooltip').not(this).hide(); will bypass any bootstrap show, shown, hide or hidden events you may have attached to the trigger element. After some thought, I've come up the following code allows for somewhat more transparent handling of attached events.

Note: tested on firefox and chrome only but should work fine in theory.

$(document).ready(function() {

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


  $(document).on('show.bs.popover', function(event) {
    // could use [data-toggle="popover"] instead
    // using a different selector allows to have different sets of single instance popovers.
    $('[data-popover-type="singleton"]').not(event.target).each(function(key, el) {
      $(el).popover('hide'); // this way everything gets propagated properly
    });
  });

  $(document).on('click', function(event) {
    // choose to close all popovers if clicking on anything but a popover element.
    if (!($(event.target).data('toggle') === "popover" /* the trigger buttons */ 
          || $(event.target).hasClass('popover') /* the popup menu */
          || $(event.target).parents('.popover[role="tooltip"]').length /* this one is a bit fiddly but also catches child elements of the popup menu. */ )) {
      
      $('[data-toggle="popover"]').popover('hide');
    }
  });


});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />



<button type="button" class="btn btn-danger" data-placement="bottom" data-toggle="popover" title="Popover One" data-content="Popover One Content. `focus` trigger still behaves as expected" data-trigger="focus" data-popover-type="singleton">Popover One</button>

<button type="button" class="btn btn-warning" data-placement="bottom" data-toggle="popover" title="Popover Two" data-content="Popover Two Content. for other triggers, clicking on content does not close popover" data-trigger="click" data-popover-type="singleton">Popover Two</button>

<button type="button" class="btn btn-success" data-placement="bottom" data-toggle="popover" title="Popover Three" data-content="Popover Three Content. clicking outside popover menu closes everything" data-trigger="click" data-popover-type="singleton">Popover Three</button>

fiddle example here: http://jsfiddle.net/ketwaroo/x6k1h7j4/

Comments

1
$('[data-toggle=tooltip],[rel=tooltip]').tooltip({ 
        container: 'body' }).click(function () {
        $('.tooltip').not(this).hide();
    });

1 Comment

Instead of posting links as answer add some text to explanation how this answer help to OP in fixing current issue.Thanks
0

Thanks Jochen for the "Iphone" click on tooltip to close solution, exactly what I was looking for.

As for the original request (prevent multiple tooltip fonctionnality is an obvious need when you are asked to implement click tooltip instead of rollover ones), here is my take:

Just after , show: function () { add:

  // HACK BEGIN
  // Quick fix. Only one tooltip should be visible at all time.
  // prototype level property are accessible to all instances so we use one to track last opened tooltip (ie. current this).
  if ( (Tooltip.prototype.currentlyShownTooltip != null) || (Tooltip.prototype.currentlyShownTooltip != undefined) ) {
    // Close previously opened tooltip.
    if (Tooltip.prototype.currentlyShownTooltip != this) { // Conflict with toggle func. Re-show.
        Tooltip.prototype.currentlyShownTooltip.hide();
        Tooltip.prototype.currentlyShownTooltip = null
    }
  }
  // Keep track of the currently opened tooltip.
  Tooltip.prototype.currentlyShownTooltip = this
  // HACK END

Comments

0

I will give you a good solution plus a bonus

        //save the tooltip in variable (change the selector to suit your tooltip)
        var $tooltips = $('a[data-toggle="tooltip"]');
        
        //initialise the tooltip with 'click' trigger  
        $tooltips.tooltip({
            animated: 'fade',
            placement: 'top',
            trigger: 'click',
            delay: { "show": 100, "hide": 100 }
        });
        
        //Here is the juicy bit: when a tooltip is opened it 
        //it creates an 'aria-describedby' with the id of the tooltip
        //opened we can leverage this to turn off all others but current

        $tooltips.on('click', function () {
            var toolTipId = $(this).attr('aria-describedby');
            $('.tooltip').not('#'+ toolTipId).tooltip('hide');
        });

        //But wait theres more! if you call now we chuck in a free close on X seconds event!
        $tooltips.on('shown.bs.tooltip', function (e) {
            //Auto hide after 7 seconds
            setTimeout(function () {
                $(e.target).tooltip('hide');
            }, 7000);
        });

        //call now! XD

Comments

0

I used class name to add tooltip and removed using class name. it's working.

Add Tooltip

$('.tooltips').tooltip({
      animation: true
      , container: 'body'
      , html: true
      , placement: 'auto'
      , trigger: 'focus hover'
  });

Hide Tooltip

$('.tooltips').tooltip('hide');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.