How to implement multiple tooltip show event using popper.js

Viewed 673

How to implement multiple span with tooltip using popper.js

HTML:

<div class="panel-custom">

   <span class="button" aria-describedby="tooltip">Test1</span>
   <div class="tooltip" role="tooltip">
     Test1
     <div class="arrow" data-popper-arrow></div>
   </div>
   <br />
   <br />
   <br />

   <span class="button" aria-describedby="tooltip">Test2</span>
   <div class="tooltip" role="tooltip">
     Test2
     <div class="arrow" data-popper-arrow></div>
   </div>
   <br />
   <br />
   <br />
</div>

CSS:

   .tooltip {
     background: #333;
     color: white;
     font-weight: bold;
     padding: 4px 8px;
     font-size: 13px;
     border-radius: 4px;
     display: none;
   }

   .tooltip[data-show] {
     display: block;
   }

   .arrow,
   .arrow::before {
     position: absolute;
     width: 8px;
     height: 8px;
     background: inherit;
   }

   .arrow {
     visibility: hidden;
   }

   .arrow::before {
     visibility: visible;
     content: '';
     transform: rotate(45deg);
   }

   .tooltip[data-popper-placement^='top']>.arrow {
     bottom: -4px;
   }

   .tooltip[data-popper-placement^='bottom']>.arrow {
     top: -4px;
   }

   .tooltip[data-popper-placement^='left']>.arrow {
     right: -4px;
   }

   .tooltip[data-popper-placement^='right']>.arrow {
     left: -4px;
   }

JavaScript :

 const tooltipContainer = document.querySelectorAll('.panel-custom');
   var popperInstance;
   var button;
   var tooltip;
 tooltipContainer.forEach(tooltipContainer => {
   button = document.querySelector('.button');
  tooltip = document.querySelector('.tooltip');
   popperInstance=  Popper.createPopper(button, tooltip, {
     modifiers: [{
       name: 'offset',
       options: {
         offset: [0, 8],
       },
     }, ],
   });
 });
function show() {
        // Make the tooltip visible
        tooltip.setAttribute('data-show', '');

        // Enable the event listeners
        popperInstance.setOptions((options) => ({
            ...options,
            modifiers: [
                ...options.modifiers,
                { name: 'eventListeners', enabled: true },
            ],
        }));

        // Update its position
        popperInstance.update();
    }

    function hide() {
        // Hide the tooltip
        tooltip.removeAttribute('data-show');

        // Disable the event listeners
        popperInstance.setOptions((options) => ({
            ...options,
            modifiers: [
                ...options.modifiers,
                { name: 'eventListeners', enabled: false },
            ],
        }));
    }
    
     const showEvents = ['mouseenter', 'focus'];
    const hideEvents = ['mouseleave', 'blur'];

    showEvents.forEach((event) => {
        button.addEventListener(event, show);
    });

    hideEvents.forEach((event) => {
      button.addEventListener(event, hide);
    });

Only the first span hovered with the tooltip , I just want to have all the 2 span with their own tooltip. Is there anyway that I can manage all the span with their corresponding tooltip when hovered? The other one manage to create for each tooltip but there is no showevents or hideevents for multiple class for the tooltip : https://jsfiddle.net/42Layk7t/

2 Answers
<html><button class='button'>Button1</button>
<button class='button'>Button2</button>
<button class='button'>Button3</button></html>
<script>
    const tooltipList = ['Tooltip1', 'Tooltip2','Tooltip3']
    const popperInstances = []
    tooltipList.forEach((item,index) => {
                const createElement = document.createElement('div')
                createElement.innerText = item
                createElement.setAttribute('class', `popper-tooltip tooltip${index}`)
                document.body.appendChild(createElement)
            });
    const buttonElement = container.querySelectorAll('.button')
    optionElement.forEach((buttonElement,index) => {
       const toolTipElement = document.querySelector(`.tooltip${index}`)
       const popperInstance = Popper.createPopper(buttonElement, toolTipElement, {
                                modifiers: [{
                                  name: 'offset',
                                  options: {
                                    offset: [0, 8],
                                  },
                                }, ],
                            });
                            popperInstances.push(popperInstance)
                        });
    const showEvents = ['mouseenter', 'focus'];
                        const hideEvents = ['mouseleave', 'blur'];

                        showEvents.forEach((event) => {
                            optionElement.forEach((buttonElement,index) => {
                                buttonElement.addEventListener(event, () => {
                                    // Make the tooltip visible
                                    const tooltip = document.querySelector(`.tooltip${index}`)
                                    tooltip.setAttribute('data-show', '');
                                    const popperInstance = popperInstances[index]
                                    console.log(index, tooltip, popperInstance)
                                    // Enable the event listeners
                                    popperInstance.setOptions((options) => ({
                                        ...options,
                                        modifiers: [
                                            ...options.modifiers,
                                            { name: 'eventListeners', enabled: true },
                                        ],
                                    }));

                                    // Update its position
                                    popperInstance.update();
                                });
                            })
                        });
                    
                        hideEvents.forEach((event) => {
                            optionElement.forEach((buttonElement,index) => {
                                buttonElement.addEventListener(event, () => {
                                    // Hide the tooltip
                                    const tooltip = document.querySelector(`.tooltip${index}`)
                                    tooltip.removeAttribute('data-show');
                                    const popperInstance = popperInstances[index]
                                    // Disable the event listeners
                                    popperInstance.setOptions((options) => ({
                                        ...options,
                                        modifiers: [
                                            ...options.modifiers,
                                            { name: 'eventListeners', enabled: false },
                                        ],
                                    }));
                                });
                            })
                        });</script>

So it seems that when using a createPopper function it creates the element variable accessible via the same name of the class that you pass, in this case => .tooltip it means that you mounting on the same instance

so to have multiple tooltips you can create multiple elements with different classes and use it to setAttributes

tooltip = document.querySelector('.your-custom-class1');
tooltip = document.querySelector('.your-custom-class2');

And instead of targeting tooltip.setAttribute('data-show', ''); get the element with querySelector and then setAttributes

const tooltip = document.querySelector('your-custom-class1')
tooltip.setAttribute('data-show', '')

and for the arrows positioning css to work keep .tooltip class on each so you can still target the elements

Related