How to enable Bootstrap tooltip on disabled button?
Asked Answered
P

21

223

I need to display a tooltip on a disabled button and remove it on an enabled button. Currently, it works in reverse.

What is the best way to invert this behaviour?

$('[rel=tooltip]').tooltip();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<hr>
<button class="btn" disabled rel="tooltip" data-title="Dieser Link führt zu Google">button disabled</button>
<button class="btn" rel="tooltip" data-title="Dieser Link führt zu Google">button not disabled</button>

Here is a demo

P.S.: I want to keep the disabled attribute.

Predella answered 9/11, 2012 at 16:3 Comment(3)
the button that need to be disabled is disabled...Resuscitate
@EH_warch I want to keep the button disabled but at the same time display a tooltip on click event.Predella
This won't help the OP, but future visitors may appreciate knowing that the 'readonly' attribute is similar (though not identical) and does not block user events like mouseover.Palladino
H
18

Here is some working code: http://jsfiddle.net/mihaifm/W7XNU/200/

$('body').tooltip({
    selector: '[rel="tooltip"]'
});

$(".btn").click(function(e) {
    if (! $(this).hasClass("disabled"))
    {
        $(".disabled").removeClass("disabled").attr("rel", null);

        $(this).addClass("disabled").attr("rel", "tooltip");
    }
});

The idea is to add the tooltip to a parent element with the selector option, and then add/remove the rel attribute when enabling/disabling the button.

Hambley answered 9/11, 2012 at 21:17 Comment(3)
It's the accepted answer because it worked in 2012, when it was answered. Things have changed since then, mainly the external resources used in the fiddle. I added new URLs to bootstrap cdn, code is still the same.Hambley
Can I get an updated fix for this for Bootstrap version 4.1?Leath
fiddle ain't working in Firefox (at least)Diligent
C
316

You can wrap the disabled button and put the tooltip on the wrapper:

<div class="tooltip-wrapper" data-title="Dieser Link führt zu Google">
  <button class="btn btn-default" disabled>button disabled</button>
</div>

If the wrapper has display:inline then the tooltip doesn't seem to work. Using display:block and display:inline-block seem to work fine. It also appears to work fine with a floated wrapper.

UPDATE Here's an updated JSFiddle that works with the latest Bootstrap (3.3.6). Thanks to @JohnLehmann for suggesting pointer-events: none; for the disabled button.

http://jsfiddle.net/cSSUA/209/

