You need to sign in to do that
Don't have an account?
Craig Glencross 1
findnearbywarehouses example from Visualforce Workbook does not work
I have been following along with the (workbook_vf.pdf) Visualforce Workbook
Version 6, Spring ’15. There is one section called Visual Force and Apex in Action that will create a web page that shows a Google map of nearby warehouses.
I have followed all of the code examples in the workbook but the page:/apex/FindNearbyWareshouses will not render the Google map. The page is just blank.
I also viewed the
Develop > Pages > Completed_FindNearbyWarehousesPage
that comes with the Enhanced Warehouse Data Model (see page 25 of the workbook) and it will not work either.
Can someone please try this example in the workbook and see if they can get it to work? I think it would be very valuable to be able to see how all the pieces work together.
Version 6, Spring ’15. There is one section called Visual Force and Apex in Action that will create a web page that shows a Google map of nearby warehouses.
I have followed all of the code examples in the workbook but the page:/apex/FindNearbyWareshouses will not render the Google map. The page is just blank.
I also viewed the
Develop > Pages > Completed_FindNearbyWarehousesPage
that comes with the Enhanced Warehouse Data Model (see page 25 of the workbook) and it will not work either.
Can someone please try this example in the workbook and see if they can get it to work? I think it would be very valuable to be able to see how all the pieces work together.
The area of the example that is not firing is:
alert('1');
// Fire the initialize function when the window loads
google.maps.event.addDomListener(window, 'load', initialize);
alert('2');
alert('1');
// Fire the initialize function when the window loads
google.maps.event.addDomListener(window, 'load', initialize);
alert('2');
<script>
function initialize() {
var obj = document.getElementById("map-canvas")
alert(obj.id);
var mapProp = {center:new google.maps.LatLng(51.508742,-0.120850), zoom:5, mapTypeId:google.maps.MapTypeId.ROADMAP };
var map=new google.maps.Map(obj ,mapProp);
alert('leaving init');
}
</script>
<body onload="initialize()" >
<div id="map-canvas" style="width:500px;height:280px;padding:10px;border:1px solid black ;"> </div>
</body>
I have tried to access the google api methods these ways but none have worked:
<apex:includeScript value="{!$Resource.googleMapsAPI}" />
or
<script src="http://maps.googleapis.com/maps/api/js"></script>
My fix that seems to work is to replace the reference to the Static Resource with a script hosted on googleapis.com
Replace this line
<apex:includeScript value="{!$Resource.googleMapsAPI}" />
With
<script src="https://maps.googleapis.com/maps/api/js"></script>
The workbook did mention that for production environment, you need an API key. But in development, it's supposed to work.
I wondered how to diagnose thisas Alerts weren't working.
I listed the accounts and they're being returned.
I tried https://maps.googleapis.com as a remote site.
Then I used Craig's implification. It worked!
The Alerts now worked.
I added alert(navigator.geolocation.getCurrentPosition(function(position));
and the map stopped working and Alerts stopped working.
That's enough for my addled brain at the moment...
I've restructured the code a little to help debugging.
I shrunk the map using style="width:500px;height:280px;....etc while using the console.
There's also a debug switch to overide the geolocation while testing for results.
You can also un-comment the apex pageblock list of results to see what warehouses are found.
I've added a range parameter as I'm a long way from San Francisco but it'll be useful as something passed into this controller from my vf page (eventually).
Don't forget to put in your Google API Key.
Here's the code...
vf page:
<apex:page sidebar="false" showheader="false"
standardController="Warehouse__c" recordSetVar="warehouses"
extensions="WarehouseUtils">
<!-- from https://developer.salesforce.com/docs/atlas.en-us.202.0.workbook_vf.meta/workbook_vf/vf_action_findwarehouses_intro.htm -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR-KEY-HERE"> </script>
<!--&Sensor no longer required: https://developers.google.com/maps/documentation/javascript/error-messages#sensor-not-required -->
<!-- Set the map to take up the whole window -->
<style>
html, body { height: 100%; }
.page-map, .ui-content, #map-canvas { width: 100%; height:100%; padding: 0; }
#map-canvas { height: min-height: 100%; }
</style>
<!-- java scripts... -->
<script>
//global variables
var lat, lon, range;
function initialize() {
// Set default values for the map if the device
// doesn't have geolocation capabilities.
// This is San Francisco:
lat = 40; //37.77493;
lon = -122.419416;
range = 5000; //this will be sent in from a vf page
// Logicom HQ
//lat = '52.063421';
//lon = '-0.730755';
console.log('Range='+range);
//navigator.geolocation
//based on https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function NavSuccess(pos) {
console.log('Your current position is:');
lat = pos.coords.latitude; //copy to globals
lon = pos.coords.longitude;
};
function NavError(err) {
console.warn('ERROR(' + err.code + '): ' + err.message);
};
if (navigator.geolocation){
console.log('we have geolocation');
navigator.geolocation.getCurrentPosition(NavSuccess, NavError, options);
console.log('Latitude : ' + lat + ' Longitude: ' + lon);
//remote invoke the Apex Class method findNearbyWarehouses...
//@RemoteAction --- global static List<Warehouse__c> findNearbyWarehouses(String lat, String lon, Strin range) {
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.WarehouseUtils.findNearbyWarehouses}',
lat, lon, range,
function(result, event) {
//console.log('status='+event.status);
if (event.status) {
console.log(result);
//alert('result='+result.length);
for(var i=0; i<result.length ; i++) {
console.log(result[i]);
}//for
console.log('result='+result.length);
//debug switch to ignore geolocation
var ignore = false;
if (ignore){
lat = 37.77493;
lon = -122.419416;
range = 20;
}//ignore
createMap(lat, lon, result);
} else if (event.type === 'exception') {
//exception case code
} else {
console.log(event.type);
}
},
{escape: true}
); //invoke action
}
else //we don't have geolocation so...
{
console.log('we do not have geolocation');
var result = [];
createMap(lat, lon, result);
}//have geolocation?
} //initialize
function createMap(lat, lon, warehouses){
var obj = document.getElementById("map-canvas")
//MK : var mapProp = {center:new google.maps.LatLng(52.063421,-0.730755), zoom:5, mapTypeId:google.maps.MapTypeId.ROADMAP };
//San Francisco: lat = 37.77493; lon = -122.419416;
var mapProp = {center:new google.maps.LatLng(lat,lon), zoom:10, mapTypeId:google.maps.MapTypeId.ROADMAP };
var map=new google.maps.Map(obj ,mapProp);
// Set a marker for the current location
var currentPosition = new google.maps.LatLng(lat,lon);
console.log('currentposn...'+currentPosition);
var positionMarker = new google.maps.Marker({
map: map,
position: currentPosition,
icon: 'https://maps.google.com/mapfiles/ms/micons/green.png'
});
// Keep track of the map boundary that holds all markers
console.log('mapBoundary...');
var mapBoundary = new google.maps.LatLngBounds();
//console.log(mapBoundary.getNorthEast()+','+mapBoundary.getSouthWest());
mapBoundary.extend(currentPosition);
console.log('markers...'+warehouses.length);
if (warehouses.length>0) {
// Set markers on the map from the @RemoteAction results
var warehouse;
for(var i=0; i<warehouses.length ; i++) {
warehouse = warehouses[i];
//console.log(warehouses[i]);
setupMarker();
}
}//results to display
map.fitBounds(mapBoundary);
// setupMarker function goes here
function setupMarker(){
var warehouseNavUrl='http://www.virtualworlds.co.uk';
//alert('setupMarker');
//console.log('setupMarker');
// Determine if we are in Salesforce1 and set navigation
// link appropriately
try{
if(sforce.one){
console.log('SF1');
//alert('SF1');
warehouseNavUrl =
'javascript:sforce.one.navigateToSObject(\'' +
warehouse.Id + '\')';
}
} catch(err) {
console.log(err);
warehouseNavUrl = '\\' + warehouse.Id;
}
console.log('url'+warehouseNavUrl);
var warehouseDetails =
'<a href="' + warehouseNavUrl + '">' +
warehouse.Name + '</a><br/>' +
warehouse.Street_Address__c + '<br/>' +
warehouse.City__c + '<br/>' +
warehouse.Phone__c;
// Create a panel that appears when the user clicks on the marker
var infowindow = new google.maps.InfoWindow({
content: warehouseDetails
});
// Add the marker to the map
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
warehouse.Location__Latitude__s,
warehouse.Location__Longitude__s)
});
mapBoundary.extend(marker.getPosition());
// Add the action to open the panel when its marker is clicked
google.maps.event.addListener(marker, 'click', function(){
infowindow.open(map, marker);
});
}//setupMarker
}//createmap
</script>
<!-- list returned accounts as cross check
<apex:pageblock>
<apex:pageBlockSection id="listAccs" title="List of names" columns="1">
<apex:repeat value="{!warehouses}" var="c">
<apex:outputText value="{0} at {1},{2}" >
<apex:param value="{!c.Name}"/>
<apex:param value="{!c.Location__Latitude__s}"/>
<apex:param value="{!c.Location__Longitude__s}"/>
</apex:outputText>
</apex:repeat>
</apex:pageBlockSection>
</apex:pageblock>
-->
<!-- All content is rendered by the Google Maps code
This minimal HTML just provides a target for GMaps to write to.
An alternative style which has smaller map (useful when using console for debugging): style="width:500px;height:280px;padding:10px;border:1px solid black ;font-family: Arial;"
-->
<body onload="initialize()" >
<div id="map-canvas" style="border:1px solid black ;font-family: Arial;"> </div>
</body>
</apex:page>
---------------------------------------------------------------
...and the util class:
global with sharing class WarehouseUtils {
public WarehouseUtils(ApexPages.StandardSetController controller) { }
// Find warehouses nearest a geolocation
@RemoteAction
global static List<Warehouse__c> findNearbyWarehouses(String lat, String lon, String range) {
// Initialize results to an empty list
List<Warehouse__c> results = new List<Warehouse__c>();
// If geolocation parameters are invalid, use San Francisco
if(String.isBlank(lat) || String.isBlank(lon)) {
lat = '47.793731';
lon = '-122.395002';
}
if (range=='0') {range = '50';}
system.debug('range='+range);
// SOQL query to get the nearest warehouses
String queryString =
'SELECT Id, Name, Location__Longitude__s, Location__Latitude__s, ' +
'Street_Address__c, Phone__c, City__c ' +
'FROM Warehouse__c ' +
'WHERE DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'mi\') < '+range+
' ORDER BY DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'mi\') ' +
'LIMIT 500';
system.debug(queryString);
// Run the query
results = database.Query(queryString);
system.debug('#results='+results.size());
// Return the query results
return(results);
}
}
...enjoy.