Expanding“clickable” area for custom icons using Leaflet - javascript

I have a searchable Leaflet map. The green icons represent all of the existing data and when you search for an address it shows a blue pushpin icon.
I would expect to be able to click anywhere on my custom (blue pushpin) icon and get a popup as a result. But nothing happens when I click on it.
I have to click on a very specific spot in order to get the popup to activate. I can tell it's the right spot because my hover text (on the bottom left) changes. I want to make it so that the results pop up if I click anywhere on the custom icon (or even the original green icon).
I'm using a template, so I'm not completely sure which part of the code controls the hover actions or the "clickable" area, but I'm guessing it's this...?
var hover_template;
$.get( "./templates/hover.ejs", function( template ) {
hover_template = template;
});
SearchableMapLib.info.update = function (props) {
if (props) {
this._div.innerHTML = ejs.render(hover_template, {obj: props});
}
else {
this._div.innerHTML = 'Hover over a ' + SearchableMapLib.recordName;
}
};
SearchableMapLib.info.clear = function(){
this._div.innerHTML = 'Hover over a ' + SearchableMapLib.recordName;
};

From the source code of the framework / template you are using, it seems like the custom icon / blue pushpin is just a "center mark" of the geocoding result, without attached data. Hence the absence of hover and popup.
https://github.com/datamade/searchable-map-template-csv/blob/master/js/searchable_map_lib.js#L321-L329
On the contrary, the green icon Markers seem to be results of a 2nd search, based on the coordinates of the previous result and a fixed radius. They have this hover and click popup features. Hence you get them when on the green icon behind the blue pin.
Therefore it seems like what you experience is the expected behaviour, even though it can be strange when the blue pin matches one of the green icons.
If you expect a different behaviour, it seems to me that you should raise an issue on the repo of that framework / template.

Related

Opening modal where SVG map is clicked

Looking for best practise around a feature I'm looking to implement.
I have an SVG map, which contains little blue icons where a user can click, see image below for reference:
When a user clicks any of the blue icons, I'm looking to open a little modal by it that will showcase that regions info. For example, see the below screenshot:
So, in the above instance, the user has clicked on the blue circle on the bottom, which opens a little modal for that region.
Now, in my svg, I have added id's for each blue icon (<g class="mapLocations__icon" id="uk" ...">, but with this approach, the two options I see are:
Absolute positioning the modal for each region. But this sounds like a pain for responsive.
Writing repeat markup for the modal within the svg itself.
Neither seem like a good approach.
Any recommendations?
Here is my svg for reference: https://jsfiddle.net/6squyc7d/ (Added as jsfiddle as pasting the code puts me over the charachter limit)
In the onclick event you can use the x and y coordinates to absolute position the modal dynamically. So actually you could create and position the modal right on the onclick function.
function openModal( evt ) {
var intCoordX = evt.clientX;
var intCoordY = evt.clientY;
// Modify modal properties
// Open modal
}
For each dot, you have an Id. You can add an onclick listener to each dot with an forEach loop (all Ids in an array). You can then put this code into the forEach loop:
const dot = document.getElementById('canada')
dot.addEventListener('click', event => {
console.log(event.x, event.y)
});
In this code you get the dot with the Id (canada). Then you have the click event and you can see where the user clicked on their screen (x and y pixels).
Then you can place an absolute div with the top and left value.
.position {
position: absolute;
opacity: 0;
}
You can then with JS place the modal with top and left on the right position and set the opacity to 1;
It will make the div show on the correct place.

don't change mouse icon when hovering over a marker

