Sunday, July 2, 2017

What is @RemoteAction in Salesforce?

What is difference between Action function and remote function?



1. Using action function, you can call only same class function.
2. Remote Action returns the results from the class in Javascript.
3. Action function submit the page, Remote action doesn't

Remote Action in Visual force page:
JavaScript remoting in Visualforce provides support for some methods in Apex controllers to be called via JavaScript.

• namespace is your organization's namespace. This is only required if the class comes from an installed packaged.
• controller is the name of your Apex controller- MyJSControllers
• method is the name of the Apex method you're calling- getAccount
• params is comma–separated list of parameters that your method takes-accountNameJS
• callbackFunction is the name of the function that handles the response from the controller. It returns the status of the call and the method result.- function
• escape defines whether your response should be escaped (by default, true) or not (false)- {escape:true}

·    JavaScript remoting:
- pass parameters
- provides a callback
·        The <apex:actionFunction> tag:
- specify rerender targets
- submits the form


What is @RemoteAction in Salesforce and when we are going to use this @RemoteAction?

JavaScript remoting in Visualforce provides support for some methods in Apex controllers to be called via JavaScript.

JavaScript remoting has three parts:
  •  The remote method invocation you add to the Visualforce page, written in JavaScript.
  • The remote method definition in your Apex controller class. This method definition is written in Apex, but there are few differences from normal action methods.
  • The response handler callback function you add to or include in your Visualforce page, written in JavaScript.
To use JavaScript remoting in a Visualforce page, add the request as a JavaScript invocation with the following form:
[namespace.]controller.method(    [parameters...,]    callbackFunction,    [configuration]);
  • namespace is the namespace of the controller class. This is required if your organization has a namespace defined, or if the class comes from an installed package.
  • controller is the name of your Apex controller.
  •  method is the name of the Apex method you’re calling.
  • parameters is the comma-separated list of parameters that your method takes.
  • callbackFunction is the name of the JavaScript function that will handle the response from the controller. You can also declare an anonymous function inline. callbackFunction receives the status of the method call and the result as parameters.
  • configuration configures the handling of the remote call and response. Use this to specify whether or not to escape the Apex method’s response. The default value is {escape: true}.
-------------------------------------

1. What is the use Javascript Remoting ?
 A) You can communicate with VF page's controller's methods without posting your form. Action Function posts the data.

2. If more flexible, When we need to use ?
A) JS remoting is not an alternate for Action function. There may arise a case in requirement to get/set some information or basically to perform an from controller without actually posting the form.

3. What is the use of Actionfunction ?
A) It posts data to to the controller. Unlike JS remoting you can rerender certain portions of your VF page. Because of this particual page rendering you can get refreshed values from server.

4. What is the diffrenece between Actionfunction and Javascript remoting ?
A)
i) Action function posts the form and JS Remoting does not
ii) Action function can do partial page rerendering which JS remoting can not.

5. JS remoting used for mainly calling the APEX method from javascript ? if yes what s the benefits ? can u please let me know real time scanerio ?
A)
i) Auto-complete search. for e.g. to list the articles titles while 
ii) Any scenario where you dont want to refresh the page/no partial page rendering and just want to perform an action.
iii) Any scenario where you need to repetitively call controller without a need to rerender.
iv) There is a possibility to avoid View-State issue when you use JS remoting because you will just give back the data to the user but not keep it on the server which mounts to View-State.

---------------------------------------------

JavaScript Remoting Example