Circumsolar answered 12/11, 2013 at 19:21 Comment(10)
This is what the docs suggest and it works if you use the inline-block trick suggested here!Piers
However, if your button is part of a button group then wrapping the button throws off your aesthetics :( Anyway to overcome this issue for btn-groups?Manage
Cody, for btn-groups, I found you can't wrap them, or they won't get rendered correctly. I set pointer-events to 'auto' (just targeted with: "div.btn-group > .btn.disabled { pointer-events: auto; }" just in case), and also hooked up the onclick event of the button so it just returns false. Felt hacky, but it worked for our app.Hamsun
This does not seem to work in bootstrap 3.3.5. JSFiddleMoneymaking
For bootstrap 3.3.5 also add .btn-default[disabled] { pointer-events:none; }Kulturkampf
You should update you answer with @JohnLehmann hint to keep it working with 3.3.5+ too.Needleful
The downside of this solution is the addition of the margin, without the margin it doesn't work:(Couch
Hello, I'm trying to use this to fix my issue but I don't know where this portion from the fiddle need to be set " $(function() { $('.tooltip-wrapper').tooltip({position: "bottom"}); });" Could you help me please?Notogaea
@Manage You can give the wrapper (fieldset or div) the class="btn-group" and the aestehtics is back in business. This is tested on bs5.Casiecasilda
Adding class="btn-group" didn't work for me in boostrap 5 for some reason, it still removes the spacing between the disabled button and the one after. However what worked for me is putting an empty <span></span> or <div></div> after the button, inside the wrapper. This seems to trick bootstrap into thinking the wrapper is a dropdown button or something similar.Meldameldoh
S
134

This can be done via CSS. The "pointer-events" property is what's preventing the tooltip from appearing. You can get disabled buttons to display tooltip by overriding the "pointer-events" property set by bootstrap.

.btn.disabled {
    pointer-events: auto;
}
Servetnick answered 4/4, 2014 at 15:54 Comment(15)
Took me forever to figure out that bootstrap uses this property to turn off tooltips on disabled .btn-elements.Rigidify
Just a side note, this only works for IE in 11 or higher. Pretty much all other modern browsers have supported it for a while. See: caniuse.com/#feat=pointer-eventsHogg
Since pointer-events are not supported in older browsers, disabled buttons will show the tooltip without having to make adjustments. :)Servetnick
This doesn't seem to work on [disabled] buttons. Also don't see Bootstrap (2.3.2) assigning pointer-events anywhere in source.Replevy
@Replevy you're right, this will only work for buttons disabled via the bs 'disabled' class. Balexand's answer (https://mcmap.net/q/118151/-how-to-enable-bootstrap-tooltip-on-disabled-button) will work best in that case. Thanks for pointing that out.Servetnick
In a bootstrap3 angular app, after applying this style, the disabled button is now clickableFunda
for [disabled] buttons use this: .btn[disabled]{ pointer-events: auto; } Seafaring
By far the best answer. Thanks!Buxtehude
I was excited when I found this, but unfortunately this does not work in the latest Firefox builds (40+), but works great in Chrome. I'll need to find another solution.Sarcophagus
@Sarcophagus I tried it on my FF (41.0.2) and it works just fine. Make sure that your selector is specific enough, since it could be getting overridden. #id .btn.disabled {...} or .parentclass .btn.disabled {...}. Good luck.Servetnick
I tried to use this on an anchor with btn class. It looked disabled and the tooltip worked, but I could click on the link (should not be possible).Studer
@OlleHärstedt I think the disabled attribute only affects <button>. This solution will only work for <button>, you may need to find another way to disable the click event on an <a>. Somebody correct me if I'm wrong. Thanks.Servetnick
For [disabled] buttons the approach .btn[disabled]{ pointer-events: auto; } doesn't work in IE11. It's easier to use .disabled css class.Karmen
On Bootstrap 4 it works but you have to make it "important": .btn.disabled { pointer-events: auto !important; }Nihi
I spent HOURS trying to figure out why tooltips on items that explained why links were disabled weren't working. I had disabled the links by setting pointer-events to none as was recommended on another SO article. xP Finally stumbled across this gem. To reconcile these two issues, I ended up doing a conditional [attr.href] in my angular statement to set the href to null when the link was disabled to prevent click events instead of disabling pointer events.Deport
C
28

If you're desperate (like i was) for tooltips on checkboxes, textboxes and the like, then here is my hackey workaround:

$('input:disabled, button:disabled').after(function (e) {
    d = $("<div>");
    i = $(this);
    d.css({
        height: i.outerHeight(),
        width: i.outerWidth(),
        position: "absolute",
    })
    d.css(i.offset());
    d.attr("title", i.attr("title"));
    d.tooltip();
    return d;
});

Working examples: http://jsfiddle.net/WB6bM/11/

For what its worth, I believe tooltips on disabled form elements is very important to the UX. If you're preventing somebody from doing something, you should tell them why.

Criminal answered 25/2, 2013 at 20:59 Comment(4)
This should be the correct answer. Doesn't seem hackey to me at all :)Impure
What a nightmare for something that should be baked in :(Piers
This works well, but if your input positions change based on the window size (like if your form elements wrap/move) you will need to add some handling on $(window).resize to move the tooltip div around, or they will appear in the wrong place. I recommend combining with CMS's answer from here: #2854907Spermatogonium
surprised at the amount of upvotes for this. Way too much code for something that can have a simple workaround.Pepperandsalt
D
21

Based on Bootstrap 4

Disabled elements Elements with the disabled attribute aren’t interactive, meaning users cannot focus, hover, or click them to trigger a tooltip (or popover). As a workaround, you’ll want to trigger the tooltip from a wrapper or , ideally made keyboard-focusable using tabindex="0", and override the pointer-events on the disabled element.

<span class="d-inline-block" tabindex="0" data-toggle="tooltip" title="Disabled tooltip">
  <button class="btn btn-primary" style="pointer-events: none;" type="button" disabled>Disabled button</button>
</span>

All the details here: Bootstrap 4 doc

Dollie answered 7/5, 2020 at 14:2 Comment(1)
Thanks for the post, can believe I overlooked this setup.Felker
H
18

Here is some working code: http://jsfiddle.net/mihaifm/W7XNU/200/

$('body').tooltip({
    selector: '[rel="tooltip"]'
});

$(".btn").click(function(e) {
    if (! $(this).hasClass("disabled"))
    {
        $(".disabled").removeClass("disabled").attr("rel", null);

        $(this).addClass("disabled").attr("rel", "tooltip");
    }
});

The idea is to add the tooltip to a parent element with the selector option, and then add/remove the rel attribute when enabling/disabling the button.

Hambley answered 9/11, 2012 at 21:17 Comment(3)
It's the accepted answer because it worked in 2012, when it was answered. Things have changed since then, mainly the external resources used in the fiddle. I added new URLs to bootstrap cdn, code is still the same.Hambley
Can I get an updated fix for this for Bootstrap version 4.1?Leath
fiddle ain't working in Firefox (at least)Diligent
G
9

These workarounds are ugly. I've debugged the problem is that bootstrap automatically set CSS property pointer-events: none on disabled elements.

This magic property causes that JS is not able to handle any event on elements that matches CSS selector.

If you overwrite this property to default one, everything works like a charm, including tooltips!

.disabled {
  pointer-events: all !important;
}

However you shouldn't use so general selector, because you will probably have to manually stop JavaScript event propagation way you know (e.preventDefault()).

Gasoline answered 1/6, 2015 at 8:57 Comment(0)
D
9

If it helps anyone, I was able to get a disabled button to show a tooltip by simply putting a span inside it and applying the tooltip stuff there, angularjs around it...

<button ng-click="$ctrl.onClickDoThis()"
        ng-disabled="!$ctrl.selectedStuff.length">
  <span tooltip-enable="!$ctrl.selectedStuff.length"
        tooltip-append-to-body="true"
        uib-tooltip="Select at least one thing to enable button.">
    My Butt
  </span>
</button>
Durant answered 6/3, 2020 at 20:53 Comment(1)
You're brilliant. Such a simple solution.Trainbearer
H
8

Try this example:

Tooltips must be initialized with jQuery: select the specified element and call the tooltip() method in JavaScript:

$(document).ready(function () {
    $('[data-toggle="tooltip"]').tooltip();
});

Add CSS:

.tool-tip {
  display: inline-block;
}

.tool-tip [disabled] {
  pointer-events: none;
}

And your html:

<span class="tool-tip" data-toggle="tooltip" data-placement="bottom" title="I am Tooltip">
    <button disabled="disabled">I am disabled</button>
</span>
Heroworship answered 24/3, 2017 at 9:30 Comment(0)
L
7

In my case, none of the above solutions worked. I found that it's easier to overlap the disabled button using an absolute element as:

<div rel="tooltip" title="I workz" class="wrap">
  <div class="overlap"></div>
  <button>I workz</button>
</div>

<div rel="tooltip" title="Boo!!" class="wrap poptooltip">
  <div class="overlap"></div>
  <button disabled>I workz disabled</button>
</div>

.wrap {
  display: inline-block;
  position: relative;
}

.overlap {
  display: none
}

.poptooltip .overlap {
  display: block;
  position: absolute;
  height: 100%;
  width: 100%;
  z-index: 1000;
}

Demo

Leisha answered 15/1, 2017 at 12:31 Comment(0)
A
4

You can't get the tool-tip to show on a disabled button. This is because disabled elements don't trigger any events, including the tool-tip. Your best bet would be to fake the button being disabled (so it looks and acts like its disabled), so you can then trigger the tool-tip.

Eg. Javascript:

$('[rel=tooltip].disabled').tooltip();

$('[rel=tooltip].disabled').bind('click', function(){
     return false;
});

Instead of just $('[rel=tooltip]').tooltip();​

HTML:

<hr>
<button class="btn disabled" rel="tooltip" data-title="Dieser Link führt zu Google">button disabled</button>

<button class="btn" rel="tooltip" data-title="Dieser Link führt zu Google">button not disabled</button>

JSFiddle: http://jsfiddle.net/BA4zM/75/

Argillite answered 9/11, 2012 at 16:17 Comment(2)
I am looking a solution with button disabled.Predella
@Argillite Utter rubbish! Of course you can get a tool tip on a disabled button!Impure
H
4

You can simply override Bootstrap's "pointer-events" style for disabled buttons via CSS e.g.

.btn[disabled] {
 pointer-events: all !important;
}

Better still be explicit and disable specific buttons e.g.

#buttonId[disabled] {
 pointer-events: all !important;
}
Hoehne answered 11/1, 2016 at 17:32 Comment(3)
Worked! Thank you!Incorporeal
Glad I could help @VedranMandić :)Hoehne
if we set pointer-events to all, the button can be click, it is wrong behaviorSkyway
T
2

