Google maps marker custom context menu - javascript

I am trying to create a custom context menu for google maps that will only work if I click a marker but this context menu that I am using will display the context menu anywhere I click. I want to make the context menu specifically for the map marker.
HTML:
<div id="map" style="width:100%;height:500px"></div>
<div class="menu" id="menu">
<div class="menu-item"><i class="glyphicon glyphicon-file"></i>Manage files</div>
</div>
JS:
function myMap() {
var menuDisplayed = false;
var menuBox = null;
var myCenter = new google.maps.LatLng(51.508742,-0.120850);
var mapCanvas = document.getElementById("map");
var mapOptions = {center: myCenter, zoom: 5};
var map = new google.maps.Map(mapCanvas, mapOptions);
var marker = new google.maps.Marker({position:myCenter});
marker.setMap(map);
window.addEventListener("contextmenu", function() {
var left = arguments[0].clientX;
var top = arguments[0].clientY;
menuBox = document.getElementById("menu");
menuBox.style.left = left + "px";
menuBox.style.top = top + "px";
menuBox.style.display = "block";
arguments[0].preventDefault();
menuDisplayed = true;
}, false);
window.addEventListener("click", function() {
if(menuDisplayed == true){
menuBox.style.display = "none";
}
}, true);
}
CSS:
.menu {
width: 150px;
box-shadow: 3px 3px 5px #888888;
border-style: solid;
border-width: 1px;
border-color: grey;
border-radius: 2px;
position: fixed;
display: none;
}
.menu-item {
height: 20px;
background-color: white;
}
.menu-item:hover {
background-color: #6CB5FF;
cursor: pointer;
}

