Show leaflet tooltip on hover only when popup is not being shown - javascript

I have a tooltip with a short text only description and a popup with a longer formatted description bound to a marker on a leaflet map.
The tooltip shows on hover and the popup shows when you click on the place marker. When the larger popup is visible there is no need to show the tooltip. Can I disable the tooltip when the popup is visible and how do I do this?
Here is the code I have so far:
var marker = L.marker(location);
marker.bindPopup("Long description with extra formatting ...");
marker.bindTooltip("Short description");

You can add custom handlers for the tooltip and popup. With the leaflet method isPopupOpen() which return true or false you can descide if you open the tooltip or not.
function customTip() {
this.unbindTooltip();
if(!this.isPopupOpen()) this.bindTooltip('Short description').openTooltip();
}
function customPop() {
this.unbindTooltip();
}
var marker = L.marker(location);
marker.bindPopup('Long description with extra formatting ...');
marker.on('mouseover', customTip);
marker.on('click', customPop);

I used the popupopen and popupclose events to manipulate the tooltip visibility.
This is a good generic solution that doesn't involve extending the standard classes and still respects all the standard configuration and options around popups and tooltips.
map.on('popupclose', function (e) {
// make the tooltip for this feature visible again
// but check first, not all features will have tooltips!
var tooltip = e.popup._source.getTooltip();
if (tooltip) tooltip.setOpacity(0.9);
});
map.on('popupopen', function (e) {
var tooltip = e.popup._source.getTooltip();
// not all features will have tooltips!
if (tooltip)
{
// close the open tooltip, if you have configured animations on the tooltip this looks snazzy
e.target.closeTooltip();
// use opacity to make the tooltip for this feature invisible while the popup is active.
e.popup._source.getTooltip().setOpacity(0);
}
});
NOTE: Took a bit of effort to track down the actual events this solution to a different issue pointed me in the right direction: https://stackoverflow.com/a/16707921/1690217
In my case I have bound the tooltip and the popup to have the same content, so I want to hide the tooltip to suppress the redundant information. In the following greenshot you can see the popup for one shape and the tooltip on hover over the other shapes, it looks messy when that tooltip tries to show under the existing popup when you hover over the feature that triggered the popup.

I use another solution in my project. I set the tooltip opacity acording to this.isPopupOpen(). For me this works good, because I don't want to always set the tooltip content again. To hide the tooltip instantly on the click event, set the opacity to 0 on click.
function showHideTooltip()
{
var mytooltip = this.getTooltip();
if(this.isPopupOpen())
{
// Popup is open, set opacity to 0 (invisible)
mytooltip.setOpacity(0.0);
}
else
{
// Popup is cosed, set opacity back to visible
mytooltip.setOpacity(0.9);
}
}
function clickHideTooltip()
{
var mytooltip = this.getTooltip();
mytooltip.setOpacity(0.0);
}
var marker = L.marker(location);
marker.bindPopup("Long description with extra formatting ...");
marker.bindTooltip("Short description");
marker.on('mouseover', showHideTooltip);
marker.on('click', clickHideTooltip);

You can use my solution to this problem:
marker.on('click', function () {
this.getTooltip().setOpacity(this.isPopupOpen() ? 0 : .9);
});
marker.getPopup().on('remove', function () {
this._source.getTooltip().setOpacity(0.9);
});

Related

Include open layer screenshot inside whole page screen shot

I had div - let call him 'global'- that inside him I had title and two maps of openlayer.
I can get a snapshot of the global by html2canvs in this way:
html2canvas(globalElement).then((canvas) => {
this.screenShot(canvas.toDataURL());
});
But the openlayers in the snapshot appeared as tow black div's like this:
I can get the open layer view separately by this code:
this.map.once('rendercomplete', function(event) {
const canvas = event.context.canvas;
console.log(canvas.toDataURL()); // the open layer screen shot
});
this.map.renderSync();
How can I get all this together as one screenshot?
----- edit ----
With the help of #Mike I am using domtoImage like this example:
this.map.once('rendercomplete', function(event) {
domtoimage.toPng(globalElement)
.then((dataURL) => {
console.log(dataURL);
});
});
this.map.renderSync();
and I can get the image of all the div with the open layer map.
A new question came up by this, the mat-icons of angular material didn't display properly with domtoimage, it shows the name of the icon and not the icon.
How can I fix this?

