Javascript : Destroy tippy.js instance
Asked Answered
C

2

8

I have the following code which shows a tooltip containing dynamic data. Its working fine, But it shows same tooltip for all.

I have used tip._tippy.destroy(); bit didn't worked.

<div id="template" style="display: none;">
    Loading a tooltip...
</div>

Element on which tooltip shows above:

<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>

Js:

const template = document.querySelector('#template')
const initialText = template.textContent
const tip = tippy('.otherPostTags', {
    animation: 'shift-toward',
    arrow: true,
    html: '#template',
    onShow() {
        const content = this.querySelector('.tippy-content')
        if (tip.loading || content.innerHTML !== initialText) return
        tip.loading = true
        node = document.querySelectorAll('[data-tippy]');
        let id = node[0].dataset.postid;
        $.ajax({
            url: '/get/post/'+id+'/tags',
            type: 'GET',
            success: function(res){
                let preparedMarkup = '';
                res.tags.map(function(item) {
                    preparedMarkup +=
                        '<span class="orange-tag" style="background-color: '+item.color+'">'+
                            item.name +
                        '</span>';
                });
                content.innerHTML = preparedMarkup;
                tip.loading = false
            },
        });
    },
    onHidden() {
        const content = this.querySelector('.tippy-content');
        content.innerHTML = initialText;
    },
});

When i hover over, The tooptip shows with tags coming from the database, But it shows same tags/data on hover, The data comes different but it shows tooltip which comes on first hover.

Chez answered 18/9, 2018 at 19:4 Comment(7)
why is everything declared using const? Every variable in your code i mean.Birkenhead
+1, But turns out the ID i am sending in the ajax request sends the only last one Thats why the tooltip comes the same, My bad there. How can i get tooltip data attribute with $(this), To send unique ID with each request ?Chez
@Chez you should add some markup, if you wish accurate example code - because the question does not really indicate, against what the code would run - therefore only permitting generic answers.Nagging
@martinZeitler Updating question.Chez
@martinZeitler question updatedChez
@vicByte Question updatedChez
if the span element is the one that triggers the tooltip on hover then grab the id of the tooltip showing by the aria-describedby attribute on span element. You may check what i mean in this fiddle jsfiddle.net/vo1sxzbp/3, hover over a button while inspecting the element on your browser. I hope this is what you mean in your comment. @ChezBirkenhead
Z
6

Your problem is here:

node = document.querySelectorAll('[data-tippy]');
let id = node[0].dataset.postid;

Instead of selecting currently hovered element, you always select the same element (node[0]).

You can use the callback functions argument to get the current element clicked (onShow first argument contains a reference to an object that has reference to the original element, in my example - tip.reference). Example below:

tippy.setDefaults({
  arrow: true,
  delay: 240,
  theme: 'my-tippy',
  onShow(tip) {
    console.log('Post id: ' + $(tip.reference).data('postid'));
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/tippy.js@3/dist/tippy.all.min.js"></script>
<button data-tippy="Tooltip" data-postId="1">Post 1</button>
<button data-tippy="Another tooltip" data-postId="2">Post 2</button>
<button data-tippy="Another tooltip" data-postId="3">Post 3</button>
Zebulun answered 23/9, 2018 at 13:16 Comment(6)
Perfect... Solved, Thanks a million, Sadly can't upvote your answer a million times. I will accept the answer as soon as it lets me accept.Chez
Glad i helped with your issue. :)Zebulun
In the mean time, Let me ask you something about it. Currently this works for content which loads for the first time. But It doesn't works if the html gets appends, Means when the <button data-tippy="Another tooltip" data-postId="3">Post 3</button> appends dynamically the tooltip does not shows up. What can be done with that ?Chez
@Chez If i understood you right, when you dynamically add new buttons to the page, tips no longer shows on them?Zebulun
This is probably due to how tippy does initialization (adds tips only to the elements currently on page). You could try initializing the new elements after you add them (for example load them with an additional class/data-attribute -> initialize that class -> remove the extra class).Zebulun
I will try that.Chez
N
1

this is because keyword const creates a read-only variable.

Constants are block-scoped, much like variables defined using the let statement.

The value of a constant cannot change through reassignment, and it can't be re-declared.

you have to change it to var or let, because it needs to be mutable (which const isn't).

The var statement declares a variable, optionally initializing it to a value.

The let statement declares a block scope local variable, optionally initializing it to a value.

theory aside, you have to change const tip to var tip - in order to update and/or destroy it.

according to the following markup - which is still a little narrow, because it is not the rendered HTML output of one whole post's markup, as it would be required to reproduce the issue in a reliable manner:

<span class="more-tags otherPostTags" data-postId="{{$post->id}}">...</span>

one could (probably, within the scope of the event source) obtain the id alike:

var id = parseInt($(this).data('postId'));

the most common method to handle ids would be to use attribute id (eg. with a post_id alike post_45) of the whole post's node in combination with

var id = parseInt($(selector).attr('id').replace('post_', ''));

the bottom line is, that without the complete markup of a single post, I can only hint for syntax alike $(this).parent().parent()..., which may be required in order to get a handle, which would need to be selected relative to the event source.

Nagging answered 23/9, 2018 at 12:34 Comment(6)
+1, But turns out the ID i am sending in the ajax request sends the only last one Thats why the tooltip comes the same, My bad there. How can i get tooltip data attribute with $(this), To send unique ID with each request ?Chez
I don't think const would be a problem though. You cannot reassign the variable itself, but it's entirely fine to reasign a property inside it (update it).Zebulun
@martinZeitler it says Uncaught ReferenceError: selector is not defined with $(selector).data("tooltip")Chez
@Chez selector is a commonly used pseudo-variable for all kinds of DOM selectors - while within the scope of a tooltip event, it would be this, which refers to the source of the event - while outside of that scope, it rather would be a selector string.Nagging
Uncaught ReferenceError: selector is not defined.Chez
@MartinZeitler Updating my demo here, cause its related to this answer: jsfiddle.net/gj4vymzeZebulun

© 2022 - 2024 — McMap. All rights reserved.