Showing posts with label Visualforce. Show all posts
Showing posts with label Visualforce. Show all posts

Monday, April 6, 2015

Logic behind getRecord()

In Visualforce you can have 4 types of controllers:

Standard Controller class has a method called "getRecord()". It returns the record that is currently in context (e.g. Account, Contact, Opportunity, Custom_Object__c etc.), based on the value of the id query string parameter in the Visualforce page URL.

You can use this method in a controller extension class of a Visualforce page to get the record for a specific object. The most important point here is that you can get data in ONLY those which are referenced in a Visualforce markup. This method helps and allow you to not SOQL query to get data from associated fields of a specific object.

For example you have a Visualforce page to show Detail View of Opportunity but you need "Stage" field of Opportunity in associated Controller Extension class to perform some activities based on the value of "Stage" field.

The easy way is to query that particular record of Opportunity with the Id query string parameter in the Visualforce page URL.

The smartest way is to use getRecord() method and <apex:outputText> tag of Visualforce with an attribute of render=false. This will allow you to get the Stage field data without query into the Opportunity object.


Now first, create an Apex class. To create an Apex class Go to, Setup > Build > Customize > Develop > Apex Classes > New

Now copy and paste below code into the Apex class editor and Save it.

Visualforce Controller Extension Code

              --------------------------------------------------------------------------------------------
public with sharing class OpportunityCtrlExt{

    public Opportunity opportunityRecord {get; private set;}

    public OpportunityCtrlExt(ApexPages.StandardController stdController) {
        this.opportunityRecord = (Opportunity)stdController.getRecord();
        doProcessing();
    }
    
    private void doProcessing(){
        // IF Stage = Prospecting THEN 
        // disable Prospecting button and enable Closed Won and Closed Lost buttons
        if(opportunityRecord.StageName == 'Prospecting'){
             // Your logic here
        }
        // IF Stage = Closed Won or Closed Lost THEN 
        // enable Prospecting button and disable Closed Won and Closed Lost buttons
        else{
             // Your logic here
        }
   }

}
              --------------------------------------------------------------------------------------------


To create a Visualforce page Go to, Setup > Build > Develop > Pages

Now copy and paste below code into the Visualforce page editor and name this Visualforce page as "OpportunityCustomButtonsPage" and Save it.

Visualforce Page Code

--------------------------------------------------------------------------------------------
<apex:page standardController="Opportunity" extensions="OpportunityCtrlExt">

    <!-- This will render a standard detail page of Opportunty with all related lists -->
    <apex:detail subject="{!Opportunity.Id}" relatedList="true" title="true" showChatter="true" inlineEdit="true"  />

    <!--
        This is because we do not need to query Stage field in associated Controller Extension class
        because we are using getRecord() method of Standard Controller. If you will not use below line
        then you will need to query Stage field otherwise you will get an error saying:
        SObject row was retrieved via SOQL without querying the requested field: Opportunity.StageName 
    -->
    <apex:outputText value="{!Opportunity.StageName}" rendered="false"></apex:outputText>

</apex:page>
                   --------------------------------------------------------------------------------------------

Enable / Disable Buttons on Standard Detail Page

In Salesforce.com we always have 2 ways to implement a requirement or use case. One is Declarative "or" Point-And-Click tools and if any thing which we can not implement then we consider to go with another way which is Programmatic using Apex, Visualforce, SOQL, SOSL or Salesforce API's.

Here I am going to take one of the use case which I came across during implementation. A customer wanted to show custom buttons on Opportunity detail page and based on each button click they wanted to perform some actions on an Opportunity record (e.g. Update Stage field etc.). This can be achieved easily using Declarative "or" Point-And-Click tools. However they also wanted to Enable or Disable those Custom Buttons based on the value of Stage field in Opportunity record. This is something you cannot achieve via standard OOTB (out-of-the-box) features of Salesforce.com. So, now what to do?

Now lets take a specific example here. For example you have 3 custom buttons with following Name:

  • Prospecting
  • Closed Won
  • Closed Lost
To create a custom button Go to, Setup > Build > Customize > Opportunities > Buttons, Links, and Actions

After creating custom buttons, add them in Page Layouts of Opportunity.

