function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Michael Hedrick 2Michael Hedrick 2 

Unable to pass JS values to controller

Hello,
I have a script that gets the lat and long of a user when they initiate a VF page.
</script>
</head> 
<div id="startLat">
</div>
<div id="startLon">
</div>

<script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;
        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
</script>
This works great but I am unable to bind it to the custom lat and long fields on the record.
I have tried both apex:outputField  and apex:inputputField and still unable to to save the lat and long field to the record
<label style="display:block;margin-top:12px;" for="Latitude__c"><span style="color:red;">*</span>Latitude</label>  <apex:inputField style="margin-left:0;" id="startLan" value="{!SourcingAudit.Latitude__c}" />
                    
                     <label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>    <apex:outputField style="margin-left:0;" id="startLon" value="{!SourcingAudit.Longitude__c}" />
Le me know what I am doing incorrect or if there is a better option.

Thanks

 
Best Answer chosen by Michael Hedrick 2
Maharajan CMaharajan C
Hi Micheal,

Don't get into the confusions:

You are using the Output panel so simply use Css Class selector to set the Lat and Lan in your page.

Sample is below :

<apex:page id="pg" standardController="Account" extensions="AccountExtension">

  <script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementsByClassName('Latclass')[0].value =startPos.coords.latitude;
            document.getElementsByClassName('Lonclass')[0].value =startPos.coords.longitude;

        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
  </script>

<apex:form id="inpform">
  <apex:pageBlock title="Account Form" id="pb">
      <apex:pageblockButtons >
          <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageblockButtons>

    <apex:outputPanel id="op">
      <label style="display:block;margin-top:12px;" for="Name"><span style="color:red;">*</span>Account</label>
      <apex:inputField value="{!Account.Name}" id="accNa" styleclass="findclass"/>
      <label style="display:block;margin-top:12px;" for="Latitude__c"><span style="color:red;">*</span>Latitude</label>
      <apex:inputField value="{!Account.Latitude__c}" id="startLattt" styleclass="Latclass"/>
      <label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>
      <apex:inputField value="{!Account.Longitude__c}" id="startLonnn" styleclass="Lonclass"/>
    </apex:outputPanel>
  </apex:pageBlock>
  </apex:form>  
</apex:page>

=======================

There is another way for this uiing page block and sections. where you can use the ID selector to set the Lat and Lan :

Sample is below:

<apex:page id="pg" standardController="Account" extensions="AccountExtension">

  <script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementById('{!$Component.inpform.pb.pbs.startLat}').value=startPos.coords.latitude;
            document.getElementById('{!$Component.inpform.pb.pbs.startLon}').value=startPos.coords.longitude;

        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
  </script>


  <apex:form id="inpform">
  <apex:pageBlock title="Account Form" id="pb">
      <apex:pageblockButtons >
          <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageblockButtons>
  <apex:pageBlockSection title="AccountInformation" id="pbs">            
          <apex:inputField value="{!Account.Name}" id="accName"/>
          <apex:inputField value="{!Account.Phone}"/>
          <apex:inputField value="{!Account.Latitude__c}" id="startLat"/>
          <apex:inputField value="{!Account.Longitude__c}" id="startLon"/>
  </apex:pageBlockSection>
  </apex:pageBlock>
    
</apex:page>

Mark as best answer if it helps !!!!

Thanks,
Maharajan.C

All Answers

Maharajan CMaharajan C
Use the value instead of innerHtml :

    document.getElementById('startLat').value = startPos.coords.latitude;
    document.getElementById('startLon').value= startPos.coords.longitude;

Thanks,
Maharajan.C
Michael Hedrick 2Michael Hedrick 2
Hello Maharajan,
I made the changes as you suggested but I was still unable to get the LAt and long field values into the record.
Also, when I changed teh synatx from innerHtml to value I no longer see the Lat and long when I initiate the VF.
This is fine but not sure if that was the issue.

Thanks
Michael Hedrick 2Michael Hedrick 2
I am posting the VF page and Apex Class so that you can review it and determine if I have a syntax error.
Thank you for you.
<apex:page docType="html-5.0" standardController="Account" extensions="SourcingAuditAccountController"  standardstylesheets="false" lightningStylesheets="true" showheader="false">
    
