FoxInCloud supports Google Map in both desktop and Web mode, with a high level of progam and/or user interaction. This post shows how, with very simple code, your application can provide a great map user experience on any device: desktop, browser on desktop or hand-held device.
(installed with V 2.21.1 scheduled 2016-05-01 ).
ADD OBJECT oleIE AS ficOLEIE WITH ; && ficOLEIE as awOLEIE of aw.vcx
Top = 5, ;
Left = 10, ;
Height = 315, ;
Width = 745, ;
ZOrderSet = 11, ;
Anchor = 15, ;
Name = "oleIE"
PROCEDURE oleIE.Init
&& 2016-04-20 thn -- {en} desktop mode: to use Google Maps in this control, you need to set Internet Explorer Compatibility:
&& 2016-04-20 thn -- {fr} mode desktop : pour utiliser Google Maps dans ce contrôle, vous devez régler la compatibilité Internet Explorer :
&& https://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version
ENDPROC
2- Implement a Google Map in Web mode
When generating HTML, this objects instructs the HTML/CSS/JS generator to add JavaScript that creates a Google Map in Web mode:
PROCEDURE oleIE.wcHTMLgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
local cScript as String
&& {en} The following JavaScript:
&& {en} - instantiates a Google Maps API object and stores a reference in a property added to the form's HTML element
&& {en} - implements the 'center_changed' event that fires when user moves the map using the mouse:
&& {en} event handler writes the new lattitude and longitude to the spinners in the page
&& {en} notes:
&& {en} - $() is a shortcut to document.getElementById()
&& {en} - cLitteralJS() (modify command abTxt) turns any VFP value into a JavaScript literal
&& {en} - [test ? valueTrue : valueFalse] is the JavaScript equivalent for Iif()
&& {fr} Ce JavaScript :
&& {fr} - instancie un objet Google Maps API et stocke sa référence dans une propriété ajoutée à l'élément HTML du formulaire
&& {fr} - implémente l'événement 'center_changed' déclenché lorsque l'utilisateur déplace la carte avec la souris
&& {fr} ce code écrit les nouvelles latitude et longitude dans les toupies présentes sur la page HTML
&& {fr} notes :
&& {fr} - $() est un raccourci (alias) de document.getElementById()
&& {fr} - cLitteralJS() (modify command abTxt) convertit toute valeur VFP en un littéral JavaScript
&& {fr} - [test ? valueTrue : valueFalse] est l'équivalent JavaScript de Iif()
&& https://developers.google.com/maps/documentation/javascript/reference
text to cScript noshow textmerge flags 1 pretext 15
$('<<m.thisForm.wcID>>').googleMap = new google.maps.Map(
$('<<m.this.wcID>>')
, {
center: {lat: <<cLitteralJS(thisForm.spnLat.Value)>>, lng: <<cLitteralJS(thisForm.spnLng.Value)>>}
, zoom: 8
}
);
$('<<m.thisForm.wcID>>').googleMap.addListener('center_changed', function(){
var googleMap = $('<<m.thisForm.wcID>>').googleMap
, LatLng = googleMap.getCenter()
, zoom = googleMap.getZoom()
, dec = zoom > 12
? 5
: (zoom > 10
? 4
: (zoom > 8
? 3
: (zoom > 6
? 2
: (zoom > 4
? 1
: 0
)
)
)
)
;
$('<<thisForm.spnLat.wcID>>').valueSet(LatLng.lat().toFixed(dec) + '°');
$('<<thisForm.spnLng.wcID>>').valueSet(LatLng.lng().toFixed(dec) + '°');
});
endtext
m.toHTMLgen.cScriptJSadd(m.cScript)
ENDPROC
3- Load the Google Map JavaScript resource
Of course, we need to instruct the server, namely the process object, to generate a HTML instruction that loads the Google Map JavaScript whenever necessary:
* -------------------------------------------
PROTECTED FUNCTION cawJSinc && of xxxProcess
LPARAMETERS ;
tcJSAdd; && [''] {en} Application, current form[, and custom] {fr} JS files URLs (UTF-8 encoded) {fr} URL des fichiers JS de l'application et du formulaire courant (encodés en UTF-8)
, toForm as awFrm of aw.vcx; && {en} Reference to form && {fr} Référence au formulaire && 2016-04-20 thn -- {en} {FiC V 2.21.1-beta.0} added paramter
, tcForm; && {en} .Name of form {fr} Nom du formulaire && 2016-04-20 thn -- {en} {FiC V 2.21.1-beta.0} added parameter
local result
result = DoDefault(m.tcJSAdd)
if InList(Lower(m.tcForm), Lower('index.scx'), Lower('googleMap.scx'))
result = '<script src="https://maps.googleapis.com/maps/api/js"></script>' + m.result
endif
return m.result
endfunc
4- Add control over the map location
We also add 2 spinners
and a commandButton
to control where the map is centered:
ADD OBJECT spnLat AS ficSpn WITH ; && ficSpn as awSpn of aw.vcx
Anchor = 12, ;
Height = 24, ;
InputMask = "999.99°", ;
KeyboardHighValue = 180, ;
KeyboardLowValue = -180, ;
Left = 680, ;
SpinnerHighValue = 180.00, ;
SpinnerLowValue = -180.00, ;
Top = 345, ;
Width = 75, ;
ZOrderSet = 6, ;
Value = 48.79, ; && initial map lattitude
Name = "spnLat"
ADD OBJECT spnLng AS ficSpn WITH ; && ficSpn as awSpn of aw.vcx
Anchor = 12, ;
Height = 24, ;
InputMask = "999.99°", ;
KeyboardHighValue = 180, ;
KeyboardLowValue = -180, ;
Left = 680, ;
SpinnerHighValue = 180.00, ;
SpinnerLowValue = -180.00, ;
Top = 398, ;
Width = 75, ;
ZOrderSet = 8, ;
Value = 2.21, ; && initial map longitude
Name = "spnLng"
ADD OBJECT cmdSet AS ficCmd WITH ; && ficCmd as awCmd of aw.vcx
Top = 430, ;
Left = 680, ;
Height = 24, ;
Width = 75, ;
Anchor = 12, ;
Caption = "Set", ;
ZOrderSet = 10, ;
Name = "cmdSet"
As usual, the .click() method of the button is implemented for both desktop and web mode, all code (VFP and JavaScript) in the same method:
PROCEDURE cmdSet.Click
if thisForm.wlHTMLgen && FoxInCloud adaptation
return
endif
local oAJAX as awAJAX of awServer.prg;
, cURL as String;
* ==============================
if wlAJAX(@m.oAJAX) && Web mode
* ==============================
&& tutoServer.prg > tutoProcess.cawJSinc() {en} loads the Google Map Script {fr} charge le script Google Map
&& https://developers.google.com/maps/documentation/javascript/reference
&& {en} act upon Google Maps API object stored in form HTML element
&& {en} notes:
&& {en} - FoxInCloud Application Server executes this code when user clicks this button in the browser
&& {en} - oAJAX is a reference to the FoxInCloud AJAX object processing the request
&& {en} - oAJAX.cScriptJSadd_() adds some JavaScript instruction to the AJAX response
&& {en} - $() is a shortcut to document.getElementById()
&& {en} - cLitteralJS() (modify command abTxt) turns any VFP value into a JavaScript literal
&& {fr} agir sur l'objet Google Maps API dont l'élément HTML du formulaire garde une référence
&& {fr} notes :
&& {fr} - Le serveur d'application FoxInCloud exécute ce code lorsque l'utilisateur clique le bouton dans le navigateur
&& {fr} - oAJAX est une référence à l'Objet AJAX FoxInCloud traitant la requête
&& {fr} - oAJAX.cScriptJSadd_() ajoute des instructions JavaScript à la réponse AJAX
&& {fr} - $() est un raccourci (alias) de document.getElementById()
&& {fr} - cLitteralJS() (modify command abTxt) convertit toute valeur VFP en un littéral JavaScript
m.oAJAX.cScriptJSadd_(Textmerge([$('<<wcID(thisForm)>>').googleMap.setCenter({lat:<<cLitteralJS(Cast(m.thisForm.spnLat.Value as N(6,2)))>>, lng:<<cLitteralJS(Cast(thisForm.spnLng.Value as N(6,2)))>>});]))
* ==============================
else && LAN / desktop mode
* ==============================
&& {en} change URL on Internet Explorer activeX
&& {fr} mettre à jour l'URL de l'Internet Explorer activeX
cURL = Evl(thisForm.oleIE.object.LocationURL, 'https://www.google.com/maps/@48.8000,2.2000,10z')
cURL = GetWordNum(m.cURL, 1, '@');
+ '@' + cL(thisForm.spnLat.Value); && {en} Cast() depends on Set("Point"), cL() works around this {fr} Cast() dépend de Set("Point"), cL() s'en affranchit
+ ',' + cL(thisForm.spnLng.Value); && modify command abTxt
+ ',' + GetWordNum(GetWordNum(m.cURL, 2, '@'), 3, ',');
+ ''
thisForm.oleIE.object.navigate2(m.cURL) && <==
endif
ENDPROC
We make sure that form inits to some location (default or parameter)
PROCEDURE Init
lparameters lat, lng
DoDefault()
if thisForm.wlInitFirst && FoxInCloud adaptation
return
endif
if Pcount() > 0
this.spnLat.Value = Cast(m.lat as N(4,1))
this.spnLng.Value = Cast(m.lng as N(4,1))
endif
this.cmdSet.Click
6- Update spinners with the current map location
Whenever user moves the map using the mouse, the lattitude and longitude spinners reflect where map is currently centered
PROCEDURE oleIE.NavigateComplete2
*** ActiveX Control Event ***
LPARAMETERS pdisp, url
&& {en} fires in desktop mode only
&& {fr} ne se déclenche qu'en mode desktop
url = GetWordNum(m.url, 2, '@') && eg 'https://www.google.com/maps/@48.8000,2.2000,10z' > '48.8000,2.2000,10z'
thisform.spnLat.Value = Cast(GetWordNum(m.url, 1, ',') as N(6,2))
thisform.spnLng.Value = Cast(GetWordNum(m.url, 2, ',') as N(6,2))
PROCEDURE oleIE.wcHTMLgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
text to cScript noshow textmerge flags 1 pretext 15 && for Web mode
$('<<m.thisForm.wcID>>').googleMap.addListener('center_changed', function(){
var googleMap = $('<<m.thisForm.wcID>>').googleMap
, LatLng = googleMap.getCenter()
, zoom = googleMap.getZoom()
, dec = zoom > 12
? 5
: (zoom > 10
? 4
: (zoom > 8
? 3
: (zoom > 6
? 2
: (zoom > 4
? 1
: 0
)
)
)
)
;
$('<<thisForm.spnLat.wcID>>').valueSet(LatLng.lat().toFixed(dec) + '°');
$('<<thisForm.spnLng.wcID>>').valueSet(LatLng.lng().toFixed(dec) + '°');
});
endtext
m.toHTMLgen.cScriptJSadd(m.cScript)
ENDPROC
7- Test!
On-line test
VIDEO
tags:
JavaScript
user experience
Watch FoxInCloud Marketing Videos :: Watch FoxInCloud Technical Videos :: Stay tuned on FoxInCloud Roadmap :: Learn how to use FoxInCloud :: Download FoxInCloud Adaptation Assistant for free :: Download FoxInCloud Web Application Studio for free
Please enable JavaScript to view the comments powered by Disqus.