To enable / disable those buttons on standard detail page of Opportunity, we need to override the standard detail page with a Visualforce page.

A Visualforce page must be using "Opportunity"  as a standard controller and an Apex class "OpportunityCustomButtonsCtrlExt" as a visualforce controller extension.

First, create an Apex class. To create an Apex class Go to, Setup > Build > Customize > Develop > Apex Classes > New

Now copy and paste below code into the Apex class editor and Save it.

Visualforce Controller Extension Code

              --------------------------------------------------------------------------------------------
public with sharing class OpportunityCustomButtonsCtrlExt{

    private boolean buttonProspecting;
    private boolean buttonClosedWon;
    private boolean buttonClosedLost;
    
    public Opportunity opportunityRecord {get; private set;}
    
    public boolean getButtonProspecting(){
        return buttonProspecting;
    }
    public boolean getButtonClosedWon(){
        return buttonClosedWon;
    }
    public boolean getButtonClosedLost(){
        return buttonClosedLost;
    }

    public OpportunityCustomButtonsCtrlExt(ApexPages.StandardController stdController) {
        this.opportunityRecord = (Opportunity)stdController.getRecord();
        enableDisableCustomButtons();
    }
    
    private void enableDisableCustomButtons(){
        // IF Stage = Prospecting THEN 
        // disable Prospecting button and enable Closed Won and Closed Lost buttons
        if(opportunityRecord.StageName == 'Prospecting'){
            buttonProspecting = true;
            buttonClosedWon = false;
            buttonClosedLost = false;
        }
        // IF Stage = Closed Won or Closed Lost THEN 
        // enable Prospecting button and disable Closed Won and Closed Lost buttons
        else{
            buttonProspecting = false;
            buttonClosedWon = true;
            buttonClosedLost = true;
        }
   }

}
              --------------------------------------------------------------------------------------------


To create a Visualforce page Go to, Setup > Build > Develop > Pages

Now copy and paste below code into the Visualforce page editor and name this Visualforce page as "OpportunityCustomButtonsPage" and Save it.

Visualforce Page Code

--------------------------------------------------------------------------------------------
<apex:page standardController="Opportunity" extensions="OpportunityCustomButtonsCtrlExt">

    <!-- This will render a standard detail page of Opportunty with all related lists -->
    <apex:detail subject="{!Opportunity.Id}" relatedList="true" title="true" showChatter="true" inlineEdit="true" oncomplete="javascript:location.reload();"  />

    <!--
        This is because we do not need to query Stage field in associated Controller Extension class
        because we are using getRecord() method of Standard Controller. If you will not use below line
        then you will need to query Stage field otherwise you will get an error saying:
        SObject row was retrieved via SOQL without querying the requested field: Opportunity.StageName 
    -->
    <apex:outputText value="{!Opportunity.StageName}" rendered="false"></apex:outputText>
    
    <script type="text/javascript">
    
    function checkButtonName(){
        if('{!buttonProspecting}' == true || '{!buttonProspecting}' == 'true') {
            // prospecting is an API Name of the custom button Prospecting
            // make sure you all letters must be small
            enableDisableButtons("prospecting");
        }
        if('{!buttonClosedWon}' == true || '{!buttonClosedWon}' == 'true'){
            // prospecting is an API Name of the custom button Closed Won
            // make sure you all letters must be small
            enableDisableButtons("closed_won");
        }
        if('{!buttonClosedLost}' == true || '{!buttonClosedLost}' == 'true'){
            // prospecting is an API Name of the custom button Closed Lost
            // make sure you all letters must be small
            enableDisableButtons("closed_lost");
        }
    }
    
    checkButtonName();
    function enableDisableButtons(btnName1) {
      try{
        var buttons = document.getElementsByName(btnName1);
        for (var i=0; i < buttons.length; i++) {
          buttons[i].className="btnDisabled ";
          buttons[i].disabled=true;      
        }
      } catch(e) {
      }
    }
    
    </script>

</apex:page>
                   --------------------------------------------------------------------------------------------


Now the last and final step is to override / replace detail page of Opportunity with a Visualforce page "OpportunityCustomButtonsPage" which you just created.

