Angular Material - 如何为禁用的按钮添加工具提示

110

我注意到指令matTooltip在禁用的按钮上不起作用。我该如何解决?

示例:

<button mat-raised-button [disabled]="true" matTooltip="You cannot delete that">
  <mat-icon>delete</mat-icon>
</button>

对于启用的按钮,它能够完美地工作:

<button mat-raised-button [disabled]="false" matTooltip="You cannot delete that">
  <mat-icon>delete</mat-icon>
</button>

请注意,您的文本违反了Material Design指南。工具提示应仅描述按钮。不能删除某些内容的信息应在其他地方显示。来源:https://material.io/guidelines/components/tooltips.html# - kvetis
谢谢你的建议。我在想如何让它更好。如果我这样命名它:“因为您没有权限删除,所以此按钮已被禁用”,这样是否可以接受? - Marcin Kunert
2
在我看来,按钮的上下文已经清楚明确地表明了。当一个按钮被禁用并带有垃圾桶图标时,这已经解释了用户无法删除它而不使用文字。如果你想解释为什么,我认为你应该采用不同的方法而不是工具提示。我不是专家,也许你最好去ux.stackexchange.com上询问。我在那里进行了快速搜索:https://ux.stackexchange.com/search?q=tooltip+on+disabled+button 这可能会对我们两个都有兴趣。 - kvetis
4
我发现预先验证非常有用。最好使用一个被禁用的按钮,并显示“您必须先选择事件”的提示,而不是一个需要点击才会显示错误或者没有提供任何信息的已禁用按钮。 - Stephen Turner
12个回答

189

这个不起作用是因为它被mouseenter事件触发,而大多数浏览器不会为被禁用的元素触发该事件。解决方法是将matTooltip添加到父元素中:

<div matTooltip="You cannot delete that" [matTooltipDisabled]="!isButtonDisabled()">
    <button mat-raised-button [disabled]="isButtonDisabled()">
        <mat-icon>delete</mat-icon>
    </button>
</div>

以上示例假设有一种方法可以确定按钮是否应启用。通过使用matTooltipDisabled,只有在按钮被禁用时才会显示工具提示。

参考:


1
我可能遗漏了什么,但这不是显示按钮是否已禁用吗?它似乎显示得很好,但我只希望它在按钮被禁用时显示。 - goneos
对于任何想要解决仅在按钮禁用时显示的问题的人,请参考https://dev59.com/_V4b5IYBdhLWcg3wZwu3 - goneos
1
@goneos 我已经更新了答案以回答你的问题。 - Marcin Kunert
1
感谢@MarcvinKunert。我用了一种略有不同的方式matTooltip="isButtonDisabled() ? '您无法删除此项' : ''" - goneos
2
我实际上收到了一条消息,说div不接受matTooltipDisabled属性。我可以确认你没有收到这个消息吗? - Sean Duggan
显示剩余4条评论

32

当我尝试在一个禁用的图标按钮上显示工具提示时,也遇到了类似的问题。给出的解决方案对我来说并不实用,因为在按钮上添加额外的div会破坏工具栏中按钮相对于其他按钮的布局。

对我而言,一个更简单的解决方案是将工具提示添加到按钮内部的图标中。就像这样:

<button mat-raised-button [disabled]="true">
    <mat-icon matTooltip="You cannot delete that">delete</mat-icon>
</button>

由于图标未被禁用,它可以正常使用。


13
工具提示只会在悬停于图标上时显示,而不是整个按钮。 - Saksham
1
另外,如果没有图标呢? - Jonathan
使用 span 而不是 div。 - andreisrob
这在Angular Material 15上不起作用。 - HDJEMAI

21

是的,最简单的解决方法就像上面所示。但对于我的情况,我需要更多的灵活性。

   <button  [disabled]="form.invalid">
      <span [matTooltip]="form.invalid ? 'some text' : ''">button text</span>
    </button>

对我来说没问题 :):) - laike9m
清洁的解决方案运行良好。 - Khalil

10

根据他人的建议,在按钮中添加 mat-icon 的提示工具只有在悬停在图标上时才起作用,而不是整个按钮。相反,您可以将按钮包装在另一个无任何 CSS 类的 div 中,只需要加上 tooltip 即可。

此外,您还可以添加 matTooltipDisabled 属性,以确保您的提示工具永远不会被禁用。

