Using Bootstrap's popover plugin inside a Javascript string - javascript

I'm trying to make the popover plugin work inside a Javascript string. So when a user mouse-overs geolocation the popover will appear, and disappear when the mouse is taken away.
<script type="text/javascript">
$('#directions-panel').text("We can't give you directions to our office as you don't have", <a href="#" rel="popover" data-content="Some content..." data-original-title="Some title..." > geolocation </a> " enabled on your browser. Enable geolocation and try again. The map above will show you where our office is located.");
</script>
And invoked using something like this??
$("[rel=popover]")
.popover({
offset: 10
})
.mouseover(function(e) {
e.preventDefault()
})
I know it's a bit all over place, but I've searched around and can't find anything similar to what I want to do. I'm sure it can be done, anyone point me in the right direction?
EDIT:
I know have the following in contact page:
<div id="directions-panel">
<div id="directions-error-message" style="visibility:hidden">
We can't give you directions to our office as you don't have <a href="#" id="geoloc-popover" rel="popover" data-content="Some content..." data-original-title="Some title..." > geolocation </a> enabled on your browser. Enable geolocation and try again. The map above will show you where our office is located.
</div>
</div>
and DIV directions-error-message is made visible when the following JS function failure() fires:
function failure() {
alert("Your browser does not have geolocation enabled so we can't give you directions to our office. Enable geolocation and try again, or consult the map for our address.");
$("#directions-error-message").css({
visibility: 'visible'
});
var destMapOptions = {
zoom:15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(ourLocation.lat, ourLocation.lng)
}
map = new google.maps.Map(document.getElementById("map-canvas"), destMapOptions);
marker = new google.maps.Marker({
position: ourLatLng,
map: map,
draggable: false,
animation: google.maps.Animation.DROP,
title: "Hello"
});
google.maps.event.addListener(marker, 'click', toggleBounce);
}
$(function() {
$('#directions-error-message').popover({
selector: '[rel="popover"]',
trigger: 'hover'
});
})
Is there a way to just make 'geolocation' in the directions-error-message DIV trigger the popover?

Why not try something like this instead:
<div style="visibility:hidden">
We can't give you directions to our office as you don't have", <a href="#" rel="popover" data-content="Some content..." data-original-title="Some title..." > geolocation </a> " enabled on your browser. Enable geolocation and try again. The map above will show you where our office is located.
</div>
Then change the visibility of the div with javascript. That way the jQuery setting the title will recognize the link but the user doesn't see it until you want them to.

Twitter Bootstrap's Popover plugin does have an option to enable its data-api to trigger toggling popovers. Enabling it will make all dynamically added elements with the proper markup work without further initialization calls in JavaScript.
The feature is disabled by default mostly because subscribing to all the mouseenter and mouseleave events on a page could pose performance issues (which is the default in TBS < 2.1). If you can keep the activated area relatively specific, you should be fine performance-wise.
To enable it just for the #directions-panel on hover, the syntax would be:
$('#directions-panel').popover({selector: '[rel="popover"]', trigger: 'hover'});
All subsequent updates to the panel which include popovers will then be active by default.

Related

How to add class to HTML element on marker click with Leaflet JS

