You need to sign in to do that
Don't have an account?
Jan Vandevelde
Visualforce page not listed to add on page layout
Hi all,
maybe you could help me out. I've got a visualforce page that I'd like to add to the page layout of Accounts, but it isn't listed on the page layout editor.
I know it has to start with the standardController="Account" and it does. It also uses an extension, but from what I've found on the web that's not a problem but it has to include the standardController.
So here is a bit of the code.
Visual Force page:
<apex:page sidebar="false" showheader="false" standardController="Account" recordSetVar="accts" extensions="FindNearby">
<!-- Include in Google's Maps API via JavaScript static resource -->
<apex:includeScript value="{!$Resource.googleMapsAPI}" />
<!-- Set this API key to fix JavaScript errors in production -->
<!--http://salesforcesolutions.blogspot.com/2013/01/integration-of-salesforcecom-and-google.html-->
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCROH4OR9fzDhmprWPL1wGWfPT4uGUeMWg&sensor=false">
</script>
<!-- Setup 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>
<script>
function initialize() {
var lat, lon;
// If we can, get the position of the user via device geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
lat = position.coords.latitude;
lon = position.coords.longitude;
// Use Visualforce JavaScript Remoting to query for nearby accts
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.FindNearby.getNearby}', lat, lon,
function(result, event){
if (event.status) {
console.log(result);
createMap(lat, lon, result);
} else if (event.type === 'exception') {
//exception case code
} else {
}
},
{escape: true}
);
});
} else {
// Set default values for map if the device doesn't have geolocation capabilities
/** Eindhoven **/
lat = 51.096214;
lon = 3.683153;
var result = [];
createMap(lat, lon, result);
}
}
function createMap(lat, lon, accts){
// Get the map div, and center the map at the proper geolocation
var currentPosition = new google.maps.LatLng(lat,lon);
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: currentPosition,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Set a marker for the current location
var positionMarker = new google.maps.Marker({
map: map,
position: currentPosition,
icon: 'http://maps.google.com/mapfiles/ms/micons/green.png'
});
// Keep track of the map boundary that holds all markers
var mapBoundary = new google.maps.LatLngBounds();
mapBoundary.extend(currentPosition);
// Set markers on the map from the @RemoteAction results
var acct;
for(var i=0; i<accts.length;i++){
acct = accts[i];
console.log(accts[i]);
setupMarker();
}
// Resize map to neatly fit all of the markers
map.fitBounds(mapBoundary);
function setupMarker(){
var acctNavUrl;
// Determine if we are in Salesforce1 and set navigation link appropriately
try{
if(sforce.one){
acctNavUrl =
'javascript:sforce.one.navigateToSObject(\'' + acct.Id + '\')';
}
} catch(err) {
console.log(err);
acctNavUrl = '\\' + acct.Id;
}
var acctDetails =
'<a href="' + acctNavUrl + '">' +
acct.Name + '</a><br/>' +
acct.BillingStreet + '<br/>' +
acct.BillingCity + '<br/>' +
acct.Phone;
// Create the callout that will pop up on the marker
var infowindow = new google.maps.InfoWindow({
content: acctDetails
});
// Place the marker on the map
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
acct.Location__Latitude__s,
acct.Location__Longitude__s)
});
mapBoundary.extend(marker.getPosition());
// Add the action to open up the panel when it's marker is clicked
google.maps.event.addListener(marker, 'click', function(){
infowindow.open(map, marker);
});
}
}
// Fire the initialize function when the window loads
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body style="font-family: Arial; border: 0 none;">
<!-- All content is rendered by the Google Maps code -->
<!-- This minimal HTML justs provide a target for GMaps to write to -->
<div id="map-canvas"></div>
</body>
</apex:page>
Controller class:
global with sharing class FindNearby {
public FindNearby(ApexPages.StandardSetController controller) { }
@RemoteAction
// Find Accounts nearest a geolocation
global static List<Account> getNearby(String lat, String lon) {
// If geolocation isn't set, use Eindhoven (or any other city)
// Put a default location latitue and longitude here, this could be where you are located the most
// and will only be used as a backup if the browser can not get your location details
if(lat == null || lon == null || lat.equals('') || lon.equals('')) {
lat = '51.096214';
lon = '3.683153';
}
// SOQL query to get the nearest accounts
//you can change km (kilometers) into mi (miles)
// < 20 means within a radius of 20 km or mi (you can change that)
//limit 25 shows 25 records (you can adapt that too if you want)
String queryString =
'SELECT Id, Name, Location__Longitude__s, Location__Latitude__s, ' +
'BillingStreet, Phone, BillingCity ' +
'FROM Account ' +
'WHERE DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'km\') < 20 ' +
'ORDER BY DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'km\') ' +
'LIMIT 25';
// Run and return the query results
return(database.Query(queryString));
}
}
and here's what I see on page layout editor:
What are the possible reasons it isn't listed to be added to the page layout of account?
maybe you could help me out. I've got a visualforce page that I'd like to add to the page layout of Accounts, but it isn't listed on the page layout editor.
I know it has to start with the standardController="Account" and it does. It also uses an extension, but from what I've found on the web that's not a problem but it has to include the standardController.
So here is a bit of the code.
Visual Force page:
<apex:page sidebar="false" showheader="false" standardController="Account" recordSetVar="accts" extensions="FindNearby">
<!-- Include in Google's Maps API via JavaScript static resource -->
<apex:includeScript value="{!$Resource.googleMapsAPI}" />
<!-- Set this API key to fix JavaScript errors in production -->
<!--http://salesforcesolutions.blogspot.com/2013/01/integration-of-salesforcecom-and-google.html-->
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCROH4OR9fzDhmprWPL1wGWfPT4uGUeMWg&sensor=false">
</script>
<!-- Setup 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>
<script>
function initialize() {
var lat, lon;
// If we can, get the position of the user via device geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
lat = position.coords.latitude;
lon = position.coords.longitude;
// Use Visualforce JavaScript Remoting to query for nearby accts
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.FindNearby.getNearby}', lat, lon,
function(result, event){
if (event.status) {
console.log(result);
createMap(lat, lon, result);
} else if (event.type === 'exception') {
//exception case code
} else {
}
},
{escape: true}
);
});
} else {
// Set default values for map if the device doesn't have geolocation capabilities
/** Eindhoven **/
lat = 51.096214;
lon = 3.683153;
var result = [];
createMap(lat, lon, result);
}
}
function createMap(lat, lon, accts){
// Get the map div, and center the map at the proper geolocation
var currentPosition = new google.maps.LatLng(lat,lon);
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: currentPosition,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Set a marker for the current location
var positionMarker = new google.maps.Marker({
map: map,
position: currentPosition,
icon: 'http://maps.google.com/mapfiles/ms/micons/green.png'
});
// Keep track of the map boundary that holds all markers
var mapBoundary = new google.maps.LatLngBounds();
mapBoundary.extend(currentPosition);
// Set markers on the map from the @RemoteAction results
var acct;
for(var i=0; i<accts.length;i++){
acct = accts[i];
console.log(accts[i]);
setupMarker();
}
// Resize map to neatly fit all of the markers
map.fitBounds(mapBoundary);
function setupMarker(){
var acctNavUrl;
// Determine if we are in Salesforce1 and set navigation link appropriately
try{
if(sforce.one){
acctNavUrl =
'javascript:sforce.one.navigateToSObject(\'' + acct.Id + '\')';
}
} catch(err) {
console.log(err);
acctNavUrl = '\\' + acct.Id;
}
var acctDetails =
'<a href="' + acctNavUrl + '">' +
acct.Name + '</a><br/>' +
acct.BillingStreet + '<br/>' +
acct.BillingCity + '<br/>' +
acct.Phone;
// Create the callout that will pop up on the marker
var infowindow = new google.maps.InfoWindow({
content: acctDetails
});
// Place the marker on the map
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
acct.Location__Latitude__s,
acct.Location__Longitude__s)
});
mapBoundary.extend(marker.getPosition());
// Add the action to open up the panel when it's marker is clicked
google.maps.event.addListener(marker, 'click', function(){
infowindow.open(map, marker);
});
}
}
// Fire the initialize function when the window loads
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body style="font-family: Arial; border: 0 none;">
<!-- All content is rendered by the Google Maps code -->
<!-- This minimal HTML justs provide a target for GMaps to write to -->
<div id="map-canvas"></div>
</body>
</apex:page>
Controller class:
global with sharing class FindNearby {
public FindNearby(ApexPages.StandardSetController controller) { }
@RemoteAction
// Find Accounts nearest a geolocation
global static List<Account> getNearby(String lat, String lon) {
// If geolocation isn't set, use Eindhoven (or any other city)
// Put a default location latitue and longitude here, this could be where you are located the most
// and will only be used as a backup if the browser can not get your location details
if(lat == null || lon == null || lat.equals('') || lon.equals('')) {
lat = '51.096214';
lon = '3.683153';
}
// SOQL query to get the nearest accounts
//you can change km (kilometers) into mi (miles)
// < 20 means within a radius of 20 km or mi (you can change that)
//limit 25 shows 25 records (you can adapt that too if you want)
String queryString =
'SELECT Id, Name, Location__Longitude__s, Location__Latitude__s, ' +
'BillingStreet, Phone, BillingCity ' +
'FROM Account ' +
'WHERE DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'km\') < 20 ' +
'ORDER BY DISTANCE(Location__c, GEOLOCATION('+lat+','+lon+'), \'km\') ' +
'LIMIT 25';
// Run and return the query results
return(database.Query(queryString));
}
}
and here's what I see on page layout editor:
What are the possible reasons it isn't listed to be added to the page layout of account?
1. Remove the code: public FindNearby(ApexPages.StandardSetController controller) { } // because it will not be usefull once we reomve recordSetVar
2. On that place put this code : public FindNearby(ApexPages.StandardController sc){}
3. Save the Code. If you are getting any error while saving it -- please make whole code of VF page comment and save the page, save the controller.
4. Now remove the recordSetVar ="accts" from VF Page.
5. Save VF Page and check the result.
Thanks,
Shiv
All Answers
Remove recordSetVar="accts" from <apex:page in Visualforce page and then try.
can't do that because the controller passes a list of accounts into that and the page can't be saved anymore if I remove that.
Maybe I shoudl explain what it does. Momentarily it works from a stand alone visual force tab and it looks up my location given by the browser and shows a map of accounts in my neighbourhood. It works perfectly as standalone tab
But now I would like to embedd it on a page layout of accounts, so it always shows accounts nearby my location as I'm now at the location of a specific account and I would like to go the the next nearest customer.
Accts which is used in page is parameter of a java Script function. I don't see any user of recordSetVar ="accts" on visual force page. Please remove it once and check either your functionlaity is working properly or not.
yes controller passess the list of account but it is not storing in recordSetVar. It is storing result[] array. Please test it by removing recordSetVar and check the result.
thanks for looking into this. Like I said to Anoop (he suggested the same) I get an error when saving the page after I remove the recordSetVar. So I'll post the screenshot.
remove the line --- public FindNearby(ApexPages.StandardSetController controller) { }
and insert following line on that place...
public FindNearby(ApexPages.StandardController sc){}
and save controller,
now try to save the page ....
and check the result.
Thanks
I'm in some kind of loop here ;-) I first have to change this in the controller to remove the recordsetvar from the page, but can't save because it's used by the page, but can't remove from the page because it's used in the controller :-(
1. Remove the code: public FindNearby(ApexPages.StandardSetController controller) { } // because it will not be usefull once we reomve recordSetVar
2. On that place put this code : public FindNearby(ApexPages.StandardController sc){}
3. Save the Code. If you are getting any error while saving it -- please make whole code of VF page comment and save the page, save the controller.
4. Now remove the recordSetVar ="accts" from VF Page.
5. Save VF Page and check the result.
Thanks,
Shiv
<apex:page sidebar="false" showheader="false" extensions="FindNearby">
</apex:page>
-- save it. It will be saved.
-- Now go to the controller and made the changes which I told you to make. And save controller code
Now come to page and remove everything and put following code
<apex:page sidebar="false" showheader="false" standardController="Account" extensions="FindNearby">
<!-- Include in Google's Maps API via JavaScript static resource -->
<apex:includeScript value="{!$Resource.googleMapsAPI}" />
<!-- Set this API key to fix JavaScript errors in production -->
<!--http://salesforcesolutions.blogspot.com/2013/01/integration-of-salesforcecom-and-google.html-->
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCROH4OR9fzDhmprWPL1wGWfPT4uGUeMWg&sensor=false">
</script>
<!-- Setup 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>
<script>
function initialize() {
var lat, lon;
// If we can, get the position of the user via device geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
lat = position.coords.latitude;
lon = position.coords.longitude;
// Use Visualforce JavaScript Remoting to query for nearby accts
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.FindNearby.getNearby}', lat, lon,
function(result, event){
if (event.status) {
console.log(result);
createMap(lat, lon, result);
} else if (event.type === 'exception') {
//exception case code
} else {
}
},
{escape: true}
);
});
} else {
// Set default values for map if the device doesn't have geolocation capabilities
/** Eindhoven **/
lat = 51.096214;
lon = 3.683153;
var result = [];
createMap(lat, lon, result);
}
}
function createMap(lat, lon, accts){
// Get the map div, and center the map at the proper geolocation
var currentPosition = new google.maps.LatLng(lat,lon);
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: currentPosition,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Set a marker for the current location
var positionMarker = new google.maps.Marker({
map: map,
position: currentPosition,
icon: 'http://maps.google.com/mapfiles/ms/micons/green.png'
});
// Keep track of the map boundary that holds all markers
var mapBoundary = new google.maps.LatLngBounds();
mapBoundary.extend(currentPosition);
// Set markers on the map from the @RemoteAction results
var acct;
for(var i=0; i<accts.length;i++){
acct = accts[i];
console.log(accts[i]);
setupMarker();
}
// Resize map to neatly fit all of the markers
map.fitBounds(mapBoundary);
function setupMarker(){
var acctNavUrl;
// Determine if we are in Salesforce1 and set navigation link appropriately
try{
if(sforce.one){
acctNavUrl =
'javascript:sforce.one.navigateToSObject(\'' + acct.Id + '\')';
}
} catch(err) {
console.log(err);
acctNavUrl = '\\' + acct.Id;
}
var acctDetails =
'<a href="' + acctNavUrl + '">' +
acct.Name + '</a><br/>' +
acct.BillingStreet + '<br/>' +
acct.BillingCity + '<br/>' +
acct.Phone;
// Create the callout that will pop up on the marker
var infowindow = new google.maps.InfoWindow({
content: acctDetails
});
// Place the marker on the map
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
acct.Location__Latitude__s,
acct.Location__Longitude__s)
});
mapBoundary.extend(marker.getPosition());
// Add the action to open up the panel when it's marker is clicked
google.maps.event.addListener(marker, 'click', function(){
infowindow.open(map, marker);
});
}
}
// Fire the initialize function when the window loads
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body style="font-family: Arial; border: 0 none;">
<!-- All content is rendered by the Google Maps code -->
<!-- This minimal HTML justs provide a target for GMaps to write to -->
<div id="map-canvas"></div>
</body>
</apex:page>
-- now check the result
Than I followed the steps you said and now I was able to save it, test the normal TAB functionality if it was not broken, but no IT WORKED FINE!
Then I went to page layout to see if this resolved the problem stated in the first place and YEAH you ROCK!
It's residing with the page layout and showing accounts nearby my location.
Thanks a lot shiv@SFDC !!!
Here's the result