Elevate your tooltips with Bootstrap 5: enabling hoverable tooltips and clickable links

At times, you may want to include clickable links in tooltips. I recently encountered this issue while using Bootstrap 5 and had trouble finding a solution. After some trial and error, I finally figured it out and wanted to share my findings.

The standard way to initialize tooltips in Bootstrap 5 is as follows:

var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
        
new bootstrap.Tooltip(tooltipTriggerEl);

Is there a way to keep the tooltip visible when hovering over it without losing focus on the original element?

Answer №1

After tweaking @V1Pr's solution, I developed my own Vanilla JS method:

 const tooltipTriggerList = [].slice.call(
    document.querySelectorAll('[data-bs-toggle="tooltip"]')
  );
  const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
    const tooltip = new bootstrap.Tooltip(tooltipTriggerEl, {
      trigger: "manual",
    });

    let tooltipTimeout;
    let currentToolTip;

    tooltipTriggerEl.addEventListener("mouseenter", function () {
      let toolTipID;
      
      // Clear Set Timeout
      clearTimeout(tooltipTimeout);

      // Show Tooltip
      tooltip.show();

     // Assign current tooltip ID to toolTipID variable
      toolTipID = tooltipTriggerEl.getAttribute("aria-describedby");

      // Assign current tooltip to currentToolTip variable
      currentToolTip = document.querySelector(`#${toolTipID}`);

      // Hide tooltip on tooltip mouse leave
      currentToolTip.addEventListener("mouseleave", function () {
        tooltip.hide();
      });
    });

   
    tooltipTriggerEl.addEventListener("mouseleave", function () {
      // SetTimeout before tooltip disappears
      tooltipTimeout = setTimeout(function () {
        // Hide tooltip if not hovered.
        if (!currentToolTip.matches(":hover")) {
          tooltip.hide();
        }
      }, 100);
    });

    return tooltip;
  });

The HTML :

<span data-bs-toggle="tooltip" data-bs-html="true" title="Check out <a class='text-white opacity-75' href='#'>this link</a>">
 <i class="bi bi-info-square"></i>
</span>

Answer №2

To activate tooltip hovering, make the following adjustments:

var hoverTooltip = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltips = hoverTooltip.map(function (el) {
        
    new bootstrap.Tooltip(el,{ trigger: 'manual' });
      
    $(el).on("mouseenter", function () {
        var _this = this;
        $(this).tooltip("show");
        $(".bs-tooltip-start").on("mouseleave", function () {
            $(_this).tooltip('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".bs-tooltip-start:hover").length) {
               $(_this).tooltip("hide");
            }
        }, 300);
    });
});

Remember to insert data-bs-html=true in the element, if you wish to include HTML in the tooltip ;)

Answer №3

To display the tooltip correctly, ensure that it is placed within the same container as the element.

<div data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" title="Test string">
    <button>Test</button>
</div>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
    return new bootstrap.Tooltip(tooltipTriggerEl, {container: tooltipTriggerEl});
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Identify the index of a list item using a custom list created from buttons

When dealing with a dynamically built list like this: <ul id="shortcuts"> <li><input type="checkbox" value="false"/><button>foo</button><button>-</button></li> <li><input type="checkbox" value ...

Iterate through JSON data and access values based on keys using a $.each loop

I have retrieved JSON data from the controller using AJAX and now I want to access this data. The data is in the form of a list of objects (array) with key-value pairs, so I am planning to use .each() function to go through all the data. The array looks li ...

Efficiently transferring components of a JavaScript project between files

For the first time, I am creating an npm package using ES6 and Babel. However, I am facing difficulties in connecting everything together so that it can be imported correctly by the end user. The structure of my build (output) folder is identical to src: ...

The function error is currently in a waiting state as it already includes an

