2

I want to call a apex method with parameters from my script in a visualforce page and use the return value to feed a inputField. I tried to explain it in the code here(hope you understand my request):

<script src="https://maps.googleapis.com/maps/api/js?language=de&sensor=false&libraries=places" type="text/javascript"></script>  

<script type="text/javascript"> 

    var options = {
      types: ['(cities)']         
    };

    function findLocation() {
        var components = this.getPlace().address_components,
        city = 'n/a';
        country = 'n/a';
        if (components) {
            for (var c = 0; c < components.length; ++c) {
                console.log(components[c].types.join('|'))
                if (components[c].types.indexOf('locality') > -1) {
                    city = components[c].long_name;
                }
                if(components[c].types.indexOf('country') > -1 && components[c].types.indexOf('political') > -1 ) {
                    country = components[c].long_name;
                }
            }
        }

        /*
            Here i want to call the 'findLocation' Method of the 'LocationFinder' Class
            The Method looks like this:
                public static String findLocation(String city, String country) {

                    ...

                    return result;
                }
            I want to commit the 'city' and the 'country' parameter and I get the Location.
            This return value I want to put into the hidden inputField with the 'locationField' ID

        */

    }

    function initialize() {

        var autocomplete = new google.maps.places.Autocomplete(document.getElementById('expenseEditPage:f1:pb1:pbsAccommodation:field5')); 
        google.maps.event.addListener(autocomlete, 'place_changed', findLocation);

    }
    google.maps.event.addDomListener(window, 'load', initialize);  

</script>

<apex:sectionHeader title="Expense Edit" subtitle="{!recordtypename} Expense"/>

<apex:form id="f1">
    <apex:pageBlock id="pb1" mode="edit" title="Expense Edit">

        <apex:pageMessages />

        <apex:pageBlockButtons >
            <apex:commandButton value="Save" action="{!save}"/>
            <apex:commandButton value="Cancel" action="{!cancel}"/>                
        </apex:pageBlockButtons>

        <apex:pageBlockSection rendered="false" id="pbsHidden">
            <apex:outputField value="{!Expense__c.RecordType.Name}"/>
            <apex:outputField value="{!Expense__c.RecordType.DeveloperName}"/>
            <apex:inputField value="{!Expense__c.lkp_Location__c}" id="locationField"/>
        </apex:pageBlockSection>

        <apex:pageBlockSection columns="2" id="pbsAccommodation" rendered="{!recordtypename == 'Accommodation'}">
            <apex:outputField value="{!Expense__c.mdr_Travel__c}"/>                               
            <apex:inputField value="{!Expense__c.txt_LodgingAdress__c}" style="width:100%" id="field5" required="true"/>
            <apex:inputField value="{!Expense__c.dat_CheckInDate__c}" required="true"/>
            <apex:inputField value="{!Expense__c.dat_CheckOutDate__c}" required="true"/>
            <apex:inputField value="{!Expense__c.cur_Amount__c}" required="true"/>
            <apex:inputField value="{!Expense__c.pct_TaxPercentage__c}" required="true"/>
            <apex:inputField value="{!Expense__c.CurrencyIsoCode}" required="true"/>
            <apex:inputField value="{!Expense__c.pkl_Reimbursement__c}" required="true"/>
        </apex:pageBlockSection>

    </apex:pageBlock>
</apex:form>

1

If you add this method to your page's controller:

global with sharing class MyController {
    @RemoteAction
    global static String findLocation(String city, String country) {
         // Execute Apex logic here using only "city" and "country"
         return ...
    }
}

then Visualforce will generate a JavaScript function (named MyController.findLocation) that you can just call e.g. from your other findLocation function:

function findLocation() {
    var city;
    var country;
    ...
    MyController.findLocation(city, country, function(result, event) {
        // Set the inputField value to the result in here
    });
    ...
}

This is the JavaScript Remoting for Apex Controllers approach mentioned in Seb__Wagner's answer. It has the (performance) advantage that no view state is transmitted: you just pass the values needed and it performs its action and returns the result (via a callback function).

  • I tried it that way, but the findLocation in my controller was never called. I put some debug statements at the beginning of the method, but nothing happens. – David Renz Apr 22 '14 at 13:26
  • @DavidRenz I presume you mean you added debug output to your Apex? Have you confirmed that there are no errors in your browser's JavaScript console and that the MyController.findLocation is called there. (You can use console.log to output debug output on the client side.) – Keith C Apr 22 '14 at 13:31
  • Yes, I also tried a alert right before the method gets called in the script and a debug output right after the method was called in the apex code. I get the alert, but i did not get the debug output. The method call looks like this: ExpenseCtrlExt.findLocation(city, country, new function(result, event) {});) – David Renz Apr 22 '14 at 13:43
  • @DavidRenz OK. Next thing to look at is the remote call. In Chrome the "Developer Tools" include a "Network" tab. If you click the round "Record Network Log" button at the top left of this tab and then test, you should see an "apexremote" log that if you click on you can check the request and response and perhaps see any error there. – Keith C Apr 22 '14 at 13:51
  • @DavidRenz Yeah you will not see any output directly after the ExpenseCtrlExt.findLocation call; return values are available some time later (asynchronously) inside the callback function. So your alert should display the return value (or perhaps the return value wrapped in something; if the latter you can use alert(JSON.stringify(result)) to show the structure). So you must update your input field from inside that callback. – Keith C Apr 22 '14 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.