qTip change text of specific tooltip after for each - javascript

I have an html page with some inputs and textareas.
I want them to have qTip with different texts.
Here is my attempt
First I add a qTip to every element,
$('input, textarea').each(function() {
$(this).qtip(
{
content : 'generated', //this is for debug
position : {
my : 'center left',
at : 'center right',
adjust : {
x : 90
}
}
});
});
and then I'm trying to change an qTip text like this
$("#firstName").qtip('option', 'content.text', 'adwd');
but it is not working.
I tried this
$("#lastName").qtip({
content : 'text text'
});
which is working fine but it overrides the position

This code working for me:
$("#firstName").qtip('option', 'content.text', 'new tooltip content')
If you have to change it on an event (eg over or similar) try using this code:
// make sure you target a specific tip
var qapi = $('#firstName').data('qtip'),
newtip = 'new tooltip content'
qapi.options.content.text = newtip; // update content stored in options
qapi.elements.content.text(newtip); // update visible tooltip content
qapi.redraw(); // redraw to adjust tooltip borders
The code update only a specific option and leave the others as are.
Demo: http://jsfiddle.net/IrvinDominin/L7fs5/

Related

Bootstrap 5.2, prevent closing tooltip if cursor is back on triggering element

TLDR: moving the cursor from tooltip back to triggering element closes, shows and closes the tooltip (flickers).
I need to make the tooltips open on hover and make their content clickable. I have found a working example here on SO.
As you hover over the element it shows you a tooltip which can be interacted with, once you move the cursor away from the tooltip it closes.
There is a problem though.
If you leave the tooltip and move the cursor back on the element which triggered the tooltip, the tooltip pops back up, but dissapears after a moment ("flickering"). You need to move the cursor away from the element and back on the element for the tooltip to show again.
What I am trying to do, is check if the cursor is back on the triggering element and if that is the case not run the closing function (tooltip.hide()).
I have tried to do this by imitating the existing process from the example found on SO. That is, check if the tooltip has lost :hover, setTimout (300ms) and check if cursor is now positioned on the triggering element or back on the tooltip.
Here is a jsFiddle example.
This is the code. The problematic code is between the two looong comment lines.
Note: Moving the cursor away from the triggering element and back on the triggering element also triggers the flickering.
//https://stackoverflow.com/questions/67993080/bootstrap-5-make-tooltip-hoverable-and-link-clickable
var tooltipTriggerList = [].slice.call(document.querySelectorAll('button'))
for (let tt of tooltipTriggerList){
tt.setAttribute("data-bs-placement","top")
}
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
const tooltip = new bootstrap.Tooltip(tooltipTriggerEl, {
trigger: "manual",
'customClass': 'custom-tooltip'
})
let tooltipElTimeout;
let currentToolTip;
let currentTooltipTimeout;
tooltipTriggerEl.addEventListener("mouseenter", function () {
let toolTipID;
// Clear Set Timeout
clearTimeout(currentTooltipTimeout);
// 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 () {
currentTooltipTimeout = setTimeout(()=>{
console.log("!currentToolTip.matches(':hover')");
console.log(!currentToolTip.matches(":hover"));
if(!tooltipTriggerEl.matches(":hover")){
console.log("!tooltipTriggerEl.matches(':hover')");
console.log(!tooltipTriggerEl.matches(":hover"));
if (!currentToolTip.matches(":hover")) {
tooltip.hide();
}
}
}, 300)
});
/***********************************************************************/
});
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;
})
Thank you
Edit:
Amine Ramouls answer is correct. isHidden also needs to bet set to false on the 2cnd eventListener, otherwise the tooltips no longer work (problem with aria-describedby).
in your code you have an event listener wich add an event listner and that's a big mistake because it add an infinit number of eveneent listner to your element.
so you juste have to organize your code like this :
//https://stackoverflow.com/questions/67993080/bootstrap-5-make-tooltip-hoverable-and-link-clickable
var tooltipTriggerList = [].slice.call(document.querySelectorAll('button'))
for (let tt of tooltipTriggerList){
tt.setAttribute("data-bs-placement","top")
}
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
const tooltip = new bootstrap.Tooltip(tooltipTriggerEl, {
trigger: "manual",
'customClass': 'custom-tooltip'
})
let isHidden = true;
let currentTooltipTimeout;
tooltipTriggerEl.addEventListener("mouseenter", function () {
let toolTipID;
// Clear Set Timeout
clearTimeout(tooltipElTimeout);
clearTimeout(currentTooltipTimeout);
if (isHidden)
{
tooltip.show();
isHidden=false;
}
});
// Hide tooltip on tooltip mouse leave
tooltipTriggerEl.addEventListener("mouseleave", function () {
console.log("!currentToolTip.matches(':hover')");
if(!tooltipTriggerEl.matches(":hover")){
currentTooltipTimeout=setTimeout(()=>{
if (!isHidden && !tooltipTriggerEl.matches(":hover")){
tooltip.hide();
isHidden=true;
}
console.log("!tooltipTriggerEl.matches(':hover')");
console.log(!tooltipTriggerEl.matches(":hover"));
}, 3000)
}
});
return tooltip;
})
now as you can see i juste added the isHidden var to check if the popup info is hidden or not, you can do that with the element if you can get it by a query selector request. that's it. enjoy your life.
Edit: i forget to tell you that i have put 3 seconde before checking the if the popup is hidden or not.