To override Detail View of Opportunity Go to, Setup > Build > Customize > Opportunities > Buttons, Links, and Actions > click "Edit" associated to View > select a Visualforce page "OpportunityCustomButtonsPage" from the drop-down menu  > click Save


Now Opportunity page should look like this:

IF Stage = Prospecting




IF Stage = Closed Won "or" Closed Lost






Sunday, April 5, 2015

Pagination with a Standard List Controller


In Visualforce you can add pagination logic in a visualforce page using a Standard List Controller by helping standard functions of pagination "first", "previous", "next", "last". This page also have a capability to mass update records using Inline Editing Support.


If you create a visualforce page with the following markup:

<apex:page standardController="Account" recordSetVar="accounts" tabstyle="Account">

    <apex:form >

        <apex:pageblock id="customerPageBlock" title="Mass Update Customers">

            <apex:pageblocktable value="{!accounts}" var="acct" id="customerTable">

                <apex:column headerValue="Customer ID">
                    <apex:outputField value="{!acct.Id}"/>
                </apex:column> 
                <apex:column headerValue="Customer Name">
                    <apex:outputField value="{!acct.Name}"/>
                </apex:column> 
                <apex:column headerValue="Industry">
                    <apex:outputField value="{!acct.Industry}"/>
                </apex:column>                             
                <apex:inlineEditSupport event="onClick"/>
            </apex:pageblocktable>

            <center>
                <apex:panelGrid columns="7">
                    <apex:commandButton action="{!quickSave}" value="Save"/>
                    <apex:commandButton action="{!Cancel}" value="Cancel"/>
                    <apex:inputHidden />              
                    <apex:commandButton disabled="{!NOT(hasPrevious)}" action="{!first}" value="First"/>
                    <apex:commandButton disabled="{!NOT(hasPrevious)}" action="{!previous}" value="Previous"/>
                    <apex:commandButton disabled="{!NOT(hasNext)}" action="{!next}" value="Next"/>
                    <apex:commandButton disabled="{!NOT(hasNext)}" action="{!last}" value="Last"/>
                </apex:panelGrid>
            </center>

        </apex:pageblock>
    </apex:form>
</apex:page>








Considerations

  • By default, a standard list controller returns 20 records on the page.
  • To control the number of records displayed on each page, use a controller extension to set the pageSize. See Controller Extensions.

Saturday, April 4, 2015

Visualforce Tips & Tricks

outputLink in Visualforce

<apex:page >
    <apex:pageBlock title="Visualforce Pages">
        <apex:outputLink value="{!$Page.SearchPage}?id=101" target="_blank">Search Page</apex:outputLink>    
    </apex:pageBlock>
</apex:page>


MVC & Visualforce

What is MVC?

Model–View–Controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts:

  • Model - A model consists of application data, business rules, logic and functions
  • View - A view can be any output representation of information
  • Controller - A controller accepts input and converts it to commands for the model or view

MVC Paradigm






Visualforce and the MVC Pattern






MVC Example in Visualforce






Saturday, March 21, 2015

Activities Tab

Activities Tab

A custom tab to show Activities (Tasks & Events) in Salesforce.com.


Overview

In Salesforce.com we do not have Activities (Tasks & Events) tab like we have for other standard objects (Lead, Account, Contact, Opportunity etc). This piece of code allows end users (Non-Salesforce Expert, Administrators and of course Developers) to create tab for Activities (Tasks & Events) without writing much of code.






Required Components for this functionality:

  • Visualforce Page
  • Visualforce Tab

Visualforce Page Code:

<apex:page>
    <apex:enhancedList type="Activity" height="500"/>
</apex:page>


Steps to Create a Tab for Activities:



Sunday, June 2, 2013

How to write Batch Apex along with Visualforce page?

Batch Apex with Visualforce

Visualforce Controller Code:
public class RunBatchController{
public void RunBatch(){
// DeletionBatch is the batch you implemented.
DeletionBatch batch = new DeletionBatch();
Database.executeBatch(batch);
}
}

Visualforce Page Code:
<apex:page controller="RunBatchController">
   <apex:commandButton action="{!RunBatch}" value="Delete Records"/>
</apex:page>