Concepts or coding lessons of Salesforce that you can implement easily

Learning Pagination In Salesforce Is Not Difficult At All ! You Just Need 3 Easy Steps

It is very easy to implement pagination using standard set controller provided by salesforce in visualforce page. You can decide how many records should be displayed in every page also you can easily navigate through pages, move directly to first, last page or to next or previous pages using standard set controller. 

Pagination is very useful when you want to display 1000+ records on visual force page. Without pagination if you try to display 1000+ records on visualforce page then you face visualforce error "Collection size xxxx exceeds maximum size of 1000"

Below example displaying all opportunities in visualforce page with pagination. Default page size 10.

Step 1: Create apex class

public class OpportunitiesPaginationController{
    Public Integer size{get;set;} 
    Public Integer noOfRecords{get; set;} 
    public List<SelectOption> paginationSizeOptions{get;set;}
         
    public OpportunitiesPaginationController(){
        size=10;
        paginationSizeOptions = new List<SelectOption>();
        paginationSizeOptions.add(new SelectOption('5','5'));
        paginationSizeOptions.add(new SelectOption('10','10'));
        paginationSizeOptions.add(new SelectOption('20','20'));
        paginationSizeOptions.add(new SelectOption('50','50'));
        paginationSizeOptions.add(new SelectOption('100','100'));
    }
     
    public ApexPages.StandardSetController setCon {
        get {
            if(setCon == null) {                
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                      [select id,Name,AccountId,Account.name,Amount,StageName,CloseDate from Opportunity]));
                setCon.setPageSize(size);  
                noOfRecords = setCon.getResultSize();
            }            
            return setCon;
        }
        set;
    }
     
    //Changes the size of pagination
    public PageReference refreshPageSize() {
         setCon.setPageSize(size);
         return null;
    }
    // Initialize variable setCon from below method and return a list of opportunity record    
     
    public List<Opportunity> getOpportunities() {
         return (List<Opportunity>) setCon.getRecords();
    }
}


Step 2: Create Visualforce Page


<apex:page controller="OpportunitiesPaginationController" tabStyle="Opportunity" sidebar="false">
    <apex:form >
        <apex:actionFunction name="refreshPageSize" action="{!refreshPageSize}" status="fetchStatus" reRender="pbId"/>
        <apex:pageBlock id="pbId">
            <apex:pageBlockSection title="All Opportunities" collapsible="false" columns="1">
                <apex:pageBlockTable value="{!Opportunities}" var="oppObj">
                     
                    <apex:column headerValue="Opportunity Name">
                        <a href="/{!oppObj.id}" target="_blank" ><apex:outputField value="{!oppObj.Name}"/></a>
                    </apex:column>
                     
                    <apex:column headerValue="Account Name">
                        <a href="/{!oppObj.AccountId}" target="_blank" ><apex:outputField value="{!oppObj.Account.name}"/></a>
                    </apex:column>
                     
                    <apex:column headerValue="Amount">
                        <apex:outputField value="{!oppObj.Amount}"/>
                    </apex:column>
                     
                    <apex:column headerValue="Stage">
                        <apex:outputField value="{!oppObj.StageName}"/>
                    </apex:column>
                     
                    <apex:column headerValue="Close Date">
                        <apex:outputField value="{!oppObj.CloseDate}"/>
                    </apex:column>
                </apex:pageBlockTable>
                 
                <apex:panelGrid columns="8"> 
                 
                <apex:selectList value="{!size}" multiselect="false" size="1" onchange="refreshPageSize();">
                    <apex:selectOptions value="{!paginationSizeOptions}"/>
                </apex:selectList>
                 
                <apex:commandButton status="fetchStatus" reRender="pbId" value="First" action="{!setCon.first}" disabled="{!!setCon.hasPrevious}" title="First Page"/> 
  
                <apex:commandButton status="fetchStatus" reRender="pbId" value="Previous" action="{!setCon.previous}" disabled="{!!setCon.hasPrevious}" title="Previous Page"/> 
  
                <apex:commandButton status="fetchStatus" reRender="pbId" value="Next" action="{!setCon.next}" disabled="{!!setCon.hasNext}" title="Next Page"/> 
  
                <apex:commandButton status="fetchStatus" reRender="pbId" value="Last" action="{!setCon.last}" disabled="{!!setCon.hasNext}" title="Last Page"/> 
  
                <apex:outputText >{!(setCon.pageNumber * size)+1-size}-{!IF((setCon.pageNumber * size)>noOfRecords, noOfRecords,
                     (setCon.pageNumber * size))} of {!noOfRecords}
                </apex:outputText> 
                       
                <apex:outputPanel >                      
                    <apex:actionStatus id="fetchStatus" >
                        <apex:facet name="start" >
                          <img src="/img/loading.gif" />                    
                        </apex:facet>
                    </apex:actionStatus>
                </apex:outputPanel> 
  
            </apex:panelGrid>  
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>