intro.js steps and tooltip position works fine, except when "back" is pressed

I have set up an intro of a web page using the steps and setoptions functionality, and it works fine except when the user presses back.
The two issues I find are:
scrolltoelement works fine going forward, but the tooltip goes partly off screen when going backwards
the element selected in the first step is the entire page, so I use an "onafterchange" callback to reset the tooltip top and right offset. This works fine, except it appears to be ignored (or overwritten) when the back key is pressed
The javascript is:
var introProfile = introJs();
introProfile.setOptions({
tooltipPosition : 'top',
steps: [
{
element: '#intro_step1',
intro: 'Welcome to your example.com dashboard, where you can update your skills, your availability, and your professional details so that ...',
position: 'top'
}, {
element: '#intro_step2',
intro: 'Your profile contains important information which is important to complete so that...',
position: 'bottom'
},
{
element: '#intro_step3',
intro: 'Make sure your attribute is included in your profile because the client may express a preference.',
position: 'top'
},
{
element: '#intro_step4',
intro: 'Click here to add a photograph of yourself.',
position: 'top'
},
{
element: '#intro_step5',
intro: 'Your photograph will appear when your profile matches a ...',
position: 'top'
},
{
element: '#intro_step6',
intro: 'Take example.com with you, on your Android or Apple phone by clicking here.',
position: 'top'
}
]
});
introProfile.oncomplete(function() {
;
});
introProfile.onexit(function(){
;
});
introProfile.onchange(function(targetElement) {
; //add change bits here
});
introProfile.onafterchange(function(targetElement) {
console.log(targetElement.id);
switch (targetElement.id){
case "intro_step1":
$('.introjs-tooltip').css({top:'80px',left:'200px'});
}
});
introProfile.onbeforechange(function(targetElement) {
; // add change bits here
});
introProfile.start();
All I am doing in the HTML is setting the element id for intro_step1 to intro_step6
You can see the fiddle here: https://jsfiddle.net/brianlmerritt/3ocyuu65/10/
Any idea why "back" functionality is different from forward?
The problem was you wanted to change the position of the tooltip for the 1st step by using -
$('.introjs-tooltip').css({top:'80px',left:'200px'});
This was added in the "onafterchange" function -
introProfile.onafterchange(function(targetElement) {
console.log(targetElement.id);
switch (targetElement.id){
case "intro_step1":
$('.introjs-tooltip').css({top:'80px',left:'200px'});
}
});
Now this function was as expected called when you initialised the introjs - meaning after the position was changed by the introjs and then was overridden by your positions in the "onafterchange" function
But in case of when you hit back this function was called after the position was changed by introjs. So to fix this i used "setTimeout"
setTimeout(function(){
$('.introjs-tooltip').css({top:'80px',left:'200px'});
},600)
So now your positions are now overridden for the tooltip
Note: Your code would have worked if the poition changes for the tooltip was completed first and then the "onafterchange" function was called.
Fiddle: https://jsfiddle.net/kushal812/3ocyuu65/11/
Let me know if you find a better way!!
Really IntroJS is showing some errors when using the Back button. Here is the solution using Ionic with the Typescript Framework:
export class HomePage {
introApp = introJs.introJs(); //Declared the IntroJS
...
this.intro(); // Call the method
...
intro() { this.introApp.setOptions({...})} //Set the options in IntroJS
//Bug Correction
this.introApp.onafterchange(function(targetElement) {
console.log(targetElement.id);
switch (targetElement.id){
case "b1":
setTimeout(function(){
var element = document.getElementsByClassName('introjs-tooltip');
var boxArrow = document.getElementsByClassName('introjs-arrow top');
var numberLayer = document.getElementsByClassName('introjs-helperNumberLayer');
element.item(0).setAttribute("style", "top:210px;");
boxArrow.item(0).setAttribute("style", "display: block");
numberLayer.item(0).setAttribute("style", "left: 0; top:0;");
},600)
}
});

bootstrap popover 3.0 with tables

When I use bootstrap 3.0 popover with placement: auto right inside tables it doesn't work, and it flows away from the table size.
placement: auto right (means popover should flow to the right if it has a place otherwise flow to the left)
Check this link:
http://jsfiddle.net/DTcHh/65
However, when I place it outside a table it works as it's supposed to be!
$('button.hey').popover({
placement: 'auto left',
html: true,
//selector: '[rel="popover"]',
content: function () {
return "Hi man";
}
})
Any idea?
In your case I suggest you to write your own callback for placement rather using 'auto'.
If you want 'right' for your all buttons except last td. Here is how placement can be written
$('button.hey').popover({
placement: function(context,source){
//check if current td is last one
var td = $(source).closest('td');
console.log(td);
if(td.next().length == 0) {
return 'left';
}
return 'right';
},
html: true,
//selector: '[rel="popover"]',
content: function () {
return "Hi man";
}
})
If you want to handle based on position, you can handle that in placement callback.
check this fiddle http://jsfiddle.net/codejack/DTcHh/66/

div same as tooltip

you helped me yesterday with create tooltip div. Today i would like to extend it.
I have something like that: http://jsfiddle.net/Axjgf/18/
How can I change it so that the yellow box appears next to the box that I clicked on? For instance if I click on the purple box it should appear next to the purple box instead of the black.
thanks for help!
Solution:
http://jsfiddle.net/genesis/VmXU9/26/
Have a look at the last example here: Query-Click Doc. Use $(this) for getting the clicked div attributes.
If you want to change the color of the overlay box, you can give each smaller box its own click utility.
EDIT:
Just realized you wanted a position change! ;-) Code is fixed. See below.
$("#TWO").click(
function()
{
$("#THREE").toggle().css({'opacity' : '0.8', 'backgroundColor' : 'blue', 'top' : '-320px'});
});
$("#five").click(
function()
{
$("#THREE").toggle().css({'opacity' : '0.8', 'backgroundColor' : 'purple', 'top' : '-280px'});
});
$("#six").click(
function()
{
$("#THREE").toggle().css({'opacity' : '0.8', 'backgroundColor' : 'yellow', 'top' : '-220px'});
});
http://jsfiddle.net/jasongennaro/Axjgf/21/
EDIT 2:
Since the question changed, I edited the fiddle, to remove the background color change.
$("#TWO").click(
function()
{
$("#THREE").toggle().css({'opacity' : '0.8', 'top' : '-320px'});
});
$("#five").click(
function()
{
$("#THREE").toggle().css({'opacity' : '0.8', 'top' : '-280px'});
});
$("#six").click(
function()
{
$("#THREE").toggle().css({'opacity' : '0.8', 'top' : '-220px'});
});
http://jsfiddle.net/jasongennaro/Axjgf/22/
Since you're already using jQuery, I would highly recommend using the jQuery UI library's "Position" utility.
It has quite a few useful little methods for aligning objects relative to another object. For example using that library you could modify your click function to something like this (untested):
$('.click').click(function(){
$(c) = $(this);
$('#THREE').position({
my: 'left top',
at: 'right center',
of: $(c)
});
});

