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.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With