Step 3: Click on Preview button of visualforce page



Or 
You can Go to the URL and type (Change the yoursalesforceinstance with your salesforce org URL)

https://yoursalesforceinstance.com/apex/OpportunitiesPagination.













When you use pagination, an exception is thrown when there are modified rows in the collection. This includes any new rows added to the collection through an extension action. The handling of error messages in this case follows the standard behavior and can either be displayed upon the page. For example, you can use the <apex:pageMessages> or <apex:messages> component to display an error message to the user.


Pros and Cons of Choosing This Pagination Tool


Pros:
  • Manages data sets on the server, which reduces page state and increases performance
  • Allows you to paginate over large data sets that have up to 10,000 records
  • Includes built-in functionality such as next, previous, first, last, getResultSize, and other methods that can simplify your page
  • Allows you to paginate forward and backward or to any page within the result set
  • Uses a server-side cursor to cache the entire result set, so results will not change if data changes in the database while a user is paginating from one page to the next.
Cons:
  • Has built-in functionality that results in a very small increase in view state size
  • Can be used only in Apex.

There is a good article about pagination in Apex here: https://developer.salesforce.com/page/Paginating_Data_for_Force.com_Applications that lists various options.

Enjoy! If you have any questions, comments, please feel free to let me know. 

As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.

Next post: How To Learn Get Field Values From Visualforce Page To Apex Class Controller Without Losing Your Mind

How To Learn Get Field Values From Visualforce Page To Apex Class Controller Without Losing Your Mind

Here I am explaining Get Field Values From Visualforce Page To Apex Class Controller. Below is the sample code snippet, I have created one controller class and one visual force page associated with it. 

Visual force page has to Submit button. 


Once a user clicks on the button, I am sending email using apex code. 
Check below sample code:



Step 1. Create Apex Controller with name passparamFromVFtoController

Public with sharing class passparamFromVFtoController {
  Public string myInputQueryString{get;set;}
  Public string myoutputString{get;set;}
   
  Public void myInputQuery(){
   System.debug("Inserted string is :- "+ myInputQueryString);
   myoutputString = myInputQueryString ;
   System.debug("Output string is :- "+ myoutputString);
  }
}

Step 2. Create Visualforce Page with name passparamFromVFtoController
<apex:page controller="passparamFromVFtoController" sidebar="false" showHeader="false">
  <!-- Pass parameters from visualforce page to controller -->
  <apex:form >
    <apex:pageblock >
     Input your question=> <apex:inputText value="{!myInputQueryString}"/>
     <apex:commandButton value="Submit" reRender="DisplayInputQueryID" action="{!myInputQuery}"/>
    </apex:pageblock>
     <apex:pageblock >
       <b>Output : </b><apex:outputText value="{!myoutputString}" id="DisplayInputQueryID"/>
     </apex:pageblock>
    </apex:form>
</apex:page>

Output :

You can click on Preview button which is on Visualforce page 
OR 
You can Go to the URL and type (Change the salesforceinstancename with your salesforce org URL).