So, I'm trying to show a modal when a marker is clicked as a part of my Leaflet app. I already have some of the click functionality set on my marker layer, but I seem to be failing in triggering the necessary class being added to the modal element.
Currently I have a modal div with the following HTML outside of my map div.:
<div class="modal" id="infoBox">
<div class="modal-dialog">
<header class="modal-header"><button class="close-modal" aria-label="close modal" data-close> X</button></header>
<p>
<section class="modal-content">
Address: <span id="street"></span><br/>
Neighborhood: <span id="suburb"></span><br/>
City: <span id="city"></span><br/>
Piece Type: <span id="type"></span><br/>
Description: <span id="desc"></span><br/>
</p>
</section>
<footer class="modal-footer"></footer>
</div>
</div>
I am trying to add the class with the following function:
function zoomToFeature(e) {
var latLngs = [e.target.getLatLng()];
var markerBounds = L.latLngBounds(latLngs);
var street = e.target.feature.properties.str_addr;
var city = e.target.feature.properties.city;
var desc = e.target.feature.properties.desc;
document.getElementById('street').textContent = street;
document.getElementById('city').textContent = city;
document.getElementById('desc').textContent = desc;
mymap.fitBounds(markerBounds);
mymap.fitBounds(e.target.getBounds());
document.getElementById('infoBox').classList.add('is-visible');
}
Which I add the click listener on the layer with the onEachFeature function like so:
function onEachFeature(feature, layer){
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature,
});
}
When I manually add the .is-visible class the element I get the expected behaviour, but clicking the marker layer doesn't add the class. I'm basically trying to implement this Tutsplus Tutorial with some of the functionality in the Leaflet Chrolopleth tutorial. The click functionality works as far as pulling the feature info and zooming to the marker, but as above the modal stays hidden.
Running the classListAdd in a stand alone function in the dev console adds the class like so class="modal is-visible" but it doesn't trigger the functionality. As above manually changing the class to modal.is-visible does work, but I assume that's because it's an exact match for the css and it's not being re-interpreted.
Stripped down demo version can be seen here
The culprit is the line: e.target.getBounds()
When you click on a (Circle)Marker, e.target is that Marker. But Point features do not have such getBounds() method (since they represent a single point, not an area).
So your script fails with an error like:
Uncaught TypeError: e.target.getBounds is not a function
...and the rest of the event listener is not executed, in particular the following line where you show your modal (document.getElementById('infoBox').classList.add('is-visible'))
Since you already set the view around that Marker just before (mymap.fitBounds(markerBounds)), there is no need to that repeated call (maybe just a leftover of previous attempts?)
Removing that line restores your modal behaviour.
Fixed Plunkr: https://plnkr.co/edit/DfCKrJaNzM48dzuZ
Note: your Plunkr was not working because you forgot the call to your initMap() function.

How to show modal window on marker click?

I am using leafletjs to build a web map and trying to figure out how to show a modal window when a marker is clicked (instead of the default popup method).
Here's my setup:
var myAirports = L.geoJson(myData, {
pointToLayer: function(latlng){
..snip..
},
onEachFeature: function(feature,layer){
$('#myModalOne').modal(options);
}
});
myAirports.addTo(map);
My HTML is like so:
<div id="myModalOne">....</div>
<div id="myModalTwo">....</div>
Lets say my data has a featurecollection with a key of 'name' (i.e., 'name': 'Bush Airport') for each feature. Would I just add a switch statement to my onEachFeature function?
Just need a little guidance,thanks.
Note: I am using Bootstrap for the modal windows
If I understand you correctly, you don't need to set the pointToLayer option which is useful if you want to display something else than a marker.
What you need is to catch the click event on the markers and display a modal window. There is no popup by default.
var myAirports = L.geoJson(myData, {
onEachFeature: function(feature,layer){
layer.on('click', function(e){
$('#myModal'+feature.properties.name).modal(options);
// or whatever that opens the right modal window
});
}
});
myAirports.addTo(map);

Google Maps (gmap3 plugin), fadeout overlay on click

