Multiple tippy.js tooltips with html content - javascript

I am trying to get multiple tooltips on the same page with different HTML content using tippy.js. This content varies - it might me just image or text formatted with HTML tags or text + image(s). How can I make this work?
I tried to run this code but didn't had much success
<a class="btn" href="#">Text</a>
<div class="myTemplate">
<b>Text</b> <img src="https://i.imgur.com/dLcYjue.png">
</div>
<a class="btn" href="#">Text2</a>
<div class="myTemplate">
<b>Text2</b>
</div>
<script type="text/javascript">
tippy('.btn', {
content: document.querySelector('.myTemplate')
})
const clone = document.querySelector('.myTemplate').cloneNode(true)
</script>

maybe this helps someone getting here again:
also check the documentation:
https://atomiks.github.io/tippyjs/v6/html-content/
document.querySelectorAll('button[data-template]').forEach(btn => {
tippy(btn, {
content(reference) {
const id = reference.getAttribute('data-template');
const template = document.getElementById(id);
return template.innerHTML;
},
allowHTML: true
})
})
<script src="https://unpkg.com/#popperjs/core#2.0.6/dist/umd/popper.min.js"></script>
<script src="https://unpkg.com/tippy.js#6.0.0/dist/tippy-bundle.umd.min.js"></script>
<button data-template="one">One</button>
<button data-template="two">Two</button>
<button data-template="three">Three</button>
<div style="display: none;">
<div id="one">
<strong>Content for `one`</strong>
</div>
<div id="two">
<strong>Content for `two`</strong>
</div>
<div id="three">
<strong>Content for `three`</strong>
</div>
</div>

tippy takes selector as its primary argument, You would need different ids to do this. If there are more than a couple of content tooltips/generated at runtime, I would recommend to use a common convention in setting id and using a for loop for iterating over it.
Considering, there are 2 content tooltips,
<a class="btn1" href="#">Text</a>
<div class="myTemplate1">
<b>Text</b> <img src="https://i.imgur.com/dLcYjue.png">
</div>
<a class="btn2" href="#">Text2</a>
<div class="myTemplate2">
<b>Text2</b>
</div>
<script type="text/javascript">
tippy('.btn1', {
content: document.querySelector('.myTemplate1')
})
tippy('.btn2', {
content: document.querySelector('.myTemplate2')
})
</script>

Related

Link simillary name classes so that when one is clicked the other is given a class