<div matTooltip="You cannot delete that" [matTooltipDisabled]="false">
  <button mat-raised-button [disabled]="true">
     <mat-icon>delete</mat-icon>
  </button>
</div>

2

试试这个:

<div [matTooltip]="isDisabled ? 'You cannot delete that' : ''">
    <button mat-raised-button [disabled]="isDisabled">
      <mat-icon>delete</mat-icon>
    </button>
    <div>

3
欢迎来到Stack Overflow!虽然这段代码可能解决了问题,但包含一份说明关于它是如何解决问题的将有助于提高你的帖子质量,并可能导致更多的赞。请记住,你是在回答未来读者的问题,而不仅仅是现在提出问题的人。请编辑你的答案,添加说明并指出适用的限制和假设。 - user12867493

1

只需像这样将样式“pointer-events:all”添加到您的按钮即可:

<button mat-raised-button style="pointer-events: all" [disabled]="true" matTooltip="You cannot delete that">
  <mat-icon>delete</mat-icon>
</button>

2
这对我非常有帮助。比添加额外的div包装器或switch语句要容易得多。感谢您! - Michael Norgren
遗憾的是,“pointer-events: all”似乎只针对SVG元素。如果它能在普通DOM元素上正常工作,那就太好了。 - Greg Grundy

1
你可以使用标题属性,在必要的情况下会显示。
<button mat-raised-button [disabled]="true" title = "Some text">
  <mat-icon>delete</mat-icon>
</button>

你可以使用三元运算符进行属性绑定。

在悬停时立即显示标题,而不需要延迟,这是否可能? - MatterOfFact

1

我知道这很丑,但你也可以这样做,使用多个带有ngIf的按钮。

<!-- No click action -->
<button *ngIf="disable" mat-raised-button matTooltip="You cannot delete that">
  <mat-icon>delete</mat-icon>
</button>

<button *ngIf="!disable" mat-raised-button (click)="delete()">
  <mat-icon>delete</mat-icon>
</button>

1
我找到了一个解决方案!
将工具提示放入按钮内容中,就像这样:
<button type="submit" [disabled]="disableEdit()" class="btn btn-primary btn-sm"
        [routerLink]="['/entity', entity.id, 'edit']">
    <div matTooltip="{{ 'entity.placeholders.cantEdit' | translate }}"
         [matTooltipDisabled]="disableEdit()">
        <fa-icon [icon]="'pencil-alt'"></fa-icon>
        <span class="d-none d-md-inline">{{ 'entity.action.edit' | translate }}</span>
    </div>
</button>

0

Angular和Angular Material 15

您可以将matTooltip添加到子元素中,最合理的情况是在材料按钮中,即包含按钮文本的span或具有材料图标的mat-icon

当使用Material按钮时,禁用按钮默认具有应用样式pointer-events: none;请参阅全局材料按钮样式:

图标按钮:

.mdc-icon-button:disabled,
.mat-mdc-icon-button[disabled] {
  pointer-events: none;
}

普通按钮:

.mdc-button[disabled],
.mat-mdc-button[disabled] {
  pointer-events: none;
}

如果您希望在悬停按钮时显示工具提示,则需要取消子元素的此设置。可以通过以下方式轻松解决:

<button #myIconButton mat-icon-button [disabled]="!isAllowedDelete">
  <mat-icon [style.pointer-events]="'all'"
            matTooltip="You are not allowed to delete this item"
            [matTooltipDisabled]="!myIconButton.disabled">delete</mat-icon>
</button>

<button #myButton mat-button [disabled]="!isAllowedDelete">
  <span [style.pointer-events]="'all'"
        matTooltip="You are not allowed to delete this item"
        [matTooltipDisabled]="!myButton.disabled">delete</span>
</button>

或者,如果您想将其放在样式表中:

button[disabled] span.mat-mdc-tooltip-trigger
button[disabled] mat-icon.mat-mdc-tooltip-trigger {
  /* Allows for tooltips to be triggered on disabled buttons */
  pointer-events: all;
}

在我看来,这比将按钮包装在元素中要好,现在您可以直接使用按钮的“禁用”状态(myButton.disabled)禁用/启用工具提示,而无需向DOM添加任何其他包装器或元素。

在此 Stackblitz 中查看一个可工作的示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接