This is what myself and tekromancr came up with.

Example element:

<a href="http://www.google.com" id="btn" type="button" class="btn btn-disabled" data-placement="top" data-toggle="tooltip" data-title="I'm a tooltip">Press Me</a>

note: the tooltip attributes can be added to a separate div, in which the id of that div is to be used when calling .tooltip('destroy'); or .tooltip();

this enables the tooltip, put it in any javascript that is included in the html file. this line might not be necessary to add, however. (if the tooltip shows w/o this line then don't bother including it)

$("#element_id").tooltip();

destroys tooltip, see below for usage.

$("#element_id").tooltip('destroy');

prevents the button from being clickable. because the disabled attribute is not being used, this is necessary, otherwise the button would still be clickable even though it "looks" as if it is disabled.

$("#element_id").click(
  function(evt){
    if ($(this).hasClass("btn-disabled")) {
      evt.preventDefault();
      return false;
    }
  });

Using bootstrap, the classes btn and btn-disabled are available to you. Override these in your own .css file. you can add any colors or whatever you want the button to look like when disabled. Make sure you keep the cursor: default; you can also change what .btn.btn-success looks like.

.btn.btn-disabled{
    cursor: default;
}

add the code below to whatever javascript is controlling the button becoming enabled.

$("#element_id").removeClass('btn-disabled');
$("#element_id").addClass('btn-success');
$('#element_id).tooltip('destroy');

tooltip should now only show when the button is disabled.

if you are using angularjs i also have a solution for that, if desired.

Tristichous answered 28/7, 2014 at 17:19 Comment(1)
I came across some problem when using destroy on tooltip. (See this) However, $("#element_id").tooltip('disable') and $("#element_id").tooltip('enable') work for me.Manamanacle
S
1

Working code for Bootstrap 3.3.6

Javascript:

$('body').tooltip({
  selector: '[data-toggle="tooltip"]'
});

$(".btn").click(function(e) {
 if ($(this).hasClass("disabled")){
   e.preventDefault();
 }
});

CSS:

a.btn.disabled, fieldset[disabled] a.btn {
  pointer-events: auto;
}
Stomatology answered 28/4, 2016 at 9:43 Comment(0)
C
1

You can imitate the effect using CSS3.

Simply take the disabled state off the button and the tooltip doesn't appear anymore.. this is great for validation as the code requires less logic.

I wrote this pen to illustrate.

CSS3 Disabled Tooltips

[disabled] {
  &[disabled-tooltip] {
    cursor:not-allowed;
    position: relative;
    &:hover {
      &:before {
        content:'';
        border:5px solid transparent;
        border-top:5px solid black;
        position: absolute;
        left: 50%;
        transform: translate(-50%, calc(-100% + -5px));
      }
      &:after {
        content: attr(disabled-tooltip);
        position: absolute;
        left: 50%;
        transform: translate(-50%, calc(-100% + -15px));
        width:280px;
        background-color:black;
        color:white;
        border-radius:5px;
        padding:8px 12px;
        white-space:normal;
        line-height:1;
      }
    }
  }
}

<button type="button" class="btn btn-primary" disabled-tooltip="I am a disabled tooltip using CSS3.. You can not click this button." disabled>Primary Button</button>
Copier answered 12/2, 2018 at 0:32 Comment(0)
E
1

I finally solved this problem, at least with Safari, by putting "pointer-events: auto" before "disabled". The reverse order didn't work.

Einberger answered 19/10, 2019 at 23:39 Comment(0)
D
1

Bootstrap 5

For me I needed to do the opposite of what @nathan-beach suggested. I put the span OUTSIDE the button:

<span data-bs-toggle="tooltip" data-bs-title="You can only refresh if 24 hours has passed or there are new reviews">
  <button type="button" class="btn btn-primary" disabled>
    <i class="fa-duotone fa-arrows-rotate"></i> Rebuild
  </button>
</span>

(and the the regular stuff to enable tooltips).

Devito answered 4/7, 2023 at 13:10 Comment(0)
C
0

pointer-events: auto; does not work on an <input type="text" />.

I took a different approach. I do not disable the input field, but make it act as disabled via css and javascript.

Because the input field is not disabled, the tooltip is displayed properly. It was in my case way simpler than adding a wrapper in case the input field was disabled.

$(document).ready(function () {
  $('.disabled[data-toggle="tooltip"]').tooltip();
  $('.disabled').mousedown(function(event){
    event.stopImmediatePropagation();
    return false;
  });
});
input[type=text].disabled{
  cursor: default;
  margin-top: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.3/js/tether.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"> 
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>


<input type="text" name="my_field" value="100" class="disabled" list="values_z1" data-toggle="tooltip" data-placement="top" title="this is 10*10">
Category answered 20/7, 2016 at 12:10 Comment(0)
A
0

For Bootstrap 3

HTML

<button 
    class="btn btn-success" 
    disabled
    data-hint="Enabled">
  <div class="sp-btn-overlap" data-hint="Disabled"></div>
  Submit button
</button>

CSS

button { position:relative; }

.sp-btn-overlap { 
    position:absolute; 
    top:0; 
    left:0; 
    height:100%; 
    width:100%; 
    background:none; 
    border:none; 
    z-index:1900;
}

JS

$('button .sp-btn-overlap')
    .popover({
        trigger: 'hover',
        container: 'body',
        placement: 'bottom',
        content: function() {
            return $(this).parent().prop('disabled')
                    ? $(this).data('hint')
                    : $(this).parent().data('hint');
            }
        });

$('button .sp-btn-overlap')
  .popover({
    trigger: 'hover',
    container: 'body',
    placement: 'bottom',
    content: function() {
      return $(this).parent().prop('disabled')
                  ? $(this).data('hint')
                  : $(this).parent().data('hint'); }
  });
button {
  position:relative; /* important! */
}

.sp-btn-overlap {
  position:absolute;
  top:0;
  left:0;
  height:100%;
  width:100%;
  background:none;
  border:none;
  z-index:1900;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<button disabled class="btn btn-default" data-hint="Enabled">
  <div class="sp-btn-overlap" data-hint="Disabled"></div>
  Disabled button
</button>

<button class="btn btn-default" data-hint="Enabled">
  <div class="sp-btn-overlap" data-hint="Disabled"></div>
  Enabled button
</button>
Aegyptus answered 16/5, 2018 at 12:49 Comment(0)
P
0

Simply add the disabled class to the button instead of the disabled attribute to make it visibly disabled instead.

<button class="btn disabled" rel="tooltip" data-title="Dieser Link führt zu Google">button disabled</button>

Note: this button only appears to be disabled, but it still triggers events, and you just have to be mindful of that.

Puiia answered 23/9, 2019 at 3:37 Comment(1)
This is not a great answer for the simple reason that your solution, essentially, is to turn a "disabled button" into a "button that appears disabled". These are not the same thing.Dorweiler
F
0

I had the same issue on Dynamic controls so I just simply do it by, Set style attributes and enable the read-only property = true when we need the element as disabled but show the tooltip if user click on the input button controls.

Yes disabled stopped all event functions like ObBlur, onClick /OnFocus. in place of below line :

((document.getElmentByName('MYINPUTBTN').item(0))).disabled= true;

we can do thru below code after that tooltip will be enabled in disabled input button elements.

((document.getElmentByName('MYINPUTBTN').item(0))).setAttribute("style", "background-color": #e9ecef;");

b

Hope this will resolve the issue.

Filicide answered 28/4, 2021 at 20:8 Comment(0)
E
-1

Just override the css that disables hover events on your element

add css:

pointer-events: all !important;
cursor: not-allowed !important;

This will disable clicks on the button, but will still allow hover events enabling for tooltips to work

Elevation answered 25/4, 2022 at 16:31 Comment(2)
This is not a solution because it also re-enables the click event. The button will graphically "look" disabled, but it no longer behaves disabled.Wynellwynn
Indeed, I've altered the answer so that it uses cursor: not-allowed instead.Elevation

© 2022 - 2024 — McMap. All rights reserved.