Here’s a basic sample demonstrating how to use JavaScript remoting in your Visualforce pages.
First, create an Apex controller called AccountRemoter:
01global with sharing class AccountRemoter {
02 
03    public String accountName { get; set; }
04    public static Account account { get; set; }
05    public AccountRemoter() { } // empty constructor
06     
07    @RemoteAction
08    global static Account getAccount(String accountName) {
09        account = [SELECT Id, Name, Phone, Type, NumberOfEmployees
10                   FROM Account WHERE Name = :accountName];
11        return account;
12    }
13}
Other than the @RemoteAction annotation, this looks like any other controller definition.
To make use of this remote method, create a Visualforce page that looks like this:
01<apex:page controller="AccountRemoter">
02    <script type="text/javascript">
03    function getRemoteAccount() {
04        var accountName = document.getElementById('acctSearch').value;
05 
06        Visualforce.remoting.Manager.invokeAction(
07            '{!$RemoteAction.AccountRemoter.getAccount}',
08            accountName,
09            function(result, event){
10                if (event.status) {
11                    // Get DOM IDs for HTML and Visualforce elements like this
12                    document.getElementById('remoteAcctId').innerHTML = result.Id
13                    document.getElementById(
14                        "{!$Component.block.blockSection.secondItem.acctNumEmployees}"
15                        ).innerHTML = result.NumberOfEmployees;
16                else if (event.type === 'exception') {
17                    document.getElementById("responseErrors").innerHTML =
18                        event.message + "<br/>\n<pre>" + event.where "</pre>";
19                else {
20                    document.getElementById("responseErrors").innerHTML = event.message;
21                }
22            },
23            {escape: true}
24        );
25    }
26    </script>
27 
28    <input id="acctSearch" type="text"/>
29    <button onclick="getRemoteAccount()">Get Account</button>
30    <div id="responseErrors"></div>
31 
32    <apex:pageBlock id="block">
33        <apex:pageBlockSection id="blockSection" columns="2">
34            <apex:pageBlockSectionItem id="firstItem">
35                <span id="remoteAcctId"/>
36            </apex:pageBlockSectionItem>
37            <apex:pageBlockSectionItem id="secondItem">
38                <apex:outputText id="acctNumEmployees"/>
39            </apex:pageBlockSectionItem>
40        </apex:pageBlockSection>
41    </apex:pageBlock>
42</apex:page>
Notice the following about this markup:
  • The JavaScript uses the explicit invokeAction remoting call, and takes advantage of the $RemoteAction global to resolve the correct namespace for the remote action method.
  • The event.status variable is true only if the call was successful. The error handling illustrated by the example is deliberately simple and prints the error message and stack trace from the event.message and event.where values, respectively. You’re encouraged to implement more robust alternative logic for requests where your method call doesn’t succeed.
  • The result variable represents the object returned from the Apex getAccount method.
  • Accessing the DOM ID of a plain HTML element is simple, just use the ID of the item.
  • DOM IDs of Visualforce components are dynamically generated in order to ensure IDs are unique. The code above uses the technique illustrated in Using $Component to Reference Components from JavaScript to retrieve the component’s ID by accessing it via the $Component global variable.
---------------------------------------------


Example 1:

Visualforce Page:

<apex:page controller="AccountRemoteActionController">
    <script type="text/javascript">
    function getAccountJS() 
    {
        //get the values of input text and place into the variable.
        var accountNameJS = document.getElementById('accName').value;        
        AccountRemoteActionController.getAccount( accountNameJS, 
        function(result, event)
        {
        
          alert('event.status==>'+event.status);
          alert('event.type === '+event.type);
          alert('event.message ==>'+event.message);
            if (event.status) 
            {
                // demonstrates how to get ID for HTML and Visualforce tags
                document.getElementById("{!$Component.theBlock.thePageBlockSection.theFirstItem.accId}").innerHTML = result.Id;
                document.getElementById("{!$Component.theBlock.thePageBlockSection.theSecondItem.accNam}").innerHTML = result.Name;
            } 
            else if (event.type === 'exception') 
            {
                document.getElementById("errors-js").innerHTML = event.message;
            } else 
            {
                document.getElementById("errors-js").innerHTML = 'No Records Found..';
            }
        }, {escape:true});
    }
    </script>
    Account Name :<input id="accName" type="text" />
    <button onclick="getAccountJS()">Get Account</button>
    <div id="errors-js"> </div>
    <apex:pageBlock id="theBlock">
        <apex:pageBlockSection id="thePageBlockSection" columns="2">
            <apex:pageBlockSectionItem id="theFirstItem">
                <apex:outputText id="accId"/>
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem id="theSecondItem" >
                <apex:outputText id="accNam" />
            </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>

Controller Class:

global class AccountRemoteActionController
{
    public String accountName { get; set; }
    public static Account account { get; set; }
    //Default Constructor..
    public AccountRemoteActionController() {
    
    }
    
    @RemoteAction
    global static Account getAccount(String accountName) 
    {
        account = [select id, name, phone, type, numberofemployees from Account where name = :accountName ];
        return account;
    }
}


Out Put:

RemoteAction


Example 2:

In this example once the user selected a particular opportunity stage name then calling the remote method from java script and print the opportunity details in table format.

Visualforce Page :

<apex:page controller="OpportunityRemoteActionController" showHeader="true"> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> function getStageJS(){ var oppStage= document.getElementById("{!$Component.theFm.oppStage}").value; alert("stageName==>"+oppStage); OpportunityRemoteActionController.getOpportunityDetails( oppStage, function(result, event){ // alert("event.status==>"+event.status); // alert("event.result==>"+event.result); var html = '<table border="thick solid">'; html = html + '<caption><b>Opportunity Details</b></caption><tr></tr>'; html = html + '<tr><th>Opportunity Name</th>'; html = html + '<th>Amount</th> </tr>'; if (event.status && event.result) { debugger; // alert("event.result[0].Name==>"+event.result[0].Name); for (var prop in event.result) { // important check that this is objects own property not from prototype prop inherited //alert(prop + " = " + event.result[prop].Name); html = html + '<tr><td><a href="'+event.result[prop].Name+'</td> <td>'+event.result[prop].Amount+'</td></tr> '; } html = html + '</table>'; // alert("html==>"+html); $("#opportunityDetails").html(html); } else { alert(event.message); } }, {escape:true}); } </script> <div align="center" width="550px"> <apex:form id="theFm"> <apex:selectList value="{!stageName}" size="1" id="oppStage" onchange="getStageJS()"> <apex:selectOptions value="{!options}"/> </apex:selectList> </apex:form> </div> <br/> <br/> <div id="opportunityDetails" align="center"> <!-- Opportunity details is displayed here. --> </div> </apex:page>

Controller Class:

global with sharing class OpportunityRemoteActionController { public Opportunity opp{get;set;} public String stageName{get;set;} public OpportunityRemoteActionController() { } /** * Method that creates the select option dynamically. **/ public List<SelectOption> getOptions() { List<SelectOption> options = new List<SelectOption>(); Schema.DescribeFieldResult fieldResult = Opportunity.StageName.getDescribe(); List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); options.add(new SelectOption('--Select--', '--Select--')); for( Schema.PicklistEntry f : ple) { //system.debug('f.getLabel()=>'+f.getLabel() +' ==f.getValue()' +f.getValue()); options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Remote action involved with Javascript remoting and is made global **/ @RemoteAction global static Opportunity[] getOpportunityDetails(String stageNameDet) { return [select id,Name,Amount,stageName from Opportunity WHERE stageName =: stageNameDet]; } }


Output:






No comments:

Post a Comment