One option would be rather than capturing all the clicks on the window object, just capture rightclick on the marker, open your context menu, close it on clicks on the map.
marker.addListener("rightclick", function(e) {
for (prop in e) {
if (e[prop] instanceof MouseEvent) {
mouseEvt = e[prop];
var left = mouseEvt.clientX;
var top = mouseEvt.clientY;
menuBox = document.getElementById("menu");
menuBox.style.left = left + "px";
menuBox.style.top = top + "px";
menuBox.style.display = "block";
mouseEvt.preventDefault();
menuDisplayed = true;
}
}
});
map.addListener("click", function(e) {
if (menuDisplayed == true) {
menuBox.style.display = "none";
}
});
proof of concept fiddle
code snippet:
function myMap() {
var menuDisplayed = false;
var menuBox = null;
var myCenter = new google.maps.LatLng(51.508742, -0.120850);
var mapCanvas = document.getElementById("map");
var mapOptions = {
center: myCenter,
zoom: 5
};
var map = new google.maps.Map(mapCanvas, mapOptions);
var marker = new google.maps.Marker({
position: myCenter
});
marker.setMap(map);
marker.addListener("rightclick", function(e) {
for (prop in e) {
if (e[prop] instanceof MouseEvent) {
mouseEvt = e[prop];
var left = mouseEvt.clientX;
var top = mouseEvt.clientY;
menuBox = document.getElementById("menu");
menuBox.style.left = left + "px";
menuBox.style.top = top + "px";
menuBox.style.display = "block";
mouseEvt.preventDefault();
menuDisplayed = true;
}
}
});
map.addListener("click", function(e) {
if (menuDisplayed == true) {
menuBox.style.display = "none";
}
});
}
google.maps.event.addDomListener(window, "load", myMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
.menu {
width: 150px;
box-shadow: 3px 3px 5px #888888;
border-style: solid;
border-width: 1px;
border-color: grey;
border-radius: 2px;
position: fixed;
display: none;
}
.menu-item {
height: 20px;
background-color: white;
}
.menu-item:hover {
background-color: #6CB5FF;
cursor: pointer;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>
<div class="menu" id="menu">
<div class="menu-item"><i class="glyphicon glyphicon-file"></i>Manage files</div>
</div>

Related

onmouseup event does not work correctly to the slider

I have created a simle JS slider that reacts to the click by eventListener onmousedown. But if you will run the code below, you will see, that the toddler does not stop correctly by the eventListener onmouseup if we leave the scroll zone scrollContainer with holding the left mouse button. The toddler will scroll loosely under we will click directly on the him.
What is needed - the toddler must stop when we will release the left mouse button (after end eventListener onmousedown).
I will be grateful for help.
var scrollLine = document.getElementById('scrollBar');
var scrollTog = document.getElementById('toddler');
function letsMove(event) {
var coordsHelp = getRealCoords(toddler);
var shiftX = event.pageX - coordsHelp.left;
getCoords(event);
function getRealCoords(toddler) {
var box = toddler.getBoundingClientRect();
return {
left: box.left + pageXOffset
}
};
function getCoords(event) {
var currentPosition = event.pageX - shiftX;
if (currentPosition >= 300) {
toddler.style.left = 300 + 'px';
} else if (currentPosition <= 104) {
toddler.style.left = 104 + 'px';
} else {
toddler.style.left = currentPosition + 'px';
}
};
scrollContainer.onmousemove = function(event) {
getCoords(event);
console.log();
};
toddler.ondragstart = function() {
return false;
};
toddler.onmouseup = function() {
scrollContainer.onmousemove = null;
scrollContainer.onmouseup = null;
toddler.onmouseup = null;
toddler.onmousemove = null;
return false;
};
}
toddler.addEventListener( 'mousedown', letsMove );
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#scrollContainer {
width: 400px;
height: 200px;
border: 1px solid grey;
border-radius: 4px;
}
#scrollBar {
width: 200px;
height: 5px;
background-color: grey;
border: 1px solid grey;
border-radius: 4px;
margin-top: 24%;
margin-left: 24%;
}
#toddler {
width: 10px;
height: 25px;
position: absolute;
margin-top: -11px;
background-color: blue;
border: 1px solid grey;
border-radius: 2px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="scrollContainer">
<div id="scrollBar">
<div id="toddler"></div>
</div>
</div>
<script>
</script>
</body>
</html>
The fix for this is almost embarrassingly simple. The reason you're not getting the onmouseup fired when the mouse isn't over the "toddler" is quite literally because the mouse isn't over the "toddler". (mouse events won't fire for objects that the mouse pointer is not touching).
Simply change the listener to the entire window (in "real" code you may want to add a guard so that you're aware of which slider is expecting the mouse up).
var scrollLine = document.getElementById('scrollBar');
var scrollTog = document.getElementById('toddler');
function letsMove(event) {
var coordsHelp = getRealCoords(toddler);
var shiftX = event.pageX - coordsHelp.left;
getCoords(event);
function getRealCoords(toddler) {
var box = toddler.getBoundingClientRect();
return {
left: box.left + pageXOffset
}
};
function getCoords(event) {
var currentPosition = event.pageX - shiftX;
if (currentPosition >= 300) {
toddler.style.left = 300 + 'px';
} else if (currentPosition <= 104) {
toddler.style.left = 104 + 'px';
} else {
toddler.style.left = currentPosition + 'px';
}
};
scrollContainer.onmousemove = function(event) {
getCoords(event);
console.log();
};
toddler.ondragstart = function() {
return false;
};
/* toddler.onmouseup = function() { */
window.onmouseup = function() {
scrollContainer.onmousemove = null;
scrollContainer.onmouseup = null;
toddler.onmouseup = null;
toddler.onmousemove = null;
return false;
};
}
toddler.addEventListener('mousedown', letsMove);
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#scrollContainer {
width: 400px;
height: 200px;
border: 1px solid grey;
border-radius: 4px;
}
#scrollBar {
width: 200px;
height: 5px;
background-color: grey;
border: 1px solid grey;
border-radius: 4px;
margin-top: 24%;
margin-left: 24%;
}
#toddler {
width: 10px;
height: 25px;
position: absolute;
margin-top: -11px;
background-color: blue;
border: 1px solid grey;
border-radius: 2px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="scrollContainer">
<div id="scrollBar">
<div id="toddler"></div>
</div>
</div>
<script>
</script>
</body>
</html>
One solution to this could be
Bind a mouseout event to a specific targetted region and as soon the mouse goes out of that region you should manually trigger or in javascript we should say dispatch event mousedown and that should be bound to the outer slider container so that having multiple sliders on a single page won't affect each other. As soon as you range out of the container the mouseout event will dispatch the toddler mousedown event.
A sample code for preventing the mouseout to trigger if a child element is hovered is taken from here, see your slider below.
var scrollContainer = document.getElementById('scrollContainer');
var scrollLine = document.getElementById('scrollBar');
var toddler = document.getElementById('toddler');
function letsMove(event) {
var coordsHelp = getRealCoords(toddler);
var shiftX = event.pageX - coordsHelp.left;
getCoords(event);
function getRealCoords(toddler) {
var box = toddler.getBoundingClientRect();
return {
left: box.left + pageXOffset
}
};
function getCoords(event) {
var currentPosition = event.pageX - shiftX;
if (currentPosition >= 300) {
toddler.style.left = 300 + 'px';
} else if (currentPosition <= 104) {
toddler.style.left = 104 + 'px';
} else {
toddler.style.left = currentPosition + 'px';
}
};
scrollContainer.onmousemove = function(event) {
getCoords(event);
console.log();
};
toddler.ondragstart = function() {
return false;
};
toddler.onmouseup = function() {
scrollContainer.onmousemove = null;
scrollContainer.onmouseup = null;
toddler.onmouseup = null;
toddler.onmousemove = null;
return false;
};
}
function makeMouseOutFn(elem) {
var list = traverseChildren(elem);
return function onMouseOut(event) {
var e = event.toElement || event.relatedTarget;
if (!!~list.indexOf(e)) {
return;
}
// handle mouse event here!
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.initEvent('mousedown', false, true);
toddler.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.eventType = 'mousedown';
toddler.fireEvent('on' + e.eventType, e);
}
};
}
//quick and dirty BFS children traversal, Im sure you could find a better one
function traverseChildren(elem) {
var children = [];
var q = [];
q.push(elem);
while (q.length > 0) {
var elem = q.pop();
children.push(elem);
pushAll(elem.children);
}
function pushAll(elemArray) {
for (var i = 0; i < elemArray.length; i++) {
q.push(elemArray[i]);
}
}
return children;
}
toddler.addEventListener('mousedown', letsMove);
scrollContainer.addEventListener('mouseout', makeMouseOutFn(scrollContainer), true);
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#scrollContainer {
width: 400px;
height: 200px;
border: 1px solid grey;
border-radius: 4px;
}
#scrollBar {
width: 200px;
height: 5px;
background-color: grey;
border: 1px solid grey;
border-radius: 4px;
margin-top: 24%;
margin-left: 24%;
}
#toddler {
width: 10px;
height: 25px;
position: absolute;
margin-top: -11px;
background-color: blue;
border: 1px solid grey;
border-radius: 2px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="scrollContainer">
<div id="scrollBar">
<div id="toddler"></div>
</div>
</div>
</body>
</html>