Basically, I'm asking for a way to optimize this code. I'd like to cut it down to a few lines because it does the same thing for every click bind.
$("#arch-of-triumph-button").click(function(){
$("#arch-of-triumph-info").addClass("active-info")
});
$("#romanian-athenaeum-button").click(function(){
$("#romanian-athenaeum-info").addClass("active-info")
});
$("#palace-of-parliament-button").click(function(){
$("#palace-of-parliament-info").addClass("active-info")
});
Is there a way to maybe store "arch-of-triumph", "romanian-athenaeum", "palace-of-parliament" into an array and pull them out into a click bind? I'm thinking some concatenation maybe?
$("+landmarkName+-button").click(function(){
$("+landmarkName+-info").addClass("active-info")
});
Is something like this even possible?
Thanks in advance for all your answers.
EDIT: Here's the full HTML.
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button"></div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button"></div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Assuming you're not able to modify your HTML markup (in which case with use of CSS classes would be cleaner), a solution to your question would be as shown below:
// Assign same click handler to all buttons
$("#arch-of-triumph-button, #romanian-athenaeum-button, #palace-of-parliament-button")
.click(function() {
// Extract id of clicked button
const id = $(this).attr("id");
// Obtain corresponding info selector from clicked button id by replacing
// last occurrence of "button" pattern with info.
const infoSelector = "#" + id.replace(/button$/gi, "info");
// Add active-info class to selected info element
$(infoSelector).addClass("active-info");
});
Because each .landmark-button looks to be in the same order as its related .landmark-info, you can put both collections into an array, and then when one is clicked, just find the element with the same index in the other array:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
This does not rely on IDs at all - feel free to completely remove those from your HTML to declutter, because they don't serve any purpose now that they aren't being used as selectors.
Live snippet:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
.active-info {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button">click</div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button">click</div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Older answer, without knowing the HTML: You can extract the ID of the clicked button, slice off the button part of it, and then select it concatenated with -info:
$(".landmark-button").click(function() {
const infoSel = this.id.slice(0, this.id.length - 6) + 'info';
$(infoSel).addClass('active-info');
});
A much more elegant solution would probably be possible given the HTML, though.

JQuery toggle/html: changing the content in div

I'm currently working on a blog layout with a main div and a side bar with links. I want each link to change the content of the main div.
I tried using toggle and html.
Here's the main class and the content of each link:
<div id="main"></div>
<div id="works">
These are my works.
</div>
<div id="info">
About me.
</div>
<div id="tags">
Tag list.
</div>
And the side bar:
<div id="mainlink">
<button class="linkd" id="butt1"> works </button>
<button class="linkd" id="butt2"> info </button>
<button class="linkd" id="butt3"> Tags </button>
</div>
So when I click on the button "works" I want the content of that div into the main div.
Here's the snippet of the JQuery (that doesn't work):
$(function(){
$('#butt1').click(function() {
$('#main').html($('#works'));
$('#works').toggle();
$('#info').hide();
$('#tags').hide();
});
$('#butt2').click(function() {
$('#main').html($('#info'));
$('#info').toggle();
$('#works').hide();
$('#tags').hide();
});
$('#butt3').click(function() {
$('.mainp').html($('#tags'));
$('#tags').toggle();
$('#info').hide();
$('#works').hide();
});
});
Note: on my CSS I have the display: none as well.
I think it is the easy way to show and hide divs, by assigning a relation to the buttons using HTML5's data attribute (here their ids are used in data-target attribute). See the snippet below...
$(function(){
$('[data-target]').on('click', function(){
var target = $(this).data('target');
$(target).siblings().hide().end().show();
});
});
#main > div:not(:first-child) {display: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainlink">
<button class="linkd" data-target="#works"> works </button>
<button class="linkd" data-target="#info"> info </button>
<button class="linkd" data-target="#tags"> Tags </button>
</div>
<div id="main">
<div id="works">
These are my works.
</div>
<div id="info">
About me.
</div>
<div id="tags">
Tag list.
</div>
</div>

Remove src from all iframes and add it on click

I'm trying to remove the src values from all my iframes and then on click load the srcs to the ones matched by a selector.
Right now I have a block of code that empties the src of my iframes and creates a variable with the src info.
After that I'm trying to check if an iframe src is empty and if so, have a function that on click of a link will add the corresponding src values to the returned iframes.
The code is as follows, but the click part is not working.
Naturally I'm not sure about the IF part, as well, since the thing as a whole is not working.
$j=jQuery.noConflict();
var iframesa = $j('iframe');
iframesa.each(function() {
var srca = $j(this).attr('src');
$j(this).data('src', srca).attr('src', '');
});
$j(document).ready(function(){
if($j('iframe').attr('src') == '') {
$j('.evento-more').click(function() {
$j(this).next().children('iframe').attr('src', function() {
return $j(this).data('src');
});
});
}
});
The HTLM structure is something like this
<div class="evento-feed">
<div class="wrapper">
More
<div class="evento-desc">
<div class="slide-text">
<p>
<iframe src="https://www.youtube.com/embed/xxxx"></iframe>
</p>
</div>
<div class="slide-text">
<p>
<iframe src="https://www.soundcloud.com/embed/xxxx"></iframe>
</p>
</div>
</div>
</div>
</div>
<div class="evento-feed">
<div class="wrapper">
More
<div class="evento-desc">
<div class="slide-text">
<p>
<iframe src="https://www.mixcloud.com/embed/xxxx"></iframe>
</p>
</div>
</div>
</div>
</div>
And so on. The whole .evento-feed block gets repeated a few more times, although the content may vary
Is there anyone that can help me?

Show multiple <div> on click JavaScript