I have a map with a number of markers. When a user clicks on one marker information for that marker is displayed on a side pane. To accomplish that I have added 'click' listeners to the markers and also store marker identifiers more or less as suggested in this SO answer.
Now, on certain modes I don't want the markers to be clickable (but still want them to appear on the screen). It is easy for me to remove all the 'click' listeners. However, when I hover over them with my mouse, the icon does change from the "open palm" to the "pointed hand" confusing the user. Upon investigating I see that the canvas class normally has the leaflet-zoom-animated class, but when I hover over a marker, the leaflet-interactive class gets added. I can change that cursor using, e.g.:
.leaflet-interactive {
cursor: crosshair !important;
}
... but this has two problems:
it's not something I can toggle on and off depending on the various user interaction modes my application finds itself in
it's still jarring because the cursor does change and, further, I can't change it to the open palm cursor that Leaflet is normally using, since that's a non-default cursor and it's not clear to me how to access it.
If you can remove the click listener, I suppose that you can also add a css class to your marker. Here is an example http://jsfiddle.net/Mossart/w9830at1/7/ (look at the top marker)
var breakside = [45.571601194035345, -122.65673562884331];
var marker1 = L.marker(breakside).addTo(map);
marker1._icon.classList.add("not-clickable");
CSS:
.not-clickable {
cursor: grab;
}
This works for L.circleMarker objects on a canvas renderer:
marker.options.interactive = false;
Curiously, it doesn't work on a non-canvas renderer.

After mouseup event, cursor turns back to default even though it's set to another icon. CSS, Javascript

I've looked everywhere and I can't seem to find why this is happening. I'm working on a Pixel art maker and I have a selection tool that selects table data in a table. After I click and drag the mouse to select the table data, on mouseup, even though the cursor is set to crosshair, it turns back to default cursor again. If I move the mouse even slightly on the table after that, it turns back to crosshair again. Needless to say, I do not want the mouse to turn back to default after releasing left-click. Does anyone know why this is happening?
Extra info:
Default cursor for the table is pointer.
After you click on the selection tool icon, the cursor for the table changes to crosshair.
Here is the javascript code for toggling the tool:
//Toggle selection tool
$(".tools").on('click', '#selectionTool', function () {
if (tool == 'selection') {
tool = 'pixel';
$('#pixelCanvas').css('cursor', 'pointer');
} else {
tool = 'selection';
$('#pixelCanvas').css('cursor', 'crosshair');
}
});

Positioning button inside leaflet layer control

I'm using the leaflet styled layer control plug in to customize my map control.
I'm trying to add a button to the top right corner of my controls that closes the controls (primarily for mobile use).
I found this question and it works, but now I'm wondering how I can position this button. I want it to be in the top right corner of the control.
When I position the class "leaflet-control-close" it works (I tested with "position: relative; float: right;" and it did float right but stayed at the bottom), but if I give it an absolute position at the top of the page it seems to be appear behind my overlays.
I want it to push down the overlays a little bit so that it doesn't overlap.
EDIT: here is a jsfiddle showing what's happening. It's a little convoluted because the styled layer control files don't have a CDN so I just pasted in the CSS and javascript. I made a note where I add the button in the original Javascript, and below that JS is the JS to create the map and overlays.
I know the button on a desktop is kind of annoying because when you close the control with it, it immediately pops back open because your mouse is hovering. In my actual code I've set the display to none if the screen width is larger than tablet size, because that's the only time I feel like I need the button.
I customized the styled layer control javascript in order to include the button:
L.Control.StyledLayerControl = L.Control.Layers.extend({
onAdd: function(map) {
this._initLayout();
this._update();
this._addButton();
map
.on('layeradd', this._onLayerChange, this)
.on('layerremove', this._onLayerChange, this);
return this._container;
},
_addButton: function () {
var elements = this._container.getElementsByClassName('leaflet-control-layers-list');
var button = L.DomUtil.create('button', 'layer-control-close', elements[0]);
button.innerText = 'Close control';
L.DomEvent.on(button, 'click', function(e){
L.DomEvent.stop(e);
this._collapse();
}, this);
}
)};

Leaflet marker popup extends past the map

I had to change the default size of the marker popup to accommodate the data I wanted to put in it. I changed some map settings so it always bounces back to a max bound when the user drags it out of view. The issue I have is that for markers close to the edge, when its popup opens, it is not fully visible, as in it hides behind the edges of the container for the map.
Q: What would be the fix to this? Can I get the popup to show the full content?
In this Leaflet tutorial they have an option to offset the popup anchor. You could do an if statement that if true would offset the popup anchor by enough to display properly on the screen.
Pseudo code:
if (latlng of point clicked < rightBounds of map) {
popupOptions = {
offset: (-popupwidth,0)
}
} ...
You could also try experimenting with the various popup options in the API.

Categories