How to control zoom after search has been executed?

When I search for an address on this map it zooms in too much where the map is not useful. I have tried adjusting the map bounds, but it did not help. I think I am on the right path, but Its just not working. Can someone help me fix this?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<style>
#googft-mapCanvas {
height: 600px;
margin: 0;
padding: 0;
width: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Enter your address here">
<div id="googft-mapCanvas"></div>
<script>
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) || (navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '100%' : '1000px';
mapDiv.style.height = isMobile ? '100%' : '300px';
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(38.64936217820852, -90.53628850000001),
zoom: 9,
mapTypeId: google.maps.MapTypeId.HYBRID
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: {
enabled: false
},
query: {
select: "col26",
from: "11Q0B7iRayT2JIOBl8_VRUmitimhX1W01byuFDnAv",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function () {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function () {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
var marker = new google.maps.Marker({
position: new google.maps.LatLng(38.64936217820852, -90.53628850000001),
map: map,
draggable: true,
title: "Your New Home",
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
}
else {
bounds.extend(place.geometry.location);
}
// now let's move the marker
marker.setPosition(place.geometry.location);
});
map.fitBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
</body>
</html>
in you code, you use map.fitBounds(bounds);, which bounds is the place.geometry.viewport returned from the search result, which by default zoom in as much as it can. Instead, you want to pan to the new location, which save your current zoom level. Look at this jsfiddle demo for more information.

Google Maps Marker does not move with search

I have created a map, and when I search for an address in the input box, my marker does not move to my new location.
I have added this thinking that it will solve my problem, but I guess I do not understand exactly what this snippet is doing
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
This is the full HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<style>
#googft-mapCanvas {
height: 500px;
margin: 0;
padding: 0;
width: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Enter your address here">
<div id="googft-mapCanvas"></div>
<script>
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) || (navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '100%' : '1000px';
mapDiv.style.height = isMobile ? '100%' : '300px';
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(38.64936217820852, -90.53628850000001),
zoom: 9,
mapTypeId: google.maps.MapTypeId.HYBRID
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: {
enabled: false
},
query: {
select: "col26",
from: "11Q0B7iRayT2JIOBl8_VRUmitimhX1W01byuFDnAv",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function () {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function () {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
var marker = new google.maps.Marker({
position: new google.maps.LatLng(38.64936217820852, -90.53628850000001),
map: map,
draggable: true,
title: "Your New Home",
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
marker.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
</body>
</html>
Can someone please help me to fix this problem?
Like this.
I deleted some code that wasn't doing anything. Moving the marker, is this code, at the bottom: marker.setPosition(place.geometry.location);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<style>
#googft-mapCanvas {
height: 500px;
margin: 0;
padding: 0;
width: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Enter your address here">
<div id="googft-mapCanvas"></div>
<script>
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) || (navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '100%' : '1000px';
mapDiv.style.height = isMobile ? '100%' : '300px';
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(38.64936217820852, -90.53628850000001),
zoom: 9,
mapTypeId: google.maps.MapTypeId.HYBRID
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: {
enabled: false
},
query: {
select: "col26",
from: "11Q0B7iRayT2JIOBl8_VRUmitimhX1W01byuFDnAv",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function () {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function () {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
var marker = new google.maps.Marker({
position: new google.maps.LatLng(38.64936217820852, -90.53628850000001),
map: map,
draggable: true,
title: "Your New Home",
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
}
else {
bounds.extend(place.geometry.location);
}
// now let's move the marker
marker.setPosition(place.geometry.location);
});
map.fitBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
</body>
</html>

How can i make it follow my exact location using geolocation?

i need to make a restaurant finder.. but to do that i need to be able to locate my users.. i have been having a hard time figuring out on how to geolocate them and pinpoint their location on the map and find restaurants near them..please help me.. i am new to this
First js code
var map, places, iw;
var markers = [];
var searchTimeout;
var centerMarker;
var autocomplete;
var hostnameRegexp = new RegExp('^https?://.+?/');
function initialize() {
var myLatlng = new google.maps.LatLng(37.786906, -122.410156);
var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
places = new google.maps.places.PlacesService(map);
google.maps.event.addListener(map, 'tilesloaded', tilesLoaded);
document.getElementById('keyword').onkeyup = function(e) {
if (!e) var e = window.event;
if (e.keyCode != 13) return;
document.getElementById('keyword').blur();
search(document.getElementById('keyword').value);
}
var typeSelect = document.getElementById('type');
typeSelect.onchange = function() {
search();
};
var rankBySelect = document.getElementById('rankBy');
rankBySelect.onchange = function() {
search();
};
}
function tilesLoaded() {
search();
google.maps.event.clearListeners(map, 'tilesloaded');
google.maps.event.addListener(map, 'zoom_changed', searchIfRankByProminence);
google.maps.event.addListener(map, 'dragend', search);
}
function searchIfRankByProminence() {
if (document.getElementById('rankBy').value == 'prominence') {
search();
}
}
function search() {
clearResults();
clearMarkers();
if (searchTimeout) {
window.clearTimeout(searchTimeout);
}
searchTimeout = window.setTimeout(reallyDoSearch, 500);
}
function reallyDoSearch() {
var type = document.getElementById('type').value;
var keyword = document.getElementById('keyword').value;
var rankBy = document.getElementById('rankBy').value;
var search = {};
if (keyword) {
search.keyword = keyword;
}
if (type != 'establishment') {
search.types = [type];
}
if (rankBy == 'distance' && (search.types || search.keyword)) {
search.rankBy = google.maps.places.RankBy.DISTANCE;
search.location = map.getCenter();
centerMarker = new google.maps.Marker({
position: search.location,
animation: google.maps.Animation.DROP,
map: map
});
} else {
search.bounds = map.getBounds();
}
places.search(search, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var icon = 'number_' + (i + 1) + '.png';
markers.push(new google.maps.Marker({
position: results[i].geometry.location,
animation: google.maps.Animation.DROP,
icon: icon
}));
google.maps.event.addListener(markers[i], 'click', getDetails(results[i], i));
window.setTimeout(dropMarker(i), i * 100);
addResult(results[i], i);
}
}
});
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
if (centerMarker) {
centerMarker.setMap(null);
}
}
function dropMarker(i) {
return function() {
if (markers[i]) {
markers[i].setMap(map);
}
}
}
function addResult(result, i) {
var results = document.getElementById('results');
var tr = document.createElement('tr');
tr.style.backgroundColor = (i % 2 == 0 ? '#F0F0F0' : '#FFFFFF');
tr.onclick = function() {
google.maps.event.trigger(markers[i], 'click');
};
var iconTd = document.createElement('td');
var nameTd = document.createElement('td');
var icon = document.createElement('img');
icon.src = 'number_' + (i + 1) + '.png';
icon.setAttribute('class', 'placeIcon');
icon.setAttribute('className', 'placeIcon');
var name = document.createTextNode(result.name);
iconTd.appendChild(icon);
nameTd.appendChild(name);
tr.appendChild(iconTd);
tr.appendChild(nameTd);
results.appendChild(tr);
}
function clearResults() {
var results = document.getElementById('results');
while (results.childNodes[0]) {
results.removeChild(results.childNodes[0]);
}
}
function getDetails(result, i) {
return function() {
places.getDetails({
reference: result.reference
}, showInfoWindow(i));
}
}
function showInfoWindow(i) {
return function(place, status) {
if (iw) {
iw.close();
iw = null;
}
if (status == google.maps.places.PlacesServiceStatus.OK) {
iw = new google.maps.InfoWindow({
content: getIWContent(place)
});
iw.open(map, markers[i]);
}
}
}
function getIWContent(place) {
var content = '';
content += '<table>';
content += '<tr class="iw_table_row">';
content += '<td style="text-align: left"><img class="hotelIcon" src="' + place.icon + '"/></td>';
content += '<td><b>' + place.name + '</b></td></tr>';
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Address:</td><td>' + place.vicinity + '</td></tr>';
if (place.formatted_phone_number) {
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Telephone:</td><td>' + place.formatted_phone_number + '</td></tr>';
}
if (place.rating) {
var ratingHtml = '';
for (var i = 0; i < 5; i++) {
if (place.rating < (i + 0.5)) {
ratingHtml += '✩';
} else {
ratingHtml += '✭';
}
}
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Rating:</td><td><span id="rating">' + ratingHtml + '</span></td></tr>';
}
if (place.website) {
var fullUrl = place.website;
var website = hostnameRegexp.exec(place.website);
if (website == null) {
website = 'http://' + place.website + '/';
fullUrl = website;
}
content += '<tr class="iw_table_row"><td class="iw_attribute_name">Website:</td><td>' + website + '</td></tr>';
}
content += '</table>';
return content;
}
google.maps.event.addDomListener(window, 'load', initialize);
<!-- begin snippet: js hide: false -->
html {
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(superb-seaside-restaurant-hd-wallpaper-506329.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
background-size: cover
}
#form {
font: 20px"Walkway SemiBold";
letter-spacing: 5px;
text-align: center;
padding-bottom: 3px;
padding-right: 4px;
padding-top: 3px;
height: 35%;
width: 50%;
background: #ccc;
margin-bottom: 10px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
float: left;
}
#header {
font: 20px"Josefin Slab";
letter-spacing: 10px;
background-color: #fff;
color: #000;
text-align: center;
margin-top: 3px;
padding: 5px;
width: 1255px;
background: #ccc;
margin-bottom: 10px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
}
#map_canvas {
-webkit-box-shadow: 0 0 10px #bfdeff;
-moz-box-shadow: 0 0 5px #bfdeff;
box-shadow: 0 0 7px #bfdeff;
float: right;
height: 500px;
width: 593px;
padding: 10px;
margin-right: 3px;
vertical-align: top;
}
#listing {
font: 18pt"Nilland";
letter-spacing: 5px;
text-align: center;
padding: 3px;
height: 500px;
width: 50%;
background: #ccc;
margin-bottom: 10px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
float: left;
}
#footer {
font: 18px"Nilland-Black";
letter-spacing: 10px;
background-color: #fff;
color: #000;
text-align: right;
padding: 5px;
height: 27px;
width: 1255px;
background: #ccc;
margin-top: 3px;
margin-bottom: 3px;
/* Fallback for older browsers without RGBA-support */
background: rgba(204, 204, 204, 0.5);
float: right;
}
.placeIcon {
width: 32px;
height: 37px;
margin: 4px;
}
.hotelIcon {
width: 24px;
height: 24px;
}
#resultsTable {
font: 16pt"Nilland-Black";
border-collapse: collapse;
width: 450px;
margin-left: 90px;
float: left;
background: rgba(204, 204, 204, 0.5);
}
#rating {
font-size: 13px;
font-family: Arial Unicode MS;
}
#keywordsLabel {
text-align: right;
width: 70px;
font-size: 14px;
padding: 4px;
position: absolute;
}
.iw_table_row {
height: 18px;
}
.iw_attribute_name {
font-weight: bold;
text-align: right;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Map</title>
<link href="working.css" rel="stylesheet" type="text/css" />
<script src="http://maps.google.com/maps/api/js?sensor=true&libraries=places"></script>
<script src="C:\Users\beesumbernice\Documents\html\html\whole.js"></script>
<script src="C:\Users\beesumbernice\Documents\html\html\this.js"></script>
</head>
<body>
<div id="header">
<h1>
HEADER
</h1>
</div>
<div id="form">
Keywords:
<input id="keyword" type="text" placeholder="Mexican,Italian,Chinese..." />
<div id="controls">
<span id="typeLabel">
Type:
</span>
<select id="type">
<option value="bar">Bars</option>
<option value="cafe">Cafe</option>
<option value="restaurant" selected="selected">Restaurants</option>
</select>
<span id="rankByLabel">
Rank by:
</span>
<select id="rankBy">
<option value="prominence">Prominence</option>
<option value="distance" selected="selected">Distance</option>
</select>
</div>
</div>
<div id="map_canvas"></div>
<div id="listing" style="overflow-y: scroll; height:453px;">
<table id="resultsTable">
<tbody id="results"></tbody>
</table>
</div>
<div id="footer">
Maps Icons Collection
<img src="C:\Users\beesumbernice\Documents\html\html\desktop\powered-by-google-on-non-white.png" height="16" width="104"></img>
</div>
</body>
</html>
Hope this code will help you out
var mapInterval;
if(navigator.geolocation) {
var intervalTime = 5; // 5 seconds inteerval
mapInterval = window.setInterval(function(){
navigator.geolocation.getCurrentPosition(function(position) {
map.setCenter(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
}, intervalTime*1000)
});
// Whenever you want to stop updating the location
// mapInterval
Try this:
<html>
<body>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script>
function initialize(){
var mapOptions =
{
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 8
};
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var lat=position.coords.latitude;
var lng=position.coords.longitude;
var geolocate = new google.maps.LatLng(lat, lng);
map.setCenter(geolocate);
});
}
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<div id="map-canvas" style="width:300;height:300px;border:1px solid black;"> </div>
</body>
</html>
Check it out "HERE"

google places api autocomplete - adding click event

I'm appending a Search Results to the google places javascript api autocomplete.
So far I'm doing this:
var autocomplete;
function initialize() {
var myLatlng = new google.maps.LatLng(40.738793, -73.991402);
autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'));
}
later on I have this:
$('.pac-container').append( '<div class="j-search pac-item-refresh">Search Results</div>' );
$(document.body).on('click', '.pac-container .j-search', function(e) {
console.log('click fired');
});
The problem? The click event never fires...
Any idea why? Anything wrong with my code?
It seems that the click-event for .pac-container is cancelled by the Autocomplete-instance. Use mousedown instead.
You can follow the this article.
Implement and Optimize Autocomplete with Google Places API
Specifically Autocompletion using the AutocompleteService:
link: JS Filddle Of AutocompletionService
function debounce(func, wait, immediate) {
let timeout;
return function() {
let context = this,
args = arguments;
let later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
function initAutocomplete() {
let map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 48,
lng: 4
},
zoom: 4,
disableDefaultUI: true
});
// Create the search box and link it to the UI element.
let inputContainer = document.querySelector('autocomplete-input-container');
let autocomplete_results = document.querySelector('.autocomplete-results');
let service = new google.maps.places.AutocompleteService();
let serviceDetails = new google.maps.places.PlacesService(map);
let marker = new google.maps.Marker({
map: map
});
let displaySuggestions = function(predictions, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
let results_html = [];
predictions.forEach(function(prediction) {
results_html.push(`<li class="autocomplete-item" data-type="place" data-place-id=${prediction.place_id}><span class="autocomplete-icon icon-localities"></span> <span class="autocomplete-text">${prediction.description}</span></li>`);
});
autocomplete_results.innerHTML = results_html.join("");
autocomplete_results.style.display = 'block';
let autocomplete_items = autocomplete_results.querySelectorAll('.autocomplete-item');
for (let autocomplete_item of autocomplete_items) {
autocomplete_item.addEventListener('click', function() {
let prediction = {};
const selected_text = this.querySelector('.autocomplete-text').textContent;
const place_id = this.getAttribute('data-place-id');
let request = {
placeId: place_id,
fields: ['name', 'geometry']
};
serviceDetails.getDetails(request, function(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var bounds = new google.maps.LatLngBounds();
marker.setPosition(place.geometry.location);
if (place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
}
autocomplete_input.value = selected_text;
autocomplete_results.style.display = 'none';
});
})
}
};
let autocomplete_input = document.getElementById('my-input-autocomplete');
autocomplete_input.addEventListener('input', debounce(function() {
let value = this.value;
value.replace('"', '\\"').replace(/^\s+|\s+$/g, '');
if (value !== "") {
service.getPlacePredictions({
input: value
}, displaySuggestions);
} else {
autocomplete_results.innerHTML = '';
autocomplete_results.style.display = 'none';
}
}, 150));
}
document.addEventListener("DOMContentLoaded", function(event) {
initAutocomplete();
});
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.autocomplete-input-container {
position: absolute;
z-index: 1;
width: 100%;
}
.autocomplete-input {
text-align: center;
}
#my-input-autocomplete {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
font-size: 15px;
border-radius: 3px;
border: 0;
margin-top: 10px;
width: 290px;
height: 40px;
text-overflow: ellipsis;
padding: 0 1em;
}
#my-input-autocomplete:focus {
outline: none;
}
.autocomplete-results {
margin: 0 auto;
right: 0;
left: 0;
position: absolute;
display: none;
background-color: white;
width: 320px;
padding: 0;
list-style-type: none;
margin: 0 auto;
border: 1px solid #d2d2d2;
border-top: 0;
box-sizing: border-box;
}
.autocomplete-item {
padding: 5px 5px 5px 35px;
height: 26px;
line-height: 26px;
border-top: 1px solid #d9d9d9;
position: relative;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.autocomplete-icon {
display: block;
position: absolute;
top: 7px;
bottom: 0;
left: 8px;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-position: center center;
}
.autocomplete-icon.icon-localities {
background-image: url(https://images.woosmap.com/icons/locality.svg);
}
.autocomplete-item:hover .autocomplete-icon.icon-localities {
background-image: url(https://images.woosmap.com/icons/locality-selected.svg);
}
.autocomplete-item:hover {
background-color: #f2f2f2;
cursor: pointer;
}
.autocomplete-results::after {
content: "";
padding: 1px 1px 1px 0;
height: 18px;
box-sizing: border-box;
text-align: right;
display: block;
background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3_hdpi.png);
background-position: right;
background-repeat: no-repeat;
background-size: 120px 14px
}
<div class="autocomplete-input-container">
<div class="autocomplete-input">
<input id="my-input-autocomplete" placeholder="AutocompleteService" autocomplete="off" role="combobox">
</div>
<ul class="autocomplete-results">
</ul>
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback"></script>

Categories