qTip tooltip does not appear, jQuery

I have a site that displays items, 12 items per page and I can paginate through the pages using jquery. On the same page I implemented a the tooltip feature with qTip.
Hovering over the items some information appear. That works until I use the paginator to go to the next page.
The pagination reloads the content. But it has the same structure as when I refresh the page.
Here's my code:
$(document).ready(function() {
$(".cornerize").corner("5px");
$('a#verd').live('click', exSite);
$("a.tp").live('click', thumpsUp);
$("a#next").click(getProgramms);
$("a#previous").click(getProgramms);
$("a#page").each(function() {
$(this).click(getProgramms);
});
$('a.ppname[rel]').each(function(){
$(this).qtip( {
content : {url :$(this).attr('rel')},
position : {
corner : {
tooltip : 'leftBottom',
target : 'rightBottom'
}
},
style : {
border : {
width : 5,
radius : 10
},
padding : 10,
textAlign : 'center',
tip : true,
name : 'cream'
}
});
});
});
The html/dom does not change:
<a class="ppname" rel="link" href="#">...</a>
qTip takes from every a.ppname the rel value end loads the content.
This is happening because new elements are not automatically "qTiped" when they are loaded after page load. For regular events, you would have to use .live() instead of .bind().
This has been solved before (judging from the comment): Problem with qTip - Tips not showing because elements load after the script.
The correct way to do it is (from that answer):
$('a.ppname[rel]').live('mouseover', function() {
var target = $(this);
if (target.data('qtip')) { return false; }
target.qtip({
overwrite: false, // Make sure another tooltip can't overwrite this one without it being explicitly destroyed
show: {
ready: true // Needed to make it show on first mouseover event
},
content : {url :$(this).attr('rel')},
position : {
corner : {
tooltip : 'leftBottom',
target : 'rightBottom'
}
},
style : {
border : {
width : 5,
radius : 10
},
padding : 10,
textAlign : 'center',
tip : true,
name : 'cream'
});
target.trigger('mouseover');
});

Categories

Resources