<div id="startLat">
</div>

<div id="startLon">
</div>

<script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementById('startLat').value=startPos.coords.latitude;
            document.getElementById('startLon').value=startPos.coords.longitude;
        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
</script>
 
     
    <script type='text/javascript' src='/canvas/sdk/js/publisher.js'/>  
    <script>
        Sfdc.canvas.publisher.subscribe({name: "publisher.showPanel", onData:function(e) { 
            Sfdc.canvas.publisher.publish({name:"publisher.setValidForSubmit", payload:"true"}); 
        }});

        Sfdc.canvas.publisher.subscribe({ name: "publisher.post", onData: function(e) { 
            Sfdc.canvas.publisher.publish({name:"publisher.setValidForSubmit", payload:"false"}); 
            saveActivity();
        }});
    </script>
    <div>
        <apex:form id="SourcingAuditVF" >
            <apex:outputPanel id="out">
                <script>
                    function refreshFeed() { 
                        {!Close}
                        {!PostSaveMessage}
                                 
        };
                               
                </script>

                <apex:pageMessages ></apex:pageMessages>
                      
                <apex:actionFunction action="{!Save}"  name="saveActivity" rerender="out" oncomplete="refreshFeed();"/> 

                <apex:outputPanel >
                    <label style="display:block;margin-top:12px;" for="Contact__c">SourcingAudit Contact</label>
                    <apex:inputField style="margin-left:0;" id="Contact__c" value="{!SourcingAudit.Contact__c}" required="true"/>

                    <label style="display:block;margin-top:12px;" for="Quality_Bale_Issue__c">SourcingAudit Bale Issue</label>
                    <apex:inputField style="margin-left:0;" id="Quality_Bale_Issue__c" value="{!SourcingAudit.Quality_Bale_Issue__c}" required="true"/>                

                    <label style="display:block;margin-top:12px;" for="Bales_Inspected__c"><span style="color:red;">*</span>Bale Inspected</label>
                    <apex:inputField style="margin-left:0;" id="Bales_Inspected__c" value="{!SourcingAudit.Bales_Inspected__c}" required="true"/>
                    
                      <label style="display:block;margin-top:12px;" for="Volume_Reviewed__c">SourcingAudit Volume Review</label>
                    <apex:inputField style="margin-left:0;" id="Volume_Reviewed__c" value="{!SourcingAudit.Volume_Reviewed__c}" required="true"/>

                    <label style="display:block;margin-top:12px;" for="Weight_Issues__c">Weight Issue</label>
                    <apex:inputField style="margin-left:0;" id="Weight_Issues__c" value="{!SourcingAudit.Weight_Issues__c}" required="true"/>                

                    <label style="display:block;margin-top:12px;" for="Admin_review__c"><span style="color:red;">*</span>Admin review?</label>
                    <apex:inputField style="margin-left:0;" id="Admin_review__c" value="{!SourcingAudit.Admin_review__c}" required="true"/>
                    
                      <label style="display:block;margin-top:12px;" for="Referral__c"><span style="color:red;">*</span>Referral?</label>
                    <apex:inputField style="margin-left:0;" id="Referral__c" value="{!SourcingAudit.Referral__c}" required="true"/>
                    
                      <label style="display:block;margin-top:12px;" for="Latitude__c"><span style="color:red;">*</span>Latitude</label>
                    <apex:inputField style="margin-left:0;" id="startLat" value="{!SourcingAudit.Latitude__c}" />
                    
                     <label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>
                    <apex:inputField style="margin-left:0;" id="startLon" value="{!SourcingAudit.Longitude__c}" />
                </apex:outputPanel>   

                <apex:outputPanel >
                    
                </apex:outputPanel>       

                <apex:outputPanel >
                    <label style="display:block;margin-top:10px;" for="notes">Notes</label>
                    <apex:inputTextarea style="margin-left:0;" id="notes" rows="5" cols="30" value="{!Notes}" />
                </apex:outputPanel>

             <apex:outputPanel >
              <label style="display:block;margin-top:10px;" for="Latitude__c">Latitude</label>
                    <apex:outputText id="latitude">{!SourcingAudit.Latitude__c}
                    </apex:outputText>
              </apex:outputPanel>       

                <apex:outputPanel >
                    <label style="display:block;margin-top:10px;" for="account_name">Account</label>
                    <span style="margin-left:0;" id="account_name">{!Account.Name}</span>
                </apex:outputPanel> 
            </apex:outputPanel>
        </apex:form>
    </div>