I have a google map application built using the gmap3 plugin that draws dynamic overlays when a marker is clicked. I am trying to make a button inside the overlay to "dismiss" the overlay using this line from my script:
$('.dismiss-overlay').click(function() {
$(this).parent('div').fadeOut();
})
I have tested this and everything appears to function just fine when placed outside of the gmap overlay, but when inside the overlay clicking on the button causes nothing to happen. Below is the full script:
$("#map_canvas").gmap3({
map:{
options:{
streetViewControl: false,
mapTypeControl: false,
zoom: 0
}
},
marker:{
values: markers,
options:{
draggable: false,
icon: "files/map-marker.png"
},
events:{
click: function(marker, event, context) {
$(this).gmap3({
clear:"overlay",
overlay: {
latLng: marker.getPosition(),
options: {
content: '<div class="container overlay"><button class="btn btn-xs dismiss-overlay">x close</button>'+$("#"+context.data.id).html()+'</div>',
offset: {
y: -30,
x: 30
}
}
},
});
$(this).gmap3('get').panTo(marker.getPosition());
$(this).gmap3('get').panBy(150, 0);
}
}
},
autofit:{maxZoom: zoom},
});
});
if you need to see a working example: http://schaffner-publications.com/development/map/
Alright, I found the issue.
The thing is that you are creating your overlay dynamically and your event listener is registered during map.js file load. When user clicks 'More info' button on your sample page (http://schaffner-publications.com/development/map/), map is initialised and when user clicks on the marker its overlay is dynamically created and pushed to the page. Specially the close button div. Meaning browser doesn't know anything about the close button (or events on it) unless user clicks on a marker.
In short your event never gets fired because you registered events on .dismis-overlay divs that were available at the map.js load time (& there weren't any, as you create them dynamically).
So to resolve your issue try changing your map.js where you are setting overlay content to the following.
content: '<div class="container-fluid overlay"><button class="btn btn-xs dismiss-overlay" onclick="$(this).parent().toggle();">x close</button>'+$("#"+context.data.id).html()+'</div>',
I have added just below to your code:
onclick="$(this).parent().toggle();"
Not sure if there is specific reason for using gmap3 plugin. If I were you, I would use google map api without it, gives you more control. If you really need clustering, I would go for leaflet.
OLD ANSWER (See comments)
Instead of parent, just mention the id in the event:
$('.dismiss-overlay').click(function() {
$('#parkmap').modal('toggle');
})
On the other note, I tried fade-out and it just fades out the modal while the dark background still exists. Standard way of closing the modal will be to use toggle instead of fadeout.
Hope this helps. :)

Google Maps not correctly initialising within Angular directive

I am trying to use the Google Maps API to display a map within an Angular site but it appears to not initialise correctly.
My html page uses bootstrap nav nav-tabs and I use an Angular controller to switch between them.
<ul class="nav navbar-nav">
<li ng-class="{ active:myCtrl.isSet('map') }">
<a href ng-click="myCtrl.setTab('map')">Show Map</a>
</li>
</ul>
With one of the tabs containing only the google map canvas element - set up using an angular directive
Module.directive('mapPage', function() {
return {
restrict: 'E',
template: '<div id="map-canvas"></div>'
};
});
Within my angular controller I set up a listener for the window 'load' event to initialise the map as follows:
google.maps.event.addDomListener(window, 'load', myCtrl.initMap);
myCtrl.initMap = function() {
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(55.937879, -3.241619),
};
myCtrl.map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(55.937879, -3.241619),
map: myCtrl.map
});
myCtrl.map.setCenter(new google.maps.LatLng(55.937879, -3.241619));
}
What I see on screen is the map element showing a grey area with the location marker not centered correctly (it's just off screen).
If I move the map-canvas div to the main section of my index.html page (rather than a sub page within the app) it loads correctly, so I know my Google API js code and html is correct. The map also shows if the page is resized.
It just doesn't work when used on a page that is not rendered immediately. I have tried searching for similar questions/answers but could not find this particular issue.
I have created a simple fiddle that demonstrates the issue.
http://jsfiddle.net/johntough/nc0u7h2c/5/
Any help appreciated!
The issue is, you are loading Map on window load whereas the container will appear on click. Google Map has behavior (never seen documented yet but I have observed it many time though) that if the container is hidden on load, it does not load map in there. I changed your "load" to "click" and its working. The only change is as below,
google.maps.event.addDomListener(window, 'click', myCtrl.initMap);
See fiddle and verify yourself. http://jsfiddle.net/anandgh/nc0u7h2c/6/

Change Marker position + Replace close button

Please check this screenshot to understand completely the problem:
My first question is:
How could I move the InfoWindow lower near the pin itself? I tried with css, javascript, etc and I cannot seem to find a "non hacky" way of doing it.
My second question is:
Is there any way to close an InfoWindow from my custom InfoWindow? I know I can do infoWindow.close() but I don't think I have the InfoWindow instance from a jquery event (it's a normal InfoWindow but with custom html in it).
Any help will be greatly welcome :)
Thanks and have a nice day!
From the API on pixelOffset:
The offset, in pixels, of the tip of the info window from the point on the map at whose geographical coordinates the info window is anchored
For the second question, you don't want to use jQuery events to open the infowindow, instead you can use the content property of the options to set your custom html, then do something like this:
var myInfoWindow = new google.maps.InfoWindow({ content: 'customHTML',
//some mode options
})
google.maps.event.addListener(marker, 'click', function (event) {
if (myInfoWindow) {
myInfoWindow.close()
myInfoWindow.setPosition(event.latLng);
myInfoWindow.open(map, marker);
}
})

Categories

Resources