Showing posts with label @RemoteAction. Show all posts
Showing posts with label @RemoteAction. Show all posts

Saturday, April 2, 2016

What is Visualforce Remote Objects.?

What is Visualforce Remote Objects.?


One of the exciting feature of Spring14 release is introduction of “Visualforce Remote Objects”. You can say its actually replacement of JavaScript Remoting.

Why do we need “Visualforce Remote Objects” when we already have “JavaScript Remoting” ?
Well, here are few advantages of “Visualforce Remote Objects” :
    1.    No need to write Controllers, Everything can be done in Visualforce only.
   2.    As @RemoteAction annotated methods needs to be static so you had to take special precaution as it didn’t supported Viewstate. This hurdle is completely removed now.
   3.    No need to write Test Class now, as no Controller is involved.
   4.    Not counted against API call

How to start with this ?
At time of writing this article, This feature is under Pilot release. So, you have to contact Salesforce support to enable it in your Organization.
Visualforce code Sample :

<!-- This Demo will assume Querying Account Object -->
<apex:remoteObjects>
<apex:remoteObjectModel name="Account" jsShorthand="getActs" fields="Name,Id">
 <apex:remoteObjectField name="ClientType__c" jsShorthand="cType">
</apex:remoteObjectModel>
</apex:remoteObjects>



you can see in above code, few new Visualforce tags are introduced like “remoteObjectModel” and “remoteObjectField“.
jsShorthand attribute defines shortcut that can be used inside your JavaScript code. Now, we don’t have to write annoying object or field name ending with “__c” or namespace name. This will keep our code tidy.
Javascript code Sample :

//Create new Remote Object Reference
var src = new SObjectModel.getActs();
 
//Use Remote Object to query 5 records
src.retrieve({
                        limit : 10,
                        where : {
                             cType :{
                                          eq : 'Banking'
                                                                            }
                                        }
                               } ,
                          function(err,records){
                               if(err == null)
                                  {
                                      //Process returned "records" to display in Visualforce code.
                                  }
} );


In above code, we are calling retrieve() method of Javascript object SObjectModel. Once you get records, you can process it in your javascript. Other than retrieve() , you can perform all CRUD operations on object.
You can see below articles also on same topic.


Let test this features quickly on our own, by designing a visualforce page.  Here I have designed a page that pulls up ten accounts from Salesforce solely by using JavaScript Remote Objects (see picture below)

Just copy-paste the code in your org to test this by yourself. I am querying Accounts (standard object) and using bootstrap CDN (check what is bootstrap and cdn go to bootstrap site to style the page. At the moment, I wrote retrieve() operation that pulls ten records, soon ill update the code will perform all sort of DML operation mentioned in the documentation.


Test on Salesforce 1 :  this works like charm on Salesforce 1







<apex:page sidebar="false" showHeader="false" standardStylesheets="false">
   <apex:includeScript value="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"/>
   <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" media="screen"/>
   <style>
      .wrapper
      {
      text-align : center;
      }
   </style>
   <!-- lets query Salesforce Contact using remoting objects -->
   <!--Lets add up Amount field on Contact objects here using shorthand amt-->
   <apex:remoteObjects >
      <!--Name the field you like to query-->
      <apex:remoteObjectModel name="Account" jsShorthand="acc" fields="Id,Name,BillingState, Phone"/>
   </apex:remoteObjects>
   <!-- now address you field with shorthand -->
   <script>
      function clearList()
      {
          if(!$('#cList').empty())
          {
              //if non-empty then clear list before every call
              $('#cList').empty();
          }
      }
     
      var DML = function(){
          //clear old list beforehand
          clearList();
          //Instantiate a reference
          var data = new SObjectModel.acc();
          //process the data received in return
          data.retrieve({ limit: 10 } ,function(err, records){
              //if failure
              if(err) alert(err.message);
              else {
                  populate(records);      
              }
          });
         
          //Method to Pouplate Records
          function populate(records)
          {
              var ul = document.getElementById("cList");
              records.forEach(function(record) {
                  // Build the text for a warehouse line item
                  var toAdd = record.get("Name");
                  // Add the line item to the warehouses list
                  var rule = document.createElement("br");
                  var li = document.createElement("li");
                  li.appendChild(document.createTextNode(toAdd));
                  ul.appendChild(li);
                  ul.appendChild(rule);
              });
          }
      }
     
   </script>
   <div class="jumbotron">
      <h1>Retrieve Contacts via Remote Objects</h1>
      <p>via Remote Objects</p>
      <a href="#" class="list-group-item active">
         <h4 class="list-group-item-heading">What is Remote Object?</h4>
         <p class="list-group-item-text">Visualforce Remote Objects are proxy objects that allow basic DML operations on sObjects directly from JavaScript. Remote Objects take some of the complexity out of JavaScript remoting, by reducing the need for @RemoteAction methods in an Apex controller or extension. Like JavaScript remoting, <br/> Remote Objects calls don’t count towards API request limits.</p>
      </a>
      <br/>
      <div class="wrapper">
         <p> <button  class="btn btn-success btn-lg" onclick="DML()"> <span class="glyphicon glyphicon-star"></span>Pull
            Accounts</button>
         </p>
      </div>
   </div>
   <a href="#" class="list-group-item active">
   <span class="glyphicon glyphicon-list"></span> Accounts:
   </a>
   <div class="wrapper">
      <ul class="list-inline" id="cList">
      </ul>
   </div>
</apex:page>




Saturday, December 27, 2014

What is @RemoteAction in Salesforce?

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}.


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:











 
| ,