Infinite Scroll + Tooltips + callback

I'm trying to implement a page with infinite scroll and add tooltips to some items. Infinite scroll works fine, but tooltips only appear on the first page, before adding new items with the scroll. This is the example:
https://stage.superbiajuridico.es/news/
The tooltip is in the small yellow circle, when placing the cursor over it. If you scroll down, in the following pages, the rest of the tooltips are not built, although I'm using the append event to build them each time the page is reloaded.
Apparently the code is very simple and I do not know what I'm doing wrong:
// TOOLTIPS
// ------------------
var miTootip = $('.tooltip-item');
new Tooltip(miTootip, {
// options
});
// INFINITE SCROLL
// ------------------
var inf = $('.infinite-scroll-container').infiniteScroll({
// options
});
inf.on('append.infiniteScroll', function(event, response, path, items) {
// THIS IS THE PART THAT DOESN'T WORK
new Tooltip(miTootip, {
// options
});
});
This is not working. I'have not much experience with JS so I think I'm doing wrong something obvious.
EDIT: When trying to codepen, I realized that the error is elsewhere. The tooltip only appears in the first item (it does not have to do with infinite-scroll). This is the pen: https://codepen.io/aitormendez/pen/yRGyZW
As I understand, your new Tooltip(miTootip) takes HtmlElement and replaces with tooltip. So in your append.infiniteScroll event's callback you have to add element with class .tooltip-item, and then create Tooltip.
UPD
You selected .tooltip-item and with this element, using Tooltip constructor, created tooltip, just for one item. So, if you want this tooltip for all items, that this tooltip need, you have to do smth like that:
inf.on('append.infiniteScroll', function(event, response, path, items)
{
$('.infinite-scroll-container').append('<div class="tooltip-item"></div>')
const miTooltip = $('.tooltip-item')
new Tooltip(miTooltip, {
// options
});
});
Tooltips must to be created iterating the jQuery object with a loop.
let myTooltip = $('.tooltip-item');
myTooltip.each(function(){
new Tooltip(this, {
title: "Tooltip",
trigger: "hover",
});
})

Add dojo tooltip dialog to each table cell

I'm tyring to add a dojo tooltip dialog to every table cell so that when i hover over each cell the content. I'm using the tooltip dialog because there is clickable content on it.
I know this is possible using the tooltip control as below
require(["dijit/Tooltip", "dojo/query!css2", "dojo/domReady!"], function(Tooltip){
new Tooltip({
connectId: "myTable",
selector: "tr",
getContent: function(matchedNode){
return matchedNode.getAttribute("tooltipText");
}
});
});
I can't find anyway to do similar with the tooltip dialog, any suggestions?
dijit/TooltipDialog looks like a Tooltip, but it's really a dressed-up dialog. You'll need to use dijit/popup manually to do what you want. Fortunately, there's a great example of this in the documentation.
I've made a fiddle that takes that demo and tweaks it to your situation with a table. Making a different tooltip per cell shouldn't be too far of a leap from here, if that's your desire. You could use dojo/query to get all the cells and attach a new TooltipDialog to each one, for instance.
The relevant parts of that code follow.
Open the dialog when hovering:
on(dom.byId('table1'), 'mouseover', function(){
popup.open({
popup: myTooltipDialog,
around: dom.byId('table1')
});
});
Close the dialog when leaving:
var myTooltipDialog = new TooltipDialog({
// ...
onMouseLeave: function(){
popup.close(myTooltipDialog);
}
});

OpenLayers: Unable to close popup when added using call from outside map

