I am trying to pass the address information that comes from a database and showing in a textbox (txAddress from SQL) to another textbox (txInputAddress GMap). In order to pass the value from txAddress to txInputAddress I needed to use an updatepanel. Here is how I coded it:
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div id="pac-container">
<asp:TextBox ID="txInputAddress" runat="server" placeholder="Enter a location" Width="415px" AutoPostBack="true" autocomplete="off"></asp:TextBox>
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnCopytToGoogleMaps" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
This is the JavaScript I am using from Google, which I modified in order to use a C# textbox to make it easier to pass the value from one textbox to another, as mentioned before.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 35.6145169, lng: -88.81394690000002 },
zoom: 13
});
var card = document.getElementById('pac-card');
var input = document.getElementById("txInputAddress");
var types = document.getElementById('type-selector');
var strictBounds = document.getElementById('strict-bounds-selector');
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
var infowindowContent = document.getElementById('infowindow-content');
infowindow.setContent(infowindowContent);
var marker = new google.maps.Marker({
map: map,
anchorPoint: new google.maps.Point(0, -29)
});
autocomplete.addListener('place_changed', function () {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
window.alert("No details available for input: '" + place.name + "'");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
infowindowContent.children['place-icon'].src = place.icon;
infowindowContent.children['place-name'].textContent = place.name;
infowindowContent.children['place-address'].textContent = address;
infowindow.open(map, marker);
});
// Sets a listener on a radio button to change the filter type on Places
// Autocomplete.
function setupClickListener(id, types) {
var radioButton = document.getElementById(id);
radioButton.addEventListener('click', function () {
autocomplete.setTypes(types);
});
}
setupClickListener('changetype-all', []);
setupClickListener('changetype-address', ['address']);
setupClickListener('changetype-establishment', ['establishment']);
setupClickListener('changetype-geocode', ['geocode']);
document.getElementById('use-strict-bounds')
.addEventListener('click', function () {
console.log('Checkbox clicked! New state=' + this.checked);
autocomplete.setOptions({ strictBounds: this.checked });
});
}
Here is an image of what I get. As you can see, it shows the address from txAddress to txInputAddress but then if you don't refresh the page, the autocomplete will not show up. Any idea what to do to solve this issue? In other words, I need to pass the address from txAddress to txInputAddress and show the autocomplete options.
After using the UpdatePanel, the browser has lost the controls and elements in the DOM. They have to be rebinded. So use the function below to call initMap every time the UpdatePanel is triggered.
<script type="text/javascript">
initMap();
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
initMap();
});
</script>
Related
Im trying to code a functionality so when I click on a certain location button that markers info window pops up. Ive got the code to console log the certain title and location of the marker, but when i try to call the infowindow in the viewmodel it comes up undefined. I know that the Infowindow is in the init function for google map, i cant seem to figure out how to open it from the viewmodel
and here is my code for the view model:
function viewModel() {
this.marker = locationArray().location;
this.openWindow = function(location){
if(this.marker){
console.log(this.marker);
};
}
}
and my click event:
google.maps.event.addListener(marker,'click', (function(marker){
return function() {
viewModel()
infoWindow.setContent("<div>" + marker.title + "</div>");
infoWindow.open( map, marker);
}
})(marker));
here is my google map api, hopefully this will help :
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.764117, lng: -72.676470},
zoom: 13,
styles: style
});
// Iterates through the locationArray and gives the marker a proper
// location.
for(var i = 0; i < locationArray().length; i++){
var locations = locationArray()[i].location;
var title = locationArray()[i].title;
var marker = new google.maps.Marker({
position: locations,
map: map,
title: title,
animation: google.maps.Animation.DROP
});
locationArray()[i].marker = marker;
var message = "hello world!";
var infoWindow = new google.maps.InfoWindow({
content: title,
position: locations
});
google.maps.event.addListener(marker,'click', (function(marker){
return function() {
viewModel();
infoWindow.setContent("<div>" + marker.title + "</div>");
infoWindow.open( map, marker);
}
})(marker));
};
};
ko.applyBindings(new viewModel());
You definition of marker in the ViewModel is ambiguous. You should in general define the observables inside the ViewModel.
function ViewModel(data) {
var self = this;
self.locations = ko.observableArray(data.locations || []);
self.showMarker(function(loc) { // bind this to click (in html)
loc.marker.showInfo(); // I'm not sure if loc.marker.click() would work
});
}
var locations = []; // your list of locations
ko.applyBindings( new ViewModel({locations: locations}) );
And you can bind the click event of your marker in a simpler way, that'll also help to easily call the
marker.showInfo = function() {
infoWindow.setContent("<div>" + this.title + "</div>");
infoWindow.open( map, this);
};
google.maps.event.addListener(marker,'click', marker.showInfo);
I have recently developed a website but I haven't been able to show the current location marker on the Google map after the location was found.
You can have a look on https://www.storra.com/listings/
I have added a custom listener to the function.php based on Listify auto-locate function but didn't manage to add the marker to the map. The code is as following,
function listify_custom_autolocation() {
if ( ! ( is_front_page() || listify_is_job_manager_archive() ) ) {
return;
}
?>
<script>
var triggered = false;
jQuery(document).on( 'facetwp-loaded', function() {
if ( ! triggered ) {
var locate = jQuery( '.locate-me' );
locate.trigger( 'click' );
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
parseFloat(coords[0]),
parseFloat(coords[1])
),
info: new google.maps.InfoWindow({
content: val.title + val.distance
})
});
}
triggered = true;
});
</script>
<?php
}
add_action( 'wp_footer', 'listify_custom_autolocation', 9999 );
Would very much appreciate if someone could guide me out.
Thank you!
You could use this one for your locate function:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var marker = new google.maps.Marker({
position: pos,
map: map,
title: 'Your position'
});
map.setCenter(pos);
}, function() {
//handle location error (i.e. if user disallowed location access manually)
});
} else {
// Browser doesn't support Geolocation
}
The following is the relevant code on the backend. I tried adding the code given by #mxlse but didn't seem to work too.
AutoLocateView.prototype.find = function() {
var cv, error, filters, success;
cv = this.collectionView;
filters = this.filters;
if (!navigator.geolocation) {
return;
}
success = function(position) {
var lat, lng;
lat = position.coords.latitude;
lng = position.coords.longitude;
cv.set({
'lat': lat,
'lng': lng
});
return $('.locate-me').removeClass('loading');
};
error = function() {
$('.locate-me').removeClass('loading');
return filters.startup();
};
navigator.geolocation.getCurrentPosition(success, error);
return this;
};
After searching for hours, I've come to the conclusion that I have to integrate reverse geocoding. However, I'm not sure how to integrate it into the gmaps.js. What I'm trying to accomplish is displaying the address instead of coordinates(lang,long) when the user clicks on "get directions"
<script>
var pinsPath = 'http://www.bohlerengineering.com/wp-content/themes/bohler/img/pins_map/';
var locations = new Array();
$(document).ready(function() {
console.log(locations);
placeMarkers(locations, false);
$('.locationButton').click(function(e){
$this=$(this);
currentId = $(this).attr('id').split('-')[1];
google.maps.event.trigger(mapsHelper.markers[currentId], 'click');
//mapsHelper.infoBubbles[currentId].open();
/** Forma anterior
mapsHelper.removeMarkers();
//mapsHelper.placeMarkerByAddress($(this).attr('rel'), function(lat, lng){
placeMarkers({'0': locations[$(this).attr('rel')]}, true); **/
e.preventDefault();
});
function placeMarkers(locations, popWindow){
for(key in locations){
var pinPath = pinsPath+locations[key]['state_abbrev'].toLowerCase()+'.png'
if(locations[key]['lat'] && locations[key]['lng']){
console.log('KEY COORD: '+key);
console.log('placed marker by coords');
var marker = mapsHelper.placeMarker(locations[key]['lat'], locations[key]['lng'], pinPath, locations[key]['id']);
//infoWindow = mapsHelper.addInfoWindow(marker, $('#info-'+locations[key]['id']).html());
infoBubble = mapsHelper.addInfoBubble(marker, $('#info-'+locations[key]['id']).html(), function(){
// setTimeout(function(){
// $('img[src="http://maps.gstatic.com/intl/en_us/mapfiles/iw_close.gif"]').attr('src', '/wp-content/themes/streetsenseV2/img/cruz_nav_active.png');
// }, 300);
});
if(popWindow){
console.log('Pop window!');
console.log(mapsHelper.map);
infoWindow.open(mapsHelper.map, marker);
}
}else{
console.log('KEY: '+key);
console.log('ID: '+locations[key]['id']);
mapsHelper.placeMarkerByAddress(locations[key]['rel'], key, pinPath, function(lat, lng, marker, key){
//console.log(locations);
console.log('KEY INSIDE: '+key);
//infoWindow = mapsHelper.addInfoWindow(marker, $('#info-'+locations[key]['id']).html());
infoBubble = mapsHelper.addInfoBubble(marker, $('#info-'+locations[key]['id']).html(), locations[key]['id'], function(){
// setTimeout(function(){
// $('img[src="http://maps.gstatic.com/intl/en_us/mapfiles/iw_close.gif"]').attr('src', '/wp-content/themes/streetsenseV2/img/cruz_nav_active.png');
// }, 300);
});
//if(popWindow) infoWindow.open(mapsHelper.map, marker);
if(popWindow) infoBubble.open(mapsHelper.map, marker);
console.log('Save location coords: '+locations[key]['id']);
$.get('/wp-content/themes/bohler/ajax/locate.php?id='+locations[key]['id']+'&lat='+lat+'&lng='+lng);
});
}
}
}
})
</script>
Here's the site I'm working on. When you click on a icon on a location, it should display 'get directions. When I click on that it sends me to a different page that displays the directions by coordinates(longitude,latitude) instead of address.
http://www.bohlereng.com/locations/
The goal
Reuse already loaded JavaScript correctly.
The problem
I'm generating a map dynamically using Google Maps API V3 and I need to reuse it. How?
The scenario
On Index.html, there's the following script:
var gMapsLoaded = false;
window.gMapsCallback = function () {
gMapsLoaded = true;
$(window).trigger('gMapsLoaded');
}
window.loadGoogleMaps = function () {
if (gMapsLoaded) return window.gMapsCallback();
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
"http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0]
|| document.documentElement).appendChild(script_tag);
}
When I click on some button to show the map, my app invokes this script:
[...]
var geocoder;
var map;
var address = context.address();
function initialize() {
var mapDiv = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 15,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions:
{ style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(mapDiv, myOptions);
if (geocoder) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
map.setCenter(results[0].geometry.location);
var infowindow = new google.maps.InfoWindow(
{
content: '<b>' + address + '</b>',
size: new google.maps.Size(150, 50)
});
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: address
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
} else {
alert("No results found");
}
} else {
alert
("Geocode was not successful
for the following reason: " + status);
}
});
}
gMapsLoaded = false;
}
$(window).on('gMapsLoaded', initialize);
window.loadGoogleMaps();
As you can see, the application is always calling the loadGoogleMaps(); function that calls the external .js file. If I click in the 5 different maps, I get 5 scripts with the same proposal.
Someone have any idea to solve this?
Duplicated question?
Yes, I think that the essence of the question is duplicated, but the nucleus isn't.
As you can see, the application is always calling the
loadGoogleMaps(); function that calls the external .js file. If I
click in the 5 different maps, I get 5 scripts with the same proposal.
That is incorrect. After the first time it completely loads, the if statement on the first line will return early, preventing you from including it multiple times.
There's nothing wrong with the way that's written.
jsFiddle
var gMapsLoaded = false;
window.gMapsCallback = function () {
gMapsLoaded = true;
$(window).trigger('gMapsLoaded');
}
window.loadGoogleMaps = function () {
if (gMapsLoaded) return window.gMapsCallback();
console.log('Generating new script tag');
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
"http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0]
|| document.documentElement).appendChild(script_tag);
}
$(window).on("gMapsLoaded",function(){
console.log("gMapsLoaded");
});
$(function(){
$("button").on("click",window.loadGoogleMaps);
});
Now, if you were to click it 5 times really fast when it isn't already loaded, it could potentially load it multiple times. You should call that function on it's own before a click event would normally happen to prevent that.
Update:
At the end of your initialize() method, you're using gMapsLoaded = false; which causes the above code to once again request a new script tag. Simply remove/comment out that line.
I wonder whether someone may be able to help me please.
Because of loading issues, I've moved the map options code to my HTML form, rather than it being in a separate Javascript file.
The problem is that I now can't get the Geocode functionality to work. I've added my code below. I'm sure it must be something simple, but I'm a little perplexed by this. I just wondered whether it would be at all possible please that someone could let me know where I've gone wrong.
Many thanks
function geocode() {
// This is defining the global variables
var geocoder, marker;
// This is making the link with the 'Search For Location' HTML form
var form = document.getElementById('searchforlocationform');
// This is catching the forms submit event
form.onsubmit = function() {
// This is getting the Address from the HTML forms 'Address' text box
var address = document.getElementById('inputaddress').value;
// This is making the Geocoder call
getCoordinates(address);
// This is preventing the form from doing a page submit
return false;
}
}
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
},
function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
} else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
//New Code
function updateMarkerStatus(str) {
document.getElementById('markerStatus').innerHTML = str;
}
//Changed 'address' to 'returnedaddress'
function updateMarkerAddress(str) {
document.getElementById('returnedaddress').value= str;
}
// This creates the function that will return the coordinates for the address
function getCoordinates(address) {
// This checks to see if there is already a geocoded object. If not, it creates one
if(!geocoder){geocoder = new google.maps.Geocoder();}
// This is creating a GeocoderRequest object
var geocoderRequest = {address: address}
// This is making the Geocode request
geocoder.geocode(geocoderRequest, function(results, status) {
// Check if status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
// Center the map on the returned location
map.setCenter(results[0].geometry.location);
// Check to see if we've already got a Marker object
if (!marker) {
map.setZoom(16);
marker = new google.maps.Marker({
map: map, draggable:true
});
}
// Setting the position of the marker to the returned location
marker.setPosition(results[0].geometry.location);
// Add dragging event listeners.
google.maps.event.addListener(marker, function() {
updateMarkerAddress;
});
//This fills out the 'Latitude' and 'Longitude' text boxes on the HTML form
document.getElementById('osgb36lat').value= results[0].geometry.location.lat();
document.getElementById('osgb36lon').value= results[0].geometry.location.lng();
//This allows the marker to be draggable and tells the 'Latitude' and 'Longitude' text boxes on the HTML form to update with the new co-ordinates as the marker is dragged
google.maps.event.addListener(marker,'dragend',
function() {
updateMarkerStatus;
geocodePosition(marker.getPosition());
document.getElementById('osgb36lat').value = marker.position.lat();
document.getElementById('osgb36lon').value = marker.position.lng();
});
// Update current position info.
latLng = [marker.position.lat(), marker.position.lng()].join(', ');
geocodePosition(marker.getPosition());
var point = marker.getPosition();
map.panTo(point);
}
}
)
}
<script type="text/javascript">
(function() {
window.onload = function(){
var latlng = new google.maps.LatLng(54.312195845815246,-4.45948481875007);
var options = {
zoom: 6,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.TOP_RIGHT
},
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.ZOOM_PAN,
position: google.maps.ControlPosition.TOP_LEFT
},
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT
}
};
var map = new google.maps.Map(document.getElementById('map'), options);
}
})();
</script>
You seen to be trying to call updateMarkerAddress with updateMarkerAddress; and updateMarkerStatus with updateMarkerStatus;, here you are missing (/*some param*/).
What are the loading issues? Maybe if you show your html someone could help with that too.