I encountered a particular issue that states: "await is only valid in async function." Here is the code snippet where the error occurs: async function solve(){ var requestUrl = "url"; $.ajax({url: "requestUrl", succes ...

Is there a way to use Ajax to analyze and contrast information from two separate web links?

I am looking to compare and display the genre_ids from the first link and the id from the second link. Example: genre_ids: [ 18, 878, ] { id: 18, name: "Drama", }, { id: 878, name: "Science Fiction", } Result: Drama, Science Fiction $(document).ready( ...

Jasmine - verifying variable invocation in test function

As part of my testing process, I am exploring a scenario where a service method is called using a local variable within an angular controller. In this particular case, when the items array is empty, a modal for creating a new item will be triggered via th ...

Error: Trying to access a property that is undefined (specifically referencing 'rendered') has resulted in an uncaught TypeError

As a newcomer to React, I'm attempting to create a headless WordPress application. However, when I fetch a post, I only receive the first value. After fetching the post, I save it in the state: componentDidMount() { this.setState({ lo ...

Disabling the last control in a formGroup when sorting an array with Angular

I am facing an issue with sorting an array based on a numeric control value inside a formGroup nested in another array: const toSort = [ ['key2', FormGroup: {controls: {order: 2}}], ['key1', FormGroup: {controls: {order: 1}}] ] ...

Processing incoming requests with a loading interface in CodeIgniter

Is there a way to notify the user who sent the request whether or not the requested user will approve it? Optional: If there is no notification sent to the user who made the request, the requested user will have to wait for verification. For Example: Ima ...

Accessing JSON files locally using JavaScript in IE and Firefox

I am a beginner in JavaScript and currently working on a small HTML page that will be run locally. I have a string in JSON format that I need to store and load as a file on the hard drive. I have managed to store the string using the following code snippe ...

Robotic Arm in Motion

GOAL: The aim of the code below is to create a robotic arm that consists of three layers (upper, lower, and middle), all connected to the base. There are four sliders provided to independently move each part except for the base which moves the entire arm. ...

Adjusting the properties of an element with Javascript

My goal is to dynamically set the value of a parameter within a <script> element using JavaScript. I am using the Stripe checkout.js and I want to populate the Email input field with a value obtained from another text box on the page. Here's how ...

Check if all items in the array exist in Mongodb, then update them; if not, insert

In my database, I have a collection of tags and I want to perform the following actions when a user enters an array of tags: If a tag in the array already exists, update its count If a tag in the array does not exist, insert it with a count of 0 Current ...

confirmation message upon completing a form submission

<script> var remainingCredit = document.getElementById("cor_credit"); var remaining = document.getElementById("remain_credit"); function validateForm() { if (remaining.value < remainingCredit.value) { return conf ...

Troubleshooting URL Problems with Node.js Search and Pagination

My results page has pagination set up and the routes are structured like this: app.get("/results",function(req,res){ query= select * from courses where // this part adds search parameters from req.query to the sql query// Object.keys(req.query.search).for ...

Update class name in React component based on state change

My current setup involves the setting of active and class flags as shown below: constructor(props) { super(props); this.state = {'active': false, 'class': 'album'}; } handleClick(id) { if(this.state.active){ this.s ...

Validating numbers in React JS input fields component

I need assistance with implementing number validation for 3 Textfields in my application. Currently, the code displays an error message if a Textfield is empty, but I am stuck on validating whether the input is text or numbers. import React from 'rea ...

Image not appearing when sharing on Facebook

I've been trying to create a Facebook share button using the Javascript SDK, and here is the code I have been utilizing: $(function() { $('.facebook-share').click(function(e) { e.preventDefault(); FB.ui({ method: 'feed& ...

Are you familiar with the Pagination and Card Components offered by Ant Design (antd)?

Can you merge the Pagination feature from antd with Card components to create a layout resembling Pinterest, complete with pagination? The standard Pagination code from https://ant.design/components/pagination/: import { Pagination } from 'antd&apo ...

Managing API calls through Next.js routing

Here is a next.js handler function for handling api requests on our server. I am looking for assistance on how to access a variable between request methods. Any help would be greatly appreciated. export default function handler(req, res) { if(req.met ...