- A salesforce dx geolocation app created from scratch.
- Created the project
sfdx force:project:create -n sfdx-geolocation
cd sfdx-geolocation
- Best practice, add
.sfdx
folder to.gitignore
file
# Ignore sfdx folder
.sfdx
- Push to GitHub
git init
git add -A
git commit -m "Initialise project with sfdx"
git push origin master
- Create a scratch org with the alias GeoAppScratch:
sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
- Open scratch org
sfdx force:org:open
- Create custom fields as instructed in:
https://trailhead.salesforce.com/trails/sfdx_get_started/modules/sfdx_app_dev/units/sfdx_app_dev_create_app
- Assign permission set to user:
sfdx force:user:permset:assign -n Geolocation
- Pull Changes into Your Project
sfdx force:source:pull
- Best practice, push all changes to GitHub
git add -A
git commit -m "Add custom object and permset"
git push origin master
- Create Sample Data as instructed in:
https://trailhead.salesforce.com/trails/sfdx_get_started/modules/sfdx_app_dev/units/sfdx_app_dev_create_app
- Create data folder
mkdir data
- Export the created sample data:
sfdx force:data:tree:export -q "SELECT Name, Location__Latitude__s, Location__Longitude__s FROM Account WHERE Location__Latitude__s != NULL AND Location__Longitude__s != NULL" -d ./data
- Create
Apex Controller Class
sfdx force:apex:class:create -n AccountController -d force-app/main/default/classes
- Modify
AccountController.cls
public with sharing class AccountController {
@AuraEnabled
public static List<Account> findAll() {
return [SELECT Id, Name, Location__Latitude__s, Location__Longitude__s
FROM Account
WHERE Location__Latitude__s != NULL AND Location__Longitude__s !=
NULL
LIMIT 50];
}
}
- Push changes to scratch org
sfdx force:source:push
- Create
Lightning Component
sfdx force:lightning:component:create -n AccountLocator -d force-app/main/default/aura
- Modify
AccountLocator.cmp
<aura:component implements="force:appHostable">
<div>
<div>AccountMap goes here</div>
<div>AccountList goes here</div>
</div>
</aura:component>
- Modify
AccountLocator.css
.THIS {
position:absolute;
height: 100%;
width: 100%;
background: #FFFFFF;
}
.THIS>div {
height: 50%;
}
- Push source to scratch org
sfdx force:source:push
- Set Up a Tab to Open the Lightning Component as instructed in:
https://trailhead.salesforce.com/trails/sfdx_get_started/modules/sfdx_app_dev/units/sfdx_app_dev_build_app
- Pull the custom tab changes from the scratch org
sfdx force:source:pull
- Create
AccountListItem
lightning component
sfdx force:lightning:component:create -n AccountListItem -d force-app/main/default/aura
- Modify
AccountListItem.cmp
<aura:component>
<aura:attribute name="account" type="Account"/>
<li><a>{!v.account.Name}</a></li>
</aura:component>
- Modify
AccountListItem.css
.THIS {
border-bottom: solid 1px #DDDDDD;
}
.THIS a {
display: block;
padding: 20px;
color: inherit;
}
.THIS a:active {
background-color: #E8F4FB;
}
- Create
AccountList
lightning component
sfdx force:lightning:component:create -n AccountList -d force-app/main/default/aura
- Modify
AccountList.cmp
<aura:component controller="AccountController">
<aura:attribute name="accounts" type="Account[]"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<ul>
<aura:iteration items="{!v.accounts}" var="account">
<c:AccountListItem account="{!account}"/>
</aura:iteration>
</ul>
</aura:component>
- Modify
AccountListController.js
({
doInit: function(component, event) {
var action = component.get('c.findAll')
action.setCallback(this, function(a) {
component.set('v.accounts', a.getReturnValue())
})
$A.enqueueAction(action)
}
})
- Modify
AccountList.css
.THIS {
list-style-type: none;
padding: 0;
margin: 0;
background: #FFFFFF;
height: 100%;
}
- Modify
AccountLocator.cmp
to use theAccountList
component
<aura:component implements="force:appHostable">
<div>
<div>AccountMap goes here</div>
<div>
<c:AccountList/>
</div>
</div>
</aura:component>
- Push source to scratch org
sfdx force:source:push
-
Download Leaflet javascript library
-
Install in scratch org as instructed in:
https://trailhead.salesforce.com/trails/sfdx_get_started/modules/sfdx_app_dev/units/sfdx_app_dev_create_visuals
- Pull the static resource from scratch org
sfdx force:source:pull
- Create
AccountMap
lightning component
sfdx force:lightning:component:create -n AccountMap -d force-app/main/default/aura
- Modify
AccountMap.cmp
<aura:component>
<aura:attribute name="map" type="Object"/>
<ltng:require styles="/resource/leaflet/leaflet.css"
scripts="/resource/leaflet/leaflet.js"
afterScriptsLoaded="{!c.jsLoaded}" />
<div id="map"></div>
</aura:component>
- Modify
AccountMapController.js
({
jsLoaded: function(component, event, helper) {
var map = L.map('map', { zoomControl: false }).setView([37.784173, -122.401557], 14)
L.tileLayer(
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
{
attribution: 'Tiles © Esri'
}).addTo(map)
component.set('v.map', map)
}
})
- Modify
AccountMap.css
.THIS {
width: 100%;
height: 100%;
}
- Update the
AccountLocator.cmp
to useAccountMap
component
<aura:component implements="force:appHostable">
<div>
<div>
<c:AccountMap />
</div>
<div>
<c:AccountList />
</div>
</div>
</aura:component>
- Push changes to scratch org
sfdx force:source:push
- Create
AccountsLoaded
Lightning Event to Add Markers to the Map
sfdx force:lightning:event:create -n AccountsLoaded -d force-app/main/default/aura
- Modify
AccountsLoaded.evt
<aura:event type="APPLICATION">
<aura:attribute name="accounts" Type="Account[]"/>
</aura:event>
- Modify
AccountList.cmp
to and add an event declaration and map attribute. The map attribute loads the Leaflet stylesheet from the scratch org's static resources.
<aura:component controller="AccountController">
<aura:registerEvent name="accountsLoaded" type="c:AccountsLoaded"/>
<aura:attribute name="accounts" type="Account[]"/>
<ltng:require styles="/resource/leaflet/leaflet.css" scripts="/resource/leaflet/leaflet.js" afterScriptsLoaded="{!c.doInit}" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<ul>
<aura:iteration items="{!v.accounts}" var="account">
<c:AccountListItem account="{!account}"/>
</aura:iteration>
</ul>
</aura:component>
- Modify
AccountsListController.js
to add theAccountsLoaded
event
({
doInit : function(component, event) {
var action = component.get("c.findAll");
action.setCallback(this, function(a) {
component.set("v.accounts", a.getReturnValue());
var event = $A.get("e.c:AccountsLoaded");
event.setParams({"accounts": a.getReturnValue()});
event.fire();
});
$A.enqueueAction(action);
}
})
- Modify
AccountMap.cmp
to add theAccountsLoaded
event handler
<aura:component>
<aura:attribute name="map" type="Object"/>
<aura:handler event="c:AccountsLoaded" action="{!c.accountsLoaded}"/>
<ltng:require styles="/resource/leaflet/leaflet.css"
scripts="/resource/leaflet/leaflet.js"
afterScriptsLoaded="{!c.jsLoaded}" />
<div id="map"></div>
</aura:component>
- Modify AccountMapController.js
to add the
accountsLoaded` function
({
jsLoaded: function(component, event, helper) {
var map = L.map('map', { zoomControl: false }).setView([37.784173, -122.401557], 14)
L.tileLayer(
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
{
attribution: 'Tiles © Esri'
}).addTo(map)
component.set('v.map', map)
},
accountsLoaded: function(component, event, helper) {
// Add markers
var map = component.get('v.map');
var accounts = event.getParam('accounts');
for (var i=0; i<accounts.length; i++) {
var account = accounts[i];
var latLng = [account.Location__Latitude__s, account.Location__Longitude__s];
L.marker(latLng, {account: account}).addTo(map);
}
}
})
- Push changes to scratch org
sfdx force:source:push
- Create new scratch org
sfdx force:org:create -f config/project-scratch-def.json -a GeoTestOrg
- Push local source and metadata to GeoTestOrg
sfdx force:source:push -u GeoTestOrg
- Add permission set for GeoTestOrg
sfdx force:user:permset:assign -n Geolocation -u GeoTestOrg
- Load sample data to GeoTestOrg
sfdx force:data:tree:import -f data/Account.json -u GeoTestOrg
- Open GeoTestOrg
sfdx force:org:open -u GeoTestOrg