</apex:page>
 
public class SourcingAuditAccountController{
    private Sourcing_Audit__c  SourcingAudit;
    private Account Account;
   

    public SourcingAuditAccountController(ApexPages.StandardController controller) 
    {
        Account = [SELECT Id, Name FROM Account WHERE Id =: controller.getId()];
        SourcingAudit = new Sourcing_Audit__c();
        SourcingAudit.Account__c = Account.Id;

      
        PostSaveMessage = '';

        // Default close behavior to re-enable the save button in case there was an error.  The save method 
        // replaces this if the save was successful.
        Close = 'Sfdc.canvas.publisher.publish({name:"publisher.setValidForSubmit", payload:"true"});';
    }  

    public string Notes {get; set;}
    public string PostSaveMessage {get; set;}
    public string Close {get; set;}

   
    public Sourcing_Audit__c  getSourcingAudit() {
        return SourcingAudit ;
    }    

    public Account getAccount() {
        return Account;
    }

    public PageReference Save()
    {
        System.debug('In Save method.');
        
        try {
            Insert SourcingAudit;

            if (Notes != null && Notes != '') {
                Note note = new Note();
                note.parentId = SourcingAudit.Id;
                note.body = Notes;
                note.title = Notes.abbreviate(50);
                note.isPrivate = false;
                Insert note;
            }

           

            // save succeeded, close the screen and refresh the host page on re-render.
            Close = 'Sfdc.canvas.publisher.publish({name : "publisher.close", payload : {refresh:"true"}});';
            return null;           
        } 
        catch (Exception ex) {
            string message = ex.getMessage();
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Fatal, message));
            return null;
        }
    }

   
}

 
Maharajan CMaharajan C
HI Micheel,

Sorry for the late reply:

Please try to use the Class instaed of id selector. It's working for me. i can able to populate the Lat and Longs in UI:

By using i can't able to assign the values . But if i am using the PageBlock, PB Section and InputField inside the apex form then i can set the value using the ID . You refer my Sample code:

Script :
 <script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementsByClassName('Latclass')[0].value =startPos.coords.latitude;
           document.getElementsByClassName('Lonclass')[0].value =startPos.coords.longitude;
        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
  </script>

VF Page : 
      <label style="display:block;margin-top:12px;" for="Latitude__c"><span style="color:red;">*</span>Latitude</label>
      <apex:inputField value="{!Account.Latitude__c}"  styleclass="Latclass"/>
      <label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>
      <apex:inputField value="{!Account.Longitude__c}" styleclass="Lonclass"/>

========================

The below is the Sample code i have tried in my org:


<apex:page id="pg" standardController="Account" extensions="AccountExtension">

  <script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementById('{!$Component.inpform.pb.pbs.startLat}').value=startPos.coords.latitude;
            document.getElementById('{!$Component.inpform.pb.pbs.startLon}').value=startPos.coords.longitude;
            //alert('@@@ ' + document.getElementsByClassName('findclass')[0].value);
            document.getElementsByClassName('Latclass')[0].value =startPos.coords.latitude;
           document.getElementsByClassName('Lonclass')[0].value =startPos.coords.longitude;


        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
  </script>


  <apex:form id="inpform">
  <apex:pageBlock title="Account Form" id="pb">
      <apex:pageblockButtons >
          <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageblockButtons>
  <apex:pageBlockSection title="AccountInformation" id="pbs">            
          <apex:inputField value="{!Account.Name}" id="accName"/>
          <apex:inputField value="{!Account.Phone}"/>
          <apex:inputField value="{!Account.Latitude__c}" id="startLat"/>
          <apex:inputField value="{!Account.Longitude__c}" id="startLon"/>
  </apex:pageBlockSection>
  </apex:pageBlock>
  
  <apex:outputPanel id="op">
      <label style="display:block;margin-top:12px;" for="Name"><span style="color:red;">*</span>Latitude</label>
      <apex:inputField value="{!Account.Name}" id="accNa" styleclass="findclass"/>
      <label style="display:block;margin-top:12px;" for="Latitude__c"><span style="color:red;">*</span>Latitude</label>
      <apex:inputField value="{!Account.Latitude__c}" id="startLattt" styleclass="Latclass"/>
      <label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>
      <apex:inputField value="{!Account.Longitude__c}" id="startLonnn" styleclass="Lonclass"/>
  </apex:outputPanel>
  </apex:form>
   