Go to : https://salesforceinstancename/apex/passparamFromVFtoController.



There is another way: JavaScript Remoting


JavaScript Remoting is a framework or tool that front end developers can use to make an AJAX request from a Visual force page directly to an Apex controller. JavaScript remoting allows you to run asynchronous action by separating the page from the controller and to perform tasks on the page without having reloading the entire page.
JavaScript Remoting is the well-organized and competent way of calling the controller in an asynchronous manner and passing data in from the page, because you are sure that you are passing only that data which you need each time that you make a call.

Step 1: Create an Apex controller called AccountRemoterClass

global with sharing class AccountRemoterClass {

    public String accountName { get; set; }
    public static Account account { get; set; }
    public AccountRemoterClass () { } // empty constructor
    
    @RemoteAction
    global static Account getAccount(String accountName) {
        account = [SELECT Id, Name, Phone, Type, NumberOfDepartments__c 
                   FROM Account WHERE Name = :accountName];
        return account;
    }

}

Step 2: Create a Visualforce page that looks like this:

<apex:page controller="AccountRemoterClass">
    <script type="text/javascript">
    function getRemoteAccount() {
        var accountName = document.getElementById('accountSearch').value;

        Visualforce.remoting.Manager.invokeAction(
            '{!$RemoteAction.AccountRemoterClass.getAccount}',
            accountName, 
            function(result, event){
                if (event.status) {
                    // Below line fetch Visualforce elements and DOM IDs for HTML
                    document.getElementById('remoteAcctId').innerHTML = result.Id
                    document.getElementById(
                        "{!$Component.block.blockSection.secondItem.acctNumEmployees}"
                        ).innerHTML = result.NumberOfEmployees;
                } else if (event.type === 'exception') {
                    document.getElementById("responseErrors").innerHTML = 
                        event.message + "<br/>\n<pre>" + event.where + "</pre>";
                } else {
                    document.getElementById("responseErrors").innerHTML = event.message;
                }
            }, 
            {escape: true}
        );
    }
    </script>

    <input id="accountSearch" type="text"/>
    <button onclick="getRemoteAccount()">Get An Account</button>
    <div id="responseErrors"></div>

    <apex:pageBlock id="block">
        <apex:pageBlockSection id="blockSection" columns="2">
            <apex:pageBlockSectionItem id="firstItem">
                <span id="remoteAcctId"/>
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem id="secondItem">
                <apex:outputText id="acctNumEmployees"/>
            </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
    </apex:pageBlock>

</apex:page>

Below are the JavaScript Remoting Limits:


Remote call`s default response time is 30 seconds. If remote call taking longer time than 30 seconds then you will get a time out exception.
If your request requires more time to complete the transaction, then configure a longer timeout. You can setup it to 120 seconds. 
Most of the interviewer asks the question, what is the maximum response size of your remote call ?
Answer is : maximum 15 MB.

Enjoy! If you have any questions, comments etc. please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.





Schedulable Batch Apex In 3 Easy steps In Salesforce

There are three main steps involved in Schedulable Batch Apex

1. Write a Batch Class
2. Write a Scheduled Apex class which execute the above Batch Class
3. Schedule the Scheduled Apex class from the Developer Console or from UI

So here we go...

Step 1. Write Batch Class

global class BatchApexClassExample implements Database.Batchable<SObject>{
 global Database.QueryLocator start(Database.BatchableContext BC) { 
  String soqlquery = 'SELECT Id, name, phone FROM Account';
  return database.getquerylocator(soqlquery);
 }
 // The batch job executes and operates on one records batch of max 200
 global void execute(Database.BatchableContext BC, List<SObject> scope) { 
   // your logic
   System.debug('In BatchApexClassExample - Execute Method ');
 }
 // The batch job finishes
 global void finish(Database.BatchableContext BC) { 
   System.debug('BatchApexClassExample Batch job completed successfully.');

Step 2. Write a Scheduled Apex which execute the above Batch Class

global with sharing class ScheduleBatchApexClassExample implements Schedulable {
 global void execute(SchedulableContext sc) {
  ID BatchId = Database.executeBatch(new BatchApexClassExample(), 200);
 }
}

Step 3. Schedule the class from the Developer Console or from UI
  •  From UI : Go to Setup -> Apex Classes -> Click on Schedule Apex button
  •  From Developer Console, check below 
 Execute a schedulable Apex class with System.schedule method

 System.schedule('ScheduleBatchApexClassExampleScheduler', '0 0 * * * ?', new ScheduleBatchApexClassExample());

Good job, we are done. 

If you want to see your batch job scheduled then 

  • Go to Setup—>Monitor –> Scheduled Jobs

If you want to Schedule a Class in Every 5 Mins in Salesforce, since this is not possible to do through standard Salesforce User interface.


Yes I have solution for it. Use above small code snippets to do so for every 5 minutes.


Check my next post Run Schedule a Class In Every 5 Mins in Salesforce

Some important things about Schedulable Batch Apex :


Syntax for CRON expression:

Seconds Minutes Hours Day Month Week Year

Year is optional.


Seconds                         :- 0–59
Minutes                         :- 0–59
Hours                         :- 0–23
Day (Day_of_month) :- 1–31
Month                         :- 1–12
Week (Day_of_week)         :- 1–7

Year                             :- null or 1970–2099

The following are some examples of cron expressions:

ExpressionDescription
0 0 13 * * ?Class runs every day at 1 PM.
0 0 22 ? * 6LClass runs the last Friday of every month at 10 PM.
0 0 10 ? * MON-FRIClass runs Monday through Friday at 10 AM.
0 0 20 * * ? 2010Class runs every day at 8 PM during the year 2010.
Apex Scheduler Limits:


  • You can only have maximum 100 scheduled Apex jobs at one time.
  • The maximum number of scheduled Apex executions per a day or 24-hour period is 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater in number.

Apex Scheduler Notes and Best Practices:


  • Salesforce schedules the apex class for execution at the specified time. Actual execution may be delayed based on salesforce service availability.
  • In Salesforce, Synchronous Web service callouts are not supported from scheduled Apex class. To be able to make callouts, make an asynchronous callout by placing @future(callout=true) annotation in class method and call this method from scheduled Apex class.
  • If any apex jobs scheduled to run during a Salesforce service maintenance downtime, those will be scheduled to run after the service comes online again, when system resources become available.
Enjoy! If you have any questions, comments, please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.

Next post: Run Schedule a Class In Every 5 Mins in Salesforce

Run Schedule a Class In Every 5 Mins in Salesforce

You can run apex job every 1-hour using CRON expression by default but you can schedule this job 12 times in one hour at 5 min duration.

If you are not aware of Schedulable Batch Apex then first look Schedulable Batch Apex In 3 Easy steps In Salesforce


Then how to Schedule a Class in Every 5 Mins in Salesforce, since this is not possible to do through the standard Salesforce User interface.

Yes, I have a solution for it. So here is a small code to do so for every 5 minutes.

Example, you have Scheduler class ScheduleBatchApexClassExample which is in my other blog and want to run the schedule a class in every five mins, then use below CRON expression.

How to run follow below process:


Go to your developer console -> Open Execute Anonymous Window -> Copy and Paste Below code and click on execute button

Simply say, Run below CRON expression from your developer console:



System.schedule('Schedule Job Name 1',  '0 00 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 2',  '0 05 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 3',  '0 10 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 4',  '0 15 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 5',  '0 20 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 6',  '0 25 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 7',  '0 30 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 8',  '0 35 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 9',  '0 40 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 10', '0 45 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 11', '0 50 * * * ?', new ScheduleBatchApexClassExample());
System.schedule('Schedule Job Name 12', '0 55 * * * ?', new ScheduleBatchApexClassExample());

After this, if you want To check apex class in scheduled or not then:
Go to -> Setup -> Jobs -> Scheduled Jobs















So Easy !!!

Some important things of System.schedule :


To Run Schedule a Class In Every 5 Mins in Salesforce, you have to use System.schedule method. System.schedule method is used to executes a Apex class. 

System.schedule('ScheduleBatchApexClassExampleScheduler', '0 0 * * * ?', new ScheduleBatchApexClassExample());

If you want to see your batch job scheduled then 
  • Go to Setup—>Monitor –> Scheduled Jobs
Syntax for CRON expression:

Seconds Minutes Hours Day Month Week Year


Year is optional.

The following are some examples of cron expressions:
ExpressionDescription
0 0 13 * * ?Class runs every day at 1 PM.
0 0 22 ? * 6LClass runs the last Friday of every month at 10 PM.
0 0 10 ? * MON-FRIClass runs Monday through Friday at 10 AM.
0 0 20 * * ? 2010Class runs every day at 8 PM during the year 2010.

Enjoy! If you have any questions, comments etc. please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.

An Introduction to Visualforce View State in Salesforce

Visualforce pages that contain a form component also contain an encrypted, hidden form field that encapsulates the view state of the page. 

This view state is automatically created, and as its name suggests, it holds the state of the page - state that includes the components, field values and controller state.

The view state size of your Visualforce pages must be under 170 KB. (Prior to Spring 19 release it was 135 KB. for reference: Spring 19 Release Notes).
By reducing your view state size, your pages can load quicker and stall less often.

Serialization is what occurs when binary computer memory is converted into a format that can be transferred to disk or over a network connection. In Salesforce (and most other web-based platforms), this is commonly called the View state in Salesforce. 


When a Visualforce page receives a view state, it "deserializes" the data into an existing object, and acts as the object initialization routine instead of the constructor that is defined for the class. When there is no view state, the constructor is called instead.

How I can see view state:

To see view state, Enable Development mode from your user record.

View State
View State
Best practices to optimize view state:

  • Minimize Number of Forms on a Page :
Assume a page contains two forms - form A and form B. Whichever form the user submits and causes a postback, the view state for the page needs to get transferred. To support this, each form on your page will have its own copy of view state. If the associated view state is large, instead of having multiple forms on a page, have a single form and use <apex:actionRegion> to submit portions of the form. This practice will ensure that only a single copy of the view state is associated with that page.
  • Declare Variables as Transient to Reduce View State :
An instance variable declared as transient is not saved and is not transmitted as part of the view state. If a certain field is needed only for the duration of the page request and does not need to be part of the view state, declare it as transient.
  • Recreate State versus Storing It in View State:
View state should ideally contain only work in progress data. If you can reconstruct the data during postback, via a SOQL query or a web services call, do that instead of storing it in controller data members.
  • Use Custom Objects or Custom Settings to Store Large Quantities of Read-Only Data:
Assume that your controller needs to call a Web service and parse a large response object. Storing it in view state may not even be an option given the size. Marking it as transient would incur the cost of an additional Web service call and parsing it again. In such instances, you could store the parsed response in a custom object and store just the record id to get to the parsed response. Custom settings provide another mechanism to cache data needed by your controller. Accessing custom settings is faster than access to custom objects since custom settings are part of your application's cache and does not require a database query to retrieve the data.
  • Refine Your SOQL to Retrieve Only the Data Needed by the Page:
Only retrieve and store the fields in variable you need and also filter the records to only retrieve records needed by the visual force page.
  • Refactor Your Pages to Make Its View Stateless:
Instead of using <apex:commandLink> or <apex:commandButton> components which need to be inside a <apex:form> component to invoke an action, use an <apex:outputLink> or other non-action method instead and implement the action through an <apex:page> action attribute - where it makes sense.


Enjoy! If you have any questions, comments etc. please feel free to let me know. As always, please feel free to get in touch me as I would be more than happy to assist you with any of your Salesforce development needs.