Positioning button inside leaflet layer control - javascript

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);
}
)};

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.

Javascript show div on load

I have some custom buttons overlayed on a Google Map. When you click on one of the buttons it slides the map div right 360px and slides in a 360px wide div on the left in the place where the map vacated. When I click the button on the map it works as designed and slides the map over and div in like it should and when you click the close button on the div it slides out of focus and the map goes back to where it was before.
My issue is I am trying to have this div that slides in to show on load. My solutions I have tried haven't quite worked and I am not great with Javascript. If I use CSS z-index 1 it will load when the page loads but it shows it on top of the map instead of the map sliding over 350px. So a CSS solution won't work in this case because the div overlays on the map instead of sliding it over and covers the map which has a logo in the top left corner.
This is how I open and close the div.
HTML
<button id="alertBtn" class="map__control_icon" onclick="openAlerts();"><i class="fa fa-exclamation-triangle"></i></button>
Javascript
function openAlerts() {
document.getElementById("alert-list").style.minWidth = "360px";
document.getElementById("map-wrapper").style.marginLeft = "360px";
document.getElementById("mapButtons").style.marginLeft = "-360px";
}
function closeAlerts() {
document.getElementById("alert-list").style.width = "0";
document.getElementById("map-wrapper").style.marginLeft= "0";
document.getElementById("mapButtons").style.marginLeft = "0";
}
So how can I have this show by default when the page loads but slide the map over like it does when you click the button? Also is there someway to get the width .style.marginLeft to auto so it slides over based on the size of the div that slides in as sometimes the content is dynamic but if I set a hard set margin then there is extra space when the div isn't filling the full width. Hench why "alert-list" is set with a minWidth.
-Thanks!
I was able to easily solve this by adding the follow to the top of my Javascript.
$(document).ready(openAlerts());
If you want pure JavaScript then use this
document.addEventListener('DOMContentLoaded', openAlerts, false);

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.

Google Plus & Javascript - Disable scrolling when choosing circles?

I've created a lot of Circles. And so when I hover over the "Add to Circles" google plus button, a small div pops up that allows me to vertically scroll through my circles.
The really cool part is that it disable body scrolling. So when I scroll to the bottom of the circles viewer, the body doesn't budge.
How is this possible with javascript?
(I've found a hacky way to do it:
$('body').css({'overflow':'hidden'});
$(document).bind('scroll',function () {
window.scrollTo(0,0);
});
But Google does it better. The body scroll bar stays in place (it doesn't vanish like my code makes it), and the body is still unscrollable...)
It's important to note (and so far overlooked) that the scroll bar on the body page has to stay in place. It can't vanish like overflow:hidden makes it, because that jerks all of the page content to the right. Google solves this problem somehow...
SCREENSHOT:
Try using :
$(document).bind('scroll',function (e) {
e.preventDefault();
e.stopPropagation();
return false;
});

Categories