I am trying to show tooltips in a mouseover event in cytoscape.js using qtip. The tooltip is displayed when the mouse is over a node in the graph, however, it is positioned at the top-left corner of the graph, instead of showing at the bottom of the node. Here is the code to display the graph:
this.cyto = cytoscape({
container: document.getElementById("graph"),
layout: {
name: 'spread',
minDist: 200
},
elements: this.graph.elements,
style: this.cy_style
});
Add here is the code I am using to add the qtip
this.cyto.nodes().forEach(function (element) {
var nodeName = element.data("name");
if (nodeName) {
element.qtip({
content: {
text: nodeName
},
position: {
my: 'bottom center',
at: 'bottom center',
adjust: {
y: 50,
mouse: false
}
},
show: {
event: 'mouseover'
},
hide: {
event: 'click mouseout'
},
style: {
classes: 'qtip-bootstrap'
}
});
}
});
Here is a screenshot showing how the tooltip is currently being displayed:
As you can see in the image above, the tooltip displays at the top left corner of the graph. However, I want to display the tooltip like this:
How can I make the tool-tip display at the proper position? What am I doing wrong here?
It looks like you're missing the qtip stylesheet, which I believe qtip needs to work.
You can refer to the demo code for a working example: http://js.cytoscape.org/demos/qtip-extension/
Related
I am using TippyJS to show a tooltip but for some reason when first click the tooltip it is positioned way too much to the right, and if you have a small screen it will even go outside of view.
Example:
While after I scroll a bit, or resize the page it gets positioned correctly.
Example:
What could be causing this behaviour?
Example codepen (shopping cart is empty but still has the same behaviour when clicking/scrolling): https://codepen.io/twan2020/pen/ZEBvYXv
I've tried setting boundary:viewport in the options like this:
$( ".carttip" ).each(function( i ) {
tippy(this, {
theme: 'blue',
trigger: 'click',
allowHTML: true,
animation: 'scale-subtle',
maxWidth: 400,
boundary: 'viewport',
interactive: true,
content: function (reference) {
return reference.querySelector('.tooltipcontent');
},
onShow(instance) {
refreshcart(true);
}
});
});
But this changed nothing.
As Stavros Angelis points out, the tippy instance positioning is already calculated when the content is applied. To reposition the tooltip when the ajax call resolves, you could pass the tippy instance into the refreshcart() function and then accessing the popper instance inside it to refresh the tooltip:
function refreshcart(force, tippyInstance) {
$.ajax({
type: 'post',
url: 'includes/refreshcart.php',
data: ({}),
success: function(data){
$('body #headercart').empty().append(data);
tippyInstance.popperInstance.update(); // Here, the tippy positioning is updated
}
});
}
// other code...
$( ".carttip" ).each(function( i ) {
tippy(this, {
theme: 'blue',
trigger: 'click',
allowHTML: true,
animation: 'scale-subtle',
maxWidth: 400,
boundary: 'viewport', // This has been dropped in tippy#6
interactive: true,
content: function (reference) {
return reference.querySelector('.tooltipcontent');
},
onShow(instance) {
refreshcart(true, instance);
}
});
});
As for the boundary: seems like tippy#6 (which your example uses) has dropped this prop, so it can be removed here.
More on the popper instance here: https://github.com/atomiks/tippyjs/issues/191
The problem comes from the onShow function. The way your code works is that first you open the popup, then you do an ajax call and fetch some html to append in the tippy box. At that point the tippy box has already rendered and calculated the position of the box with a 0 width and 0 height. Then the ajax call completes and the container changes dimensions and ends up outside the viewport.
The tippyjs documentation covers that here with a very clean example: https://atomiks.github.io/tippyjs/v6/ajax/
this is my last resort, as I was looking at this question:
Changing the position of Bootstrap popovers based on the popover's X position in relation to window edge?
And couldn't find a solution to my problem, currently I have the popovers triggered by this code:
var popOverSettings = {
selector: '[data-toggle=popover]',
viewport: {
selector: '.container',
padding: 80
},
trigger: 'hover',
placement: 'auto top',
html: true,
container: 'body',
animation: false,
delay: {
show: 50,
hide: 100
}
};
$('body').popover(popOverSettings);
When the popover reaches the body maximum top, it automatically pushes it down, but I want that it takes the height of the header too, is there any way to specify pixels to the top placement? something like placement: 'auto top' + 50, because this is what happens:
Thanks in advance.
In general, I am trying to have an icon which stays to the right of a field. I need it to work in Firefox, Chrome, IE11 and IE8
JS Fiddle: http://jsfiddle.net/e8f6N/3/
There is a fieldset which can be expanded or collapsed. When the fieldset changes, the fields below it move up or down to compensate for the movement. When this happens, Firefox is unique in that the icons do not move with the field's body.
I find that if I use relative positioning rather than absolute, the icon will move with the field like it should. However, then there is some white space being put below each field, which I do not want.
Advice is appreciated in the following questions:
A way for firefox to move the icon with the rest of the field?
A way to use relative positioning and not have the extra space being
inserted below the field?
Alternatively, a better way to skin this cat?
Code used in fiddle:
Ext.onReady(function () {
Ext.QuickTips.init();
var fieldSet = Ext.create('Ext.form.FieldSet', {
title: 'Simple Collapsible Fieldset',
collapsible: true,
items: [{
xtype: 'label',
text: 'Watch the icon and collapse this fieldset'
}]
});
var textBoxWithInfoIcon = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Example',
listeners: {
afterrender: function (me) {
var icon = me.getEl().down('.x-form-item-body').createChild({
cls: 'x-form-info-icon',
tag: 'img',
src: 'broken',
width: 16,
height: 18,
'data-qtip': 'an example textfield to simulate this icon which does not move',
'data-qtitle': 'Field Information'
});
var xPosition = 130;
var yPosition = 0;
icon.alignTo(me.getEl(), 'tl-tr', [xPosition, yPosition]);
}
}
});
var textBox = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Example'
});
var textBoxWithInfoIcon2 = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Example',
listeners: {
afterrender: function (me) {
var icon = me.getEl().down('.x-form-item-body').createChild({
cls: 'x-form-info-icon',
tag: 'img',
src: 'broken',
width: 16,
height: 18,
'data-qtip': 'an example textfield to simulate this icon which does not move',
'data-qtitle': 'Field Information'
});
var xPosition = 130;
var yPosition = 0;
icon.alignTo(me.getEl(), 'tl-tr', [xPosition, yPosition]);
}
}
});
var panel = Ext.create('Ext.panel.Panel', {
title: 'Title',
frame: true,
width: 400,
height: 200,
items: [fieldSet, textBoxWithInfoIcon, textBox, textBoxWithInfoIcon2],
renderTo: document.body
});
});
p.s. There are a lot of questions with similar titles, yet as far as I've found they don't have to deal with a collapsing fieldset and just use absolute positioning in their css.
EDIT
More details after working with it for a while: After trying to add an info icon to a field's body, the input of the field is at the same level as the icon, but the input is set to take up 100% of the width. I am not sure where/how I can change this.
Absolute positioning of the injected icons is not the best solution for the info icons after fields.
Much better would be to add a after the input field parent . That would solve everything: Input would get shorter to make space for the icon, no need to calculate and set position of the icon, no problems with collapsible fieldset as of now.
I think you need this plugin: Form Field Icon Plugin
I'm wondering how to bring attention to a section that has more information than is showed on the screen. Essentially, the way it currently looks, it might only appear that there is one piece of data in the table, but in reality there is a scroll window. I'd like to bring attention to the fact that there is more data, you just need to scroll. I added the border and that at least started to help.
http://jsfiddle.net/xG3uc/
How would you highlight that there is more data but you just need to scroll to see it?
.but_there_is_more {
max-height: 50px;
overflow-y: auto;
border: 1px dotted #ccc;
}
Maybe if the div expands over the max-height, have some javascript to show a link to "expand" the rest?
Want to try qTip2? Check DEMO http://jsfiddle.net/yeyene/xG3uc/10/
JQUERY
$(document).ready(function(){
$('.a')
.qtip({
content: {
text: 'Scroll for more data!'
},
position: {
my: 'bottom right',
at: 'bottom right'
},
show: {
event: 'mouseover',
ready: true // show the tooltip when ready
},
hide: {
event: 'click unfocus' // click anywhere to hide
},
style: {
classes: 'ui-tooltip-red'
}
});
});
Source and Doc of qTip2 http://craigsworks.com/projects/qtip2/demos/
I am using qTip: http://craigsworks.com/projects/qtip2 and my current problem is that when I hover the tooltip it disappears (because the target was mouseleave/mouseout).
Is there a way to make it stay visible when I hover the tooltip? I positioned the tooltip so that its right under the target so there are zero empty space between the target and the tooltip.
Use fixed: http://craigsworks.com/projects/qtip2/docs/hide/#fixed
You may wish to add a delay as well before the tooltip disappears, in case there's some distance between your triggering element and the tooltip.
e.g.
$('.moreinfo').qtip({
content: {
text: $('<p>This is a tooltip.</p>')
},
show: {
effect: function() { $(this).fadeIn(250); }
},
hide: {
delay: 200,
fixed: true, // <--- add this
effect: function() { $(this).fadeOut(250); }
},
style: {
classes: 'ui-tooltip-blue ui-tooltip-shadow ui-tooltip-rounded'
}
});
Hope it helps.
Use fixed: true as well as leave: false
The problem you might be having is that when you leave the qtip target it is hiding.
For some reason, using fixed:true alone didn't work for me. Instead, I had to use these configurations (v3.0.3):
hide: {
fixed: true,
delay:90,
},
position: {
viewport: $(window)
},