</apex:page>

Apex Class:

public class AccountExtension {

 public Account acc;

 public AccountExtension(ApexPages.StandardController st){
  this.acc = (Account) st.getRecord(); 
 }  
 
}

Thanks,
Maharajan.C
Michael Hedrick 2Michael Hedrick 2
Hello Maharajan,
Thnak you for the sample code.  
Will you explain the why it it nessesay to have 
<apex:inputField value="{!Account.Longitude__c}" id="startLon"/>
in the Page Block and then have 
<label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>
      <apex:inputField value="{!Account.Longitude__c}" id="startLonnn" styleclass="Lonclass"/>
in the Output panel?

It just seem reduntant to have the Lat and Long showuing twice on teh page.  If I hide the Page Block will the Lat and Long still be calculated?

Thank you for all your help. 
M
Maharajan CMaharajan C
Hi Micheal,

Don't get into the confusions:

You are using the Output panel so simply use Css Class selector to set the Lat and Lan in your page.

Sample is below :

<apex:page id="pg" standardController="Account" extensions="AccountExtension">

  <script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementsByClassName('Latclass')[0].value =startPos.coords.latitude;
            document.getElementsByClassName('Lonclass')[0].value =startPos.coords.longitude;

        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
  </script>

<apex:form id="inpform">
  <apex:pageBlock title="Account Form" id="pb">
      <apex:pageblockButtons >
          <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageblockButtons>

    <apex:outputPanel id="op">
      <label style="display:block;margin-top:12px;" for="Name"><span style="color:red;">*</span>Account</label>
      <apex:inputField value="{!Account.Name}" id="accNa" styleclass="findclass"/>
      <label style="display:block;margin-top:12px;" for="Latitude__c"><span style="color:red;">*</span>Latitude</label>
      <apex:inputField value="{!Account.Latitude__c}" id="startLattt" styleclass="Latclass"/>
      <label style="display:block;margin-top:12px;" for="Longitude__c"><span style="color:red;">*</span>Longitude</label>
      <apex:inputField value="{!Account.Longitude__c}" id="startLonnn" styleclass="Lonclass"/>
    </apex:outputPanel>
  </apex:pageBlock>
  </apex:form>  
</apex:page>

=======================

There is another way for this uiing page block and sections. where you can use the ID selector to set the Lat and Lan :

Sample is below:

<apex:page id="pg" standardController="Account" extensions="AccountExtension">

  <script>
    window.onload = function() {
        var startPos;
        var geoSuccess = function(position) {
            startPos = position;
            document.getElementById('{!$Component.inpform.pb.pbs.startLat}').value=startPos.coords.latitude;
            document.getElementById('{!$Component.inpform.pb.pbs.startLon}').value=startPos.coords.longitude;

        };
        navigator.geolocation.getCurrentPosition(geoSuccess);
    };
  </script>


  <apex:form id="inpform">
  <apex:pageBlock title="Account Form" id="pb">
      <apex:pageblockButtons >
          <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageblockButtons>
  <apex:pageBlockSection title="AccountInformation" id="pbs">            
          <apex:inputField value="{!Account.Name}" id="accName"/>
          <apex:inputField value="{!Account.Phone}"/>
          <apex:inputField value="{!Account.Latitude__c}" id="startLat"/>
          <apex:inputField value="{!Account.Longitude__c}" id="startLon"/>
  </apex:pageBlockSection>
  </apex:pageBlock>
    
</apex:page>

Mark as best answer if it helps !!!!

Thanks,
Maharajan.C
This was selected as the best answer
Michael Hedrick 2Michael Hedrick 2
Thank you for the clarification Maharajan.