I am trying to add some code to a page that keeps adding <div> sections to a page when a link is clicked. Here's my code:
<script type="text/javascript">
function ShowDiv() {
document.getElementById("show").style.display = "";
}
</script>
<p><a href="#" class="control" onclick="ShowDiv()"; >Add New</a></p>
<div id="show" style="display: none;">
<p>This is the div!</p>
</div>
This works great for one <div> but I need it to keep adding down the page when the link is clicked. I t is going to be used to hold a form with an array of ids for posting to PHP.
You can clone original div (which will be as template) and append cloned one to the page:
Fiddle.
HTML:
<p>
<a id="add" href="#" class="control">Add New</a>
</p>
<div id="show" style="display: none;">
<p>This is the div!</p>
</div>
JS:
$(document).ready(function()
{
var i = 0;
$('#add').click(function()
{
var newEl = $('#show').clone();
newEl.attr('id', "show" + i);
i++;
newEl.show().appendTo("body");
});
});
<script type="text/javascript">
function ShowDiv() {
var a = $("#show").clone(true); // clones element
$(".test").append(a); // appends to parent
}
</script>
<p><a href="#" class="control" onclick="ShowDiv()"; >Add New</a></p>
<div class="test"> <!-- defines parent for simple selection -->
<div id="show"> <!-- element to clone -->
<p>This is the div!</p>
</div>
</div>

Javascript click specific to ID

I have a div setup like so:
<div class="content">
<button class="show-comments" id="content1"></button>
</div>
<div class="comments-wrapper" id="comment1"></div>
<div class="content">
<button class="show-comments" id="content2"></button>
</div>
<div class="comments-wrapper" id="comment2"></div>
I have the following code:
$('.show-comments').click(function(e){
e.preventDefault();
$('.comments-wrapper').slideToggle('slow');
});
As you would assume, the code works but on a class basis. I'd like for it to open up only the .comments-wrapper of its associated id (i.e. open slideToggle comments2 if content 2 button is clicked and so on and so on).
How would I do this?
$('.show-comments').click(function(e){
e.preventDefault();
$(this).closest(".content").next('.comments-wrapper').slideToggle('slow');
});
Note that this is dependent on the .content element being immediately followed by the .comments-wrapper.
If you have access to modify the html itself, I would suggest adding a wrapper element and then doing the following to avoid the reliance on the exact order of elements:
<div class="wrapper">
<div class="content">
<button class="show-comments" id="content1"></button>
</div>
<div class="comments-wrapper" id="comment1"></div>
</div>
<div class="wrapper">
<div class="content">
<button class="show-comments" id="content2"></button>
</div>
<div class="comments-wrapper" id="comment2"></div>
</div>
$(this).closest(".wrapper").find('.comments-wrapper').slideToggle('slow');
This way, if you add an element between the .content and the .comments-wrapper it does not break the code.
You can do this:
$(this).parent("div").next('.comments-wrapper').slideToggle('slow');
This will find the related div of class .comments-wrapper and slide toggle.
And a fiddle: http://jsfiddle.net/xCJQB/
$('.show-comments').click(function (e) {
e.preventDefault();
var num = this.id.match(/\d+$/)[0];
$("#comment" + num).slideToggle('slow');
});
Demo ---> http://jsfiddle.net/7pkyk/1/
Use this context
$(this).closest('.comments').next('.comments-wrapper').slideToggle('slow');
If it is not the immediate element then you might try this as well
$(this).closest('.comments')
.nextAll('.comments-wrapper').first().slideToggle('slow');
you can add a common class to associate a button with a div.
html:
<div class="content">
<button class="show-comments group1" id="content1"></button>
</div>
<div class="comments-wrapper group1" id="comment1">1</div>
<div class="content">
<button class="show-comments group2" id="content2"></button>
</div>
<div class="comments-wrapper group2" id="comment2">2</div>
javascript:
$('.show-comments').click(function(e){
var associate = $(this).attr('class').match(/group\d+/).pop();
var selector = '.comments-wrapper.' + associate;
e.preventDefault();
$(selector).slideToggle('slow');
});
http://jsfiddle.net/uMNfJ/

Categories

Resources