I have written a basic function to allow me to display a popup from a link outside the map. The functionality to open the popup is working fine, but I can't then close it.
Demo link: http://www.catchingtherain.com/bikestats/stations.php - click on links in left-hand tabbed panels.
Here's a bit more detail ...
A typical map has about 300 features on a vector layer 'stations' loaded from kml. These are activated onload using
select = new OpenLayers.Control.SelectFeature(stations);
stations.events.on({
"featureselected": onFeatureSelect,
"featureunselected": onFeatureUnselect
});
map.addLayer(stations);
map.addControl(select);
select.activate();
which works fine - I can open and close popups.
With my off-map links I am calling onclick="showMyPopup([x]) with [x] being an ID attribute loaded in from the kml. The showMyPopup function is
function showMyPopup(myID){
for(var a = 0; a < stations.features.length; a++){ //loop through all the features
var feature = stations.features[a];
if (feature.attributes.ID.value == myID) { //until it finds the one with the matching ID attribute
var content = "<h4>" + feature.attributes.name + "</h4>" + feature.attributes.description;
popup = new OpenLayers.Popup.FramedCloud("chicken",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(200,200),
content,
null, true, onPopupClose);
feature.popup = popup;
map.addPopup(popup);
}
}
}
This opens the correct popup from the stations layer as expected, and I can see the popup using the DOM inspector on the stations layer just as it would appear if loaded by clicking on the map feature, but there's then seemingly no way of closing it. The original features on the stations layer are working fine though (opening and closing).
Any help would be much appreciated (maybe there's a simpler way of tackling this?)
Thanks, James
PS and just in case, here's the onFeatureUnselect function ...
function onFeatureUnselect(event) {
var feature = event.feature;
if(feature.popup) {
map.removePopup(feature.popup);
feature.popup.destroy();
delete feature.popup;
}
}
Your on onPopupClose() function is:
function onPopupClose(evt) {
select.unselectAll();
}
When you select feature from map and click on popup's Close icon, then feature will be unselected, but popup is not closed yet. Then, onFeatureUnselect event is triggered, and popup is actually closed.
When you create popup by showMyPopup() function, you are not selecting it. onPopupClose() is called, but it doesn't close popup. onFeatureUnselect is not triggered.
I suggest to select feature in showMyPopup() function. featureselected event will be fired and popup is created by onFeatureSelect(), and user can close popup both with popup's Close icon and unselecting feature on map.
But alas, there's a possible bug (or unexpected behaviour) in OL, when you select feature with code and try to unselect it with clickout. It's described here: http://lists.osgeo.org/pipermail/openlayers-users/2012-September/026349.html One possible fix is to set SelectControl.handlers.feature.lastFeature manually.
function showMyPopup(myID){
for(var a = 0; a < stations.features.length; a++){ //loop through all the features
var feature = stations.features[a];
if (feature.attributes.ID.value == myID) { //until it finds the one with the matching ID attribute
// select is your SelectFeature control
select.select(feature);
// Fix for unselect bug
select.handlers.feature.lastFeature = feature;
break;
}
}
}
I take a look in the OpenLayers sources and there is in Popup.js something like that ...
...
var closePopup = callback || function(e) {
this.hide();
OpenLayers.Event.stop(e);
};
OpenLayers.Event.observe(this.closeDiv, "touchend",
OpenLayers.Function.bindAsEventListener(closePopup, this));
OpenLayers.Event.observe(this.closeDiv, "click",
OpenLayers.Function.bindAsEventListener(closePopup, this));
...
It seems to me if you add your own closePopup function you need to call the hide function in your code.

Activate tooltip using onclick jQuery

I'm testing a tooltip plugin and it will display a tooltip on mouseover. I'm trying to make the tooltip appear with an onclick, which I'm struggling and need your help.
I'm currently using a jquery piece so it will activate a modal window, thanks to #pointy, when the links within the tooltip is clicked. Can something like this be included with jQuery?
Demo: http://jsbin.com/eliwa3
Here is the page code that calls the functionality and tooltip content
<script>
dw_Tooltip.defaultProps = {
sticky: true,
klass: 'tooltip',
showCloseBox: true,
klass: 'tooltip2', // class to be used for tooltips
closeBoxImage: 'http://www.google.com/apps/images/x.png',
wrapFn: dw_Tooltip.wrapSticky
};
dw_Tooltip.on_show = function() {
$(".modalPageWide").colorbox({
width:"800px",height:"610px",opacity:0.6,iframe:true
})
};
dw_Tooltip.content_vars = {
tooltip_popup: {
content: 'Click a link to continue' +
'<ul><li>Link 1</li>' +
'<li>Link 2</li>' +
'<li>Link 3</li>' +
'<li>Link 4</li></ul>',
klass: 'tip'
}
}
</script>
As shown below, when a link includes a reserved class "showTip", it will activate the tooltip on mouseover. Also included is a compound class (of my choice) that will call the tooltip content
Example
Here's the logic that makes the tooltip work: Tooltip logic
basically all you would need to do it something like
$('a.tooltip_popup').click(function(e){
e.preventDefault();//so link doesn't take you to where ever it's supposed to
//code that brings the tooltip up
});

Categories