31 March 2011

Adding a checkbox on a PageBlockTable

One of the common use cases I experienced developing customization in Salesforce is the ability for end user to selected multiple records from a list and process them. In Salesforce you can do this via client-side scripting using JavaScript. However, it is slow and you don't really have full control of the selected records specially when your doing multi-paging list.

The best approach I believed on doing this is to create an Apex wrapper class. The wrapper class is a class that will represent data for your table with additional properties. An example of using wrapper class is when you want to display an accounts and then select them using a checkboxes. Let's see how we approach that below.

We first create a wrapper class similar to this:

public class AccountWrapperCls {
     public Boolean isSelected {get;set;}
     public Account cAccount {get;set;}

     public AccountWrapperCls(Account cAccount){
          this.cAccount = cAccount;
     }
}

As you can see above, the class contains an account and a boolean property. The isSelected property will be referenced by our Visualforce page and will be rendered as a checkbox. To use this wrapper class we need to create a Visualforce controller for our page that will use the class above.

public class MyAccountListCntrlr {
     // PROPERTIES
     public List<AccountWrapperCls> acctList {get;set;}
     public Set<String> selAccountNames {get;set;}
     public Boolean hasSelAcct {get;set;}

     // CONSTRUCTOR
     public MyAccountListCntrlr(){
          acctList = new List<AccountWrapperCls>();
          selAccountNames = new Set<String>();

          for(Account a : [SELECT AccountNumber, Name 
          FROM Account WHERE AccountNumber != NULL 
          LIMIT 5]){
               acctList.add(new AccountWrapperCls(a));
          }
     }

     // METHODS
     public void displaySelectedAccountNumbers(){
          selAccountNames.clear();
          hasSelAcct = false;
          for(AccountWrapperCls cWrapper : acctList){
               if(cWrapper.isSelected){
                    hasSelAcct = true;
                    selAccountNames.add(cWrapper.cAccount.
                             AccountNumber);
               }
          }
     }
}

As you can see above, we created a list of type AccountWrapperCls which represents the account record and the additional isSelected property. Please note that we add a method called displaySelectedAccountNumbers() which gets all the account records whose isSelected value is set to TRUE. It also adds those selected account's account number to a set variable we defined in our class which we will use to display account numbers on the page.

Below is our Visualforce page:

<apex:page controller="MyAccountListCntrlr" tabStyle="Account">
   <apex:form >
      <apex:pageBlock title="Account List">
         <apex:pageBlockButtons >
            <apex:commandButton 
               value="Show Selected Accounts" 
               action="{!displaySelectedAccountNumbers}"/>
         </apex:pageBlockButtons>

         <!-- ACCOUNT LIST -->
         <apex:pageBlockTable 
           value="{!acctList}" 
           var="acctWrapper">
            <apex:column >
               <apex:inputCheckbox 
                 value="{!acctWrapper.isSelected}"/>
            </apex:column> 
            <apex:column 
              value="{!acctWrapper.cAccount.AccountNumber}"/>
            <apex:column 
              value="{!acctWrapper.cAccount.Name}"/>
         </apex:pageBlockTable>

         <!-- SELECTED ACCOUNT INFO -->
         <apex:pageBlockSection >
            <apex:outputPanel 
              layout="block" 
              rendered="{!hasSelAcct}">
               <apex:outputText 
                 value="Below are the selected account:"/>
               <br/>
               <apex:outputText 
                 value="{!selAccountNames}"/>
             </apex:outputPanel>
             <apex:outputPanel layout="block" 
               rendered="{!NOT(hasSelAcct)}">
                <br/>
                <apex:outputText value="No account selected."/>
             </apex:outputPanel>
         </apex:pageBlockSection>
      </apex:pageBlock>
   </apex:form>
</apex:page>

Note that we referenced our list variable while using the properties of our wrapper class in the controller .

28 March 2011

This will be the start of a good Salesforce Experience

Hello Guys! I've been in the consulting industry for 5 1/2 years and counting and started working as a .NET developer but later on switched to cloud development using Force.com technologies and now a certified developer and a future advance salesforce developer. I have been wanting to create a blog for quite sometime to share my experiences and tips, both nice and annoying during my career transition from OOP to cloud. This will not be a typical blog in which informations are copy and pasted from documentation as I want people to study on their own and uses this blog for workarounds and suggestions. From here on, I will try to update this blog and share my knowledge, some my real life use cases, designs and approaches I did to some of my projects.

Hope everybody, specially those that are new to the technology, benefits from this.