Wednesday, 15 June 2011

Dynamic Binding : Use Action Functions on Field Set's Fields


Hi,

Earlier we have talked about how to use dynamic binding with or without field set and dynamic binding when object is also dynamic. Now its time to go one level ahead. 

My first question : Why we use dynamic binding ?
Ans : So that VFP Design can be configured on production org without any code change.

Mostly when we use field set or dynamic binding we can change our UI at any time but how to handle onclick event of any field if we have such requirement. We have only one inputField control in Repeat then how to call a javascript or actionFunction. We can not have dynamic UI at the cost of any business logic. So lets try to do it now


Requirement : We have a custom picklist field in the Field Set fields that we are displaying,  "Is Active" having value "Yes" , "No" , “None” , if user select s yes then “No Of Employee” fields should become mandatory and if he changes it to other then “Yes” then it should be non mandatory. And also set No Of Employe = 5 whenever "Is Active" fields changes its value.


Step 1: First I Created a Field Set On Account , With Five Fields in the Field Set






Step 2: Create the Controller Class like this

//Controller class
public class actionFunction_FieldSet {

    
    public Account account {get;set;}
    public boolean noOfEmpReq {get;set;}
    public String IsActive {get;set;}
    
    public actionFunction_FieldSet()
        {
            noOfEmpReq  = false;
            account = new Account();
        }
    //action function to be called
    public void actionFunctionM()
        {
            if(IsActive == 'Yes')
                noOfEmpReq = true;
            else
                noOfEmpReq = false;    
        }    
}

Step 3: Create a VFP like this
<apex:page controller="actionFunction_FieldSet" title="Field Set Use">
   <apex:form >
       <!-- Action function to determine required status for No of employee field -->
       <apex:actionFunction name="jsSetNoOfEmpReq" oncomplete="alert('action completed');" action="{!actionFunctionM}" immediate="true" reRender="pbsFS">
           <apex:param assignTo="{!IsActive}" value="IsActive" id="IsActive" name="noEmpR"/>
       </apex:actionFunction>
       <script>
           
           var numberofemployeesID;
           function setNoOfEmpReq(ctrlIsActive)
               {
                    
                    //Assign value to the no of employee field
                    if(document.getElementById(numberofemployeesID) != null)
                        document.getElementById(numberofemployeesID).value = 5;
                    //action function call 
                    jsSetNoOfEmpReq(ctrlIsActive.value);
               }
       </script>
       <apex:pageBlock title="Field Set Use">
       <apex:pageBlockSection title="Field Set Use" id="pbsFS">
           <apex:repeat value="{!$ObjectType.Account.FieldSets.DemoFieldSet}" id="ctrlRepeat" var="fieldAPIName">
               <!-- 
                    1. We have cretaed there input fields one will only if active__c field comes trough field set
                    2. second when numberofemployees comes
                    3. For other field
                    
                    Using such design we can have the dynamic design as well we can use onclick or onchange events on fields
                -->
               <apex:inputField value="{!account[fieldAPIName]}" onchange="setNoOfEmpReq(this);" rendered="{!IF(CONTAINS(LOWER(fieldAPIName), 'active__c') , true , false)}"/>
               <apex:inputField value="{!account[fieldAPIName]}" required="{!noOfEmpReq}" rendered="{!IF(CONTAINS(LOWER(fieldAPIName), 'numberofemployees') , true , false)}" id="NoOfEmp" />
               <apex:inputField value="{!account[fieldAPIName]}" rendered="{!IF(OR(CONTAINS(LOWER(fieldAPIName), 'active__c') , CONTAINS(LOWER(fieldAPIName), 'numberofemployees')) , false , true)}" /> 
               
               <script>
               /*
                   Set the id for numberofemployeesID field can be used in java script
               */
               if({!CONTAINS(LOWER(fieldAPIName), 'numberofemployees')})
                   {
                       numberofemployeesID = '{!$Component.ctrlRepeat}:NoOfEmp';
                   }
               </script>
           </apex:repeat>
       </apex:pageBlockSection>
       </apex:pageBlock>
   </apex:form>>
</apex:page>

So that was a very basic requirement when we need to use action function on any event of field from field set. Using similar approach we can solve big problems as well. We can also achieved it using only a single inputField and using onclick and passing  field api name and performing actions only to valid fields otherwise return false.

<apex:page controller="actionFunction_FieldSet" title="Field Set Use">
   <apex:form >
       <!-- Action function to determine required status for No of employee field -->
       <apex:actionFunction name="jsSetNoOfEmpReq" oncomplete="alert('action completed');" action="{!actionFunctionM}" immediate="true" reRender="pbsFS">
           <apex:param assignTo="{!IsActive}" value="IsActive" id="IsActive" name="noEmpR"/>
       </apex:actionFunction>
       <script>
           
           var numberofemployeesID;
           function setNoOfEmpReq(ctrl , isctrlIsActive)
               {
                    if(isctrlIsActive)
                        {
                            //Assign value to the no of employee field
                            if(document.getElementById(numberofemployeesID) != null)
                                document.getElementById(numberofemployeesID).value = 5;
                            //action function call 
                            jsSetNoOfEmpReq(ctrl.value);
                        }
                    else
                        return false;    
               }
       </script>
       <apex:pageBlock title="Field Set Use">
       <apex:pageBlockSection title="Field Set Use" id="pbsFS">
           <apex:repeat value="{!$ObjectType.Account.FieldSets.DemoFieldSet}" id="ctrlRepeat" var="fieldAPIName">
                <!-- 
                    1. Used only one input field 
                -->
                
               <apex:inputField value="{!account[fieldAPIName]}" onchange="setNoOfEmpReq(this , {!CONTAINS(LOWER(fieldAPIName), 'active__c')});" required="{!IF(CONTAINS(LOWER(fieldAPIName), 'numberofemployees') , noOfEmpReq , false)}" id="fieldId" />
               
               
               <script>
               /*
                   Set the id for numberofemployeesID field can be used in java script
               */
               if({!CONTAINS(LOWER(fieldAPIName), 'numberofemployees')})
                   {
                       numberofemployeesID = '{!$Component.ctrlRepeat}:fieldId';
                   }
               </script>
           </apex:repeat>
       </apex:pageBlockSection>
       </apex:pageBlock>
   </apex:form>>
</apex:page>


Other Related Posts : Dynamic Binding : When Object Name is Dynamic Also


         Regards
Shashikant Sharma




Thursday, 9 June 2011

Testing Apex : Structure of Test Class for Apex Class

I saw a lot of questions on Test Methods on developer community asking how to write test class for apex class. So here I am writing a basic structure of a test class which tests an Apex Class
@isTest
private class testApexClass{

    private static TestMethod void testClassMethod(){
        
        //Step 1 : Data Insertion
        //Insert all the data required for your trigger according to your logic written in the trigger
        
        //Try to give unique values in fields while creating test data, like Name = 'TestAccountName' etc
        
        //If any configuration setting is also needed in your trigger insert that as well
        //If you create any configuration setting then you will need to create a user also so that mixed dml exception do not occur
        
        //If class has a constructor with parameter Standard Controller, that means VFP is using this class as extention and has a standard controller then please create a standard controller prior to instance of class

        //Create instance of Class 
        MyClass cls = new MyClass();

        test.startTest();
        
        //call the method that you want to test using instance of class
        cls.MethodToTest()
        
        //assert your results using system.assert and system.asserEquals 
        
        test.stopTest();
        // IF you have used any static variables
        
        
    }


}

In above structure we have not talked about the advance problems like mixed dml exception and profile base testing. We leave it for other day :)

Regards

Wednesday, 8 June 2011

Testing Trigger : Structure of Test Class for Apex Trigger


Test methods are essential part of any application developed in salesforce. To prepare a managed package all test methods should run successfully and total code coverage has to be more than 75% . but we should not prepare test methods for coverage of code but we should prepare them to ensure functionality. We should prepare test methods for positive and negative cases both. Where positive case is when correct input is given and received expected results and negative cases where we provide negative input and any validation if we have should get fired.  Properly written test methods also helps us in regression testing as well.
Before we start structure of testmethods first l would like to mention some basic points :
  • 1.       Independent of Org Data : Test methods do not commit any data to database. We should always write test methods creating all required data in the test method itself. No data dependency should be on org data. If we have any configuration settings also then we should also set there values in the test method to make test method execution independent of org data.
  • 2.       Use test.startTest and test.stopTest , all data creation should be done prior to using test.startTest. Limits do get reset as any webservice invoke or dml action gets executed after test.startTest
  • 3.       Always test for bulk data also if your code executed on bulk data as well.
  • 4.       Always assert your result in test method against expected result this will ensure you that your code is giving expected results.

Now we will start structuring a trigger class for a trigger


@isTest
private class testClass_Trigger{

    private static TestMethod void testTrigger(){
        
        //Step 1 : Data Insertion
        //Insert all the data required for your trigger according to your logic written in the trigger
        
        //Try to give unique values in fields while creating test data, like Name = 'TestAccountName' etc
        
        //If any configuration setting is also needed in your trigger insert that as well
        //If you create any configuration setting then you will need to create a user also so that mixed dml exception do not occur
        
        test.startTest();
        
        //If there are any static variables which are used in the trigger please set there values
        
        //Perform the dml action on which trigger gets fired , like insert, update ,delete , undelete
        
        //assert your results using system.assert and system.asserEquals 
        
        test.stopTest();
        // IF you have used any static variables
        
        
    }


}
Using above structure we can write test methods for a structure.

Monday, 6 June 2011

Calculate Day of Date in Salesforce

In Apex Class :

Way 1 :
Calculate using DateTime Format : It is very interesting way of finding the Day of a date.
Date d = date.newinstance(1947,8, 15);
datetime myDate = datetime.newInstance(d.year(), d.month(), d.day());
String day = myDate.format('EEEE');


Way 2 : Prepared a class to find out day of given date using Mod of  7 to determine the day.

public class DayOfDate {
    Private Date startDate = date.newInstance(0001, 1, 1);
    Public Date selectedDate{get;set;}
    public String dayValue{get;set;}
    public Account acc {get;set;}
    public DayOfDate()
    {
        selectedDate = date.today();
        acc = new Account();
    }

    public void calculateDayOfDate()
    {
        List<String> listDay = new List<String>{'Saturday' , 'Sunday' , 'Monday' , 'Tuesday' , 'Wednesday' , 'Thursday' , 'Friday'};
        selectedDate = acc.SLAExpirationDate__c;
        Integer remainder = Math.mod(startDate.daysBetween(selectedDate) , 7);
        dayValue = listDay.get(remainder);
    }



}


Visualforce Page :
<apex:page controller="DayOfDate">
  <apex:form>
  <apex:pageBlock>
      
      <apex:pageBlockSection columns="1">
          <apex:pageBlockSectionItem>
              <apex:outputLabel value="Enter Date"></apex:outputLabel>
              <apex:inputField value="{!acc.SLAExpirationDate__c}"/>
          </apex:pageBlockSectionItem>
          <apex:pageBlockSectionItem>
              <apex:outputLabel value="Day is : {!dayValue}"></apex:outputLabel>
          </apex:pageBlockSectionItem>
          <apex:commandButton action="{!calculateDayOfDate}" value="Find Day"/>
          
      </apex:pageBlockSection>
  </apex:pageBlock>
  </apex:form> 
</apex:page>

In above example I used Account objects date field  SLAExpirationDate__c to take input from user, you can take input using text field also, but in that case please format the date properly.


Calculate Day of a Date in formula field :

Create a formula field which should have return type 'Text'

IF(MOD(DateFieldAPIName__c - DATE(0001,1,1) , 7) == 0 , 'Saturday' , IF(MOD(DateFieldAPIName__c- DATE(0001,1,1) , 7) == 1 , 'Sunday' , 
IF(MOD(DateFieldAPIName__c- DATE(0001,1,1) , 7) == 2 , 'Monday' , 
IF(MOD(DateFieldAPIName__c- DATE(0001,1,1) , 7) == 3 , 'Tuesday' , 
IF(MOD(DateFieldAPIName__c- DATE(0001,1,1) , 7) == 4 , 'Wednesday' , 
IF(MOD(DateFieldAPIName__c- DATE(0001,1,1) , 7) == 5 , 'Thursday' , 
IF(MOD(DateFieldAPIName__c- DATE(0001,1,1) , 7) == 6 , 'Friday' , 'No Day')))))) 
)

In this formula DateFieldAPIName__c is the field api name of the date field for which you want to know the day of date.


You can also Use "Case" instead of  IF in in above formula like this :

CASE(MOD(DateFieldAPIName__c - DATE(0001,1,1) , 7) , 0 , 'Saturday' , 1 , 'Sunday' ,  2 , 'Monday' , 3 , 'Tuesday' , 4 , 'Wednesday' , 5 , 'Thursday' , 6 , 'Friday'  , 'No Day Found')
Regards
Shashikant Sharma

Sunday, 5 June 2011

Dynamic Binding : When Object Name is Dynamic Also

Hi,

In earlier post we talked about dynamic binding with field set in this object name was static and fields were coming dynamically from Field Sets.Now we will talk about other way when both Object and Fields are dynamic.

Now we will take examples where object name and fields both are dynamic and fields are not coming from Field Sets either.

Controller Class
public class DynamicBinding {
    
    public sObject sObjectToBind {get;set;}
    public List<String> listObjectFields {get;set;}
        
    public DynamicBinding()
    {
        listObjectFields =  new List<String>();
        Map<String , Schema.SObjectType> globalDescription = Schema.getGlobalDescribe();
        //In this example I have hard coded the object name
        Schema.sObjectType sObjType = globalDescription.get('Account');
        
        sObjectToBind = sObjType.newSObject();
        Schema.DescribeSObjectResult r1 = sObjType.getDescribe();
        
        Map<String , Schema.SObjectField> mapFieldList = r1.fields.getMap();
        Integer i = 0;
        for(Schema.SObjectField field : mapFieldList.values())
            {
                Schema.DescribeFieldResult fieldResult = field.getDescribe();
                if(fieldResult.isAccessible() && fieldResult.isUpdateable())
                    {
                        listObjectFields.add(fieldResult.getName());
                    }
                if(i == 5)
                    break;
                
                i++;
            }
                        
    }
}

Visulaforce Page

<apex:page controller="DynamicBinding">
  
   <apex:form>
       <apex:pageBlock title="Without Field Set Use">
       <apex:pageBlockSection title="Dynamic Object">
           <apex:repeat value="{!listObjectFields}" var="fieldAPIName">
               <apex:inputField value="{!sObjectToBind[fieldAPIName]}"/>
           </apex:repeat>
       </apex:pageBlockSection>
       </apex:pageBlock>
   </apex:form>


</apex:page>


So in above example I used an sObject instance and showed 5 fields only of that Object type. In above example I used Account object you can decide any object pass the name from any parameter or get as input from User using Picklist.

Related Post : http://forceschool.blogspot.com/2011/06/dynamic-binding-using-field-sets.html

Regards




Age Calculation Formula

Hi,

I saw a question in developer community How to Calculate Age in formula field using Birth Date. It's reply was a very big formula

IF(MONTH(TODAY())> MONTH(DOB__c),YEAR(TODAY())-YEAR(DOB__c),IF(AND(MONTH(TODAY())= MONTH(DOB__c), DAY(TODAY())>= DAY(DOB__c)),YEAR(TODAY())-YEAR(DOB__c),(YEAR(TODAY())- YEAR(DOB__c))-1))

I Checked this this was working fine but It looked very complicated to me. So I thought of one formula that I used in first year of My Engg. in C Programming to determine age. In it we used to divide the date difference with 365.2425, why 365.2425 because we have leap years also so the avg. days in a year is not 365 but it is 365.2425 , So I created this new formula and it worked fine.

IF(ISNULL(DOB__c) , DOB__c , FLOOR((TODAY()-DOB__c +1)/365.2425))

I checked it, It is working fine in all cases , for leap year and all other cases that we usally check for age Calculation.

Regards

Decimal Rounding in an Apex

Hi,

As I was asked by my colleague how to round any decimal to certain decimal point, he was new to Salesforce. I looked in Math Methods in Apex Lang Ref. but could not find any as Round method there only returns floor or celling integer value removing all the decimal points. Then I suggested him to basic mathematic formula that my teacher told me in 10th standard
1)Multiply your number with nth power of 10 where n is the decimal point up to which we want to round it.
2) Use Math.Round then
3)Again divide it with n th power of 10

He was amazed that is that the way we do these small things in Apex, his comment made me to go again to Apex Lang Ref. Now I found a direct method in Decimal Method



Do this in System Logs :
Decimal decimalvalue = 23.55564543;
//rounds it up to 3 decimal places
d = d.setscale(3);
system.debug('decimalvalue : ' + d.scale());

Debug Result -> decimalvalue : 23.556

Decimal decimalvalue = 23.55534543;
//rounds it up to 3 decimal places
d = d.setscale();
system.debug('decimalvalue : ' + d.scale());

Debug Result -> decimalvalue : 23.555

So to my colleague and all please use this one and don't complicate things :)

Regards

Show Hierarchy in Visualforce Page

Hi,

I saw this question regularly in developer community how to show items in a hierarchy in VFP like this.
Parent
   Child 1
       Grand Child1
   Child 2
       Grand Child2

Now here is an Example :
I created a New Object Hierarchy
Added two fields in it :
1) AccountId : To save reference to Account Record
2)Parent Hierarchy : To save the Parent Hierarchy record

I created a Account : Test Hierarchy
And 5 Records for Hierarchy Object for this account record
 Parent1 : No parent hierarchy
 Child 1 : Parent Hierarchy =  Parent1
 Child 2 : Parent Hierarchy =  Parent1

 Grand Child 1 : Parent Hierarchy =  Child1
 Grand Child 2 : Parent Hierarchy =  Child2


Now our Aim is to show them in this way

Parent1
    Child1
          GrandChild11
    Child2
          GrandChild12

Apex Controller For this

//Create Hierarchy
public class hierarchy{

    //List of items to be displayed in hierarchy
    public List<hierarchyItem> hierarchyItemList {get;set;}
    
    //map of all  hierarchy records related to for a account for which we are showing hierarchy
    private Map<Id , Hierarchy__c> mapHierarchy = new Map<Id , Hierarchy__c>();
    
    //Hierarchy Index, used to determine spaces before the name starts
    private static Integer hirarchyIndex = 0;
    
    //name of account for which hierarchy is created
    public String AccountName {get;set;}
    
    public hierarchy()
    {
        if(ApexPages.currentPage().getParameters().get('accountid') != null)
        {
            ID AccountID = ApexPages.currentPage().getParameters().get('accountid');
           
            AccountName = [Select Name From Account where id =: AccountID].Name;
            //Get all hierarchy records related to account
            mapHierarchy = new Map<Id , Hierarchy__c>([Select Name , Parent_Hierarchy__c  From Hierarchy__c Where AccountId__c =: AccountID]);
            
           
            
            List<Hierarchy> listParentHierarchy = new List<Hierarchy>();
            hierarchyItemList = new List<hierarchyItem>();
            
            for(Hierarchy__c h : mapHierarchy.values())
                {
                    if(h.Parent_Hierarchy__c  == null)
                    {
                        hierarchyItemList.add(new hierarchyItem( h.Name , 0));
                        mapHierarchy.remove(h.id);
                        hierarchyItemList = getChildHierarchy(h.id , hierarchyItemList);
                    }
                    
                }
        }
    }

    //Method to get child records
    private List<hierarchyItem> getChildHierarchy(Id parentId , List<hierarchyItem> currentHierarchyItemList)
    {
        hirarchyIndex = hirarchyIndex + 1;
        for(Hierarchy__c h : mapHierarchy.values())
            {
                if(h.Parent_Hierarchy__c == parentId)
                    {
                        hierarchyItemList.add(new hierarchyItem( h.Name , hirarchyIndex));
                        mapHierarchy.remove(h.id);
                        //Get child records of child
                        hierarchyItemList = getChildHierarchy(h.id , hierarchyItemList);
                    }
                
            }
        hirarchyIndex = hirarchyIndex - 1;    
        return currentHierarchyItemList;    
    }    
    
    //Inner class for maintaing hierarchy items
    public class hierarchyItem{
        
        public String itemValue{get;set;} 
        public String hirarchyIndexNo{get;set;}
        public hierarchyItem(String itemValue , Integer hirarchyIndexNo)
            {
                String spaceCount = '';
                for(integer i = 0 ; i < hirarchyIndexNo ; i++)
                    spaceCount = spaceCount  + '&nbsp;&nbsp;';
                    
                this.itemValue = spaceCount + itemValue;
            }
    }

}


<apex:page controller="hierarchy">
  <apex:form>
     <apex:pageBlock>
         <apex:pageblockSection columns="1" title="Hierarchy For {!AccountName}">
             <apex:repeat value="{!hierarchyItemList}" var="item">
                <apex:pageBlockSectionItem>
                    <apex:outputLabel value="{!item.itemValue}" escape="false"/>
                </apex:pageBlockSectionItem>
             </apex:repeat>
         </apex:pageblockSection>
     </apex:pageBlock>
  </apex:form>
 </apex:page>

In VFP I have used escape="false" in the outPutLabel to allow html rendering in our case &npsp; to show blank space. We can easily achieve this using it without it with use of Apex:Variable and calculate space with help of it.

Now give URL to your VFP in address bar and pass account id in query string
like this

/apex/YourPageName?accountid=00190000007EKOG

View The result



In above Child2 has come first as Hierarchy records are coming from SOQL are DESC order of Last Modified date.

Regards

Saturday, 4 June 2011

Dynamic Binding : Using Field Sets

Hi,

Dynamic binding has been an amazing feture released in Spring 11. Earlier in visualforce page means that the apex controls that used to be binded like {!sObjectAPIName.FieldAPIName} , where you have to provide object API Name and field API Name at compile time ( at the time you develope a page and save it), it was static binding. Now we can provide both of these at run time thats why it is dynamic binding.

Variations of Dynamic Binding :

1) Dynamic Field API Name : It can be sub divided in two parts
    A) Using Field Sets
    B) Without Using Field Sets where Field to be displayed are maintained in any List in apex class, we can save these list using any custom object in which we will save both object API Name and Field API Name.

2) Dynamic Object API Name and Field API Name both

We will start here by first

1) Dynamic Field API Name Using Field Set :

First we will create a field set on Account Object : Go to -> Customize -> Account -> Field Sets and create a new field set.

Here you will see three boxes for field selection
1)Account(This is Object Name) Object Fields : This box is only available on developer org. This is not visible on production org after managed packaged is installed there.
2)Available For the Field Set : These are the fields that are available to move to the "In the Field Set". This is available on production org after managed packaged is installed there.
3) In the Field Set : These are the fields that are actually rendered on Visualforce Page when Field Set is used.

Now I will add some fields see the below image


Now Save this field set.

Note : In summer 11 release layout for field set editor has been changed and made like page layout in the object. See this for more http://forceschool.blogspot.com/2011/05/summer-11-field-sets.html

Using field Set on Visulaforce Page

<apex:page standardController="Account" title="Field Set Use">
   <apex:form>
       <apex:pageBlock title="Field Set Use">
       <apex:pageBlockSection title="Field Set Use">
           <apex:repeat value="{!$ObjectType.Account.FieldSets.DemoFieldSet}" var="fieldAPIName">
               <apex:inputField value="{!Account[fieldAPIName]}"/>
           </apex:repeat>
       </apex:pageBlockSection>
       </apex:pageBlock>
   </apex:form>>
</apex:page>
In above example we used Account as standard controller, and used it for Field binding in Input Field. We can also use any account instance of account object from controller class also if we want. All fields of field set renders in order you save them in "In the Field Set" column. If any field is Hidden for any profile then field set will not render that field for that user.

You can also show field set of any related object which has a reference to parent object using relationship name.

Often it is asked whether we can create new fields and fields in the field set on production orgs. Answer to this is "Yes". As soon you create any field on the object on production org it comes in "Available Fileds" box and you can add them in the field set and render them on your VFP.

Related Post : http://forceschool.blogspot.com/2011/06/dynamic-binding-when-object-name-is.html

Thursday, 2 June 2011

Inner Wrapper Class in Apex Class

Hi,

I have seen a lot of questions regarding inner class in a apex class in developer community and issues that can be solved by use of inner class. So here I would like to show a problem which can also be solved by inner class.

Syntax of inner class :

public class myOuterClass {
   // Additional myOuterClass code here  
    
   class myInnerClass {
     // myInnerClass code here  
    
   }
}

Problem :
http://boards.developerforce.com/t5/General-Development/When-i-click-on-add-button-i-need-to-display-one-more-textbox/td-p/286261

When i click on add button i need to display one more textbox

Visual Force Page :
<apex:page controller="addTextrBox">
  <apex:Form>
       <apex:commandButton Value="Add Text Box" action="{!addTextBox}"/>
       <br></br>
       <apex:repeat value="{!listvalueOfTextBox}" var="item" rendered="{!IF(listvalueOfTextBox.size > 0 , true , false)}" >
           <apex:outPutLabel value="{!item.textBoxLabel}">
           </apex:outPutLabel>
           <apex:inputText value="{!item.textBoxValue}"/>
           <br></br>
       </apex:repeat>
   </apex:Form>
</apex:page>


Apex Controller Class

public class addTextrBox 
{

    public List<textBoxClass> listValueOfTextBox
        { 
          get; 
          set; 
        }    
    public addTextrBox ()
        {
            listvalueOfTextBox = new List<textBoxClass>();
        }
    public PageReference addTextBox() 
        {
            try
                {
                    listvalueOfTextBox.add(new textBoxClass('TextBox' + (listvalueOfTextBox.size() +  1)));
                }
            catch(Exception e)
                {
                    ApexPages.addMessages(e);
                }
            return ApexPages.currentPage();
        }

     public class textBoxClass
         {
             public string textBoxLabel{get;set;}
             public string textBoxValue{get;set;}
             
             public textBoxClass(String textBoxLabel)
                 {
                     this.textBoxLabel = textBoxLabel;
                 }
         }
}

Here textBoxClass is the inner class

In above problem we used iner class now any new text box is binded with a new item in the list listvalueOfTextBox which is of type textBoxClass.

inner class acan be intancitiated like this
outerClass.innerclass instanceOfinnerClass = new outerClass.innerclass();

in above case it will be like
addTextrBox.textBoxClass instaceOftextBoxClass = new addTextrBox.textBoxClass('Test text Box');

Regards

Tuesday, 31 May 2011

Test Method for Trigger

Hi,

I just saw a problem on develoer community. I would like to share it with you.


Problem : I need help with the test method of this trigger, can someone please help me with the code, the trigger works but do not know how to create the test methods to deploy it to production:


The trigger is:
trigger CopyAttachments on MileStone__c(after insert)
{
Attachment[] attList = [select id, name, body from Attachment where ParentId = :Trigger.new[0].Opportunity__c];
Attachment[] insertAttList = new Attachment[]{};
 
         for(Attachment a: attList)
         {
               Attachment att = new Attachment(name = a.name, body = a.body, parentid = Trigger.new[0].id);
               insertAttList.add(att);
         }
       if(insertAttList.size() > 0)
       {
            insert insertAttList;
       }
Solution :
@isTest
private class TestCopyAttachments 
    { 
        //
        // This testMethod tests CopyAttachments triger
        // 
        public static testmethod void testCopyAttachments()
            {
                       
                //Insert a new instance of Oppurtunity Object with test values 
                Opportunity opr = new Opportunity(Name = 'Test' , StageName = 'TestStag' , CloseDate = Date.today());
                insert opr;
                
                //Insert a list of Oppurtunity Object with test values 
                List<Attachment> listAtt = new List<Attachment>();
                
                for(Integer i = 0; i < 5 ; i++)
                    { 
                        Attachment att = new Attachment(Name = 'TestAttachement', ParentId = opr.id , Body = Blob.valueOf('Test Attachment'));
                        listAtt.add(att);
                    }
                
                insert listAtt;
                
                test.startTest();
                
                MileStone__c mileStone = new MileStone__c(Opportunity__c = opr.id);
                insert mileStone;
                List<Attachment> listAttCopied = [Select id From Attachment where ParentId =: mileStone.id];
                system.assertEquals(listAttCopied.size() , listAtt.size());
                
                test.stopTest();
            }
    }

URL for issue in community

Friday, 27 May 2011

Summer 11 Features

Hi,

I want to share some new enactments and feature thats coming our way in picked from summer 11 release notes.

1) Package Upload Monitoring
Available in: All Editions

As of Summer ’11, ISVs can now track package uploads directly and view any failures during the upload process. Email notification is no longer required.There are new tabs to navigate to the package detail page and new real-time upload indicators
on the package and package version pages. You can follow an upload step by step, including individual Apex test runs.

2)Half-Up Rounding for All Numeric Fields
Available in: All Editions

As of Summer '11, all numeric fields use the round half up tie-breaking rule. For example, 12.345 becomes 12.35 and −12.345
becomes −12.35.


3)Limit Updates for Fields on Custom Objects, Sharing Rules, and Rich Text Area and Long Text Area Fields
Available in: Professional, Enterprise, Unlimited, Developer, and Database.com Editions

In Summer '11, the limit for the maximum number of fields on a custom object has been raised from 500 to 800 fields per object in Unlimited Edition. The total number of sharing rules per object increases from 100 to 300 in Professional, Enterprise, Unlimited, Developer and Database.com Editions.There are no longer limits to the number of rich text area and long text area fields that an object can contain, although your Edition's limit for the total number of custom fields allowed on an object, regardless of field type, still applies. Now, each object can contain a total of 1.6 million characters across long text area and rich text area fields. The default character limit for long text area and rich text area fields is 32,000 characters. A long text area or rich text area field needs to contain at least 256 characters. This update is for all Editions except Database.com


4)Quick Find Available in Setup
Available in: All Editions

In Summer '11, the sidebar in setup includes a search box for browsing and quickly finding setup tools. In the left pane of any setup page, you can:
• Type the first few characters of a setting name in the Quick Find box. As you type, items that match your search terms appear in the menu. Click an item in the list to go to its setup page. For example, to quickly find the user profiles page, type prof in the Quick Find box.
• Click Expand All to open all setup menus. If you have typed anything in the Quick Find box, only the menus with matching items are expanded.

Regards

Thursday, 26 May 2011

Summer 11 Field Sets

Hi All,

Dynamic binding has been one of the most popular new feature in Salesforce Spring 11 release. In summer 11 Field Sets configuration have a different UI then earlier and has attributes associated with it. Ealier configuration was done using there different Boxes now it is like page layout editor where fields can be drag and drop.


 This is how field set configuration screen looks. Configuring it similar to configuring page layouts.

In Summer '11 Some more additional properties are also included in Field Sets now.

1)Required : In the field set it can be mentioned then when this field will be rendered on any Visualforce page it will be required. Again doing it similar like we make any field required in page layouts. Click to properties for any field in "In the Field Set",  there you will see a Check Box field "Required",  set this to true and click Ok and save this field set.

2)You can span a field into a field set that references multiple objects. The total number of cross object spans within the In the Field Set is 25.

Idea for future release :
Blank Space Option for Field Set Editor
Please promote if you feel it will be good addition.

Regards


Wednesday, 25 May 2011

Writing Apex Trigger : Issues and Solutions ( Cyclic Trigger )

Hi All,

Some times we have a situation where trigger on a event of one object fires another trigger and logic in that trigger again fires first trigger. These situations are called cyclic triggers.
Ex :


trigger Trigger1 on Account (after update) 
    {
        
        for(Account acc : Trigger.New)
            {   
                //Trigger Action Logic
                List<Contact> listCon = [Select Fax from Contact where AccountId =: acc.id];      
                for(Contact con : listCon)
                    {
                        con.Fax = acc.Fax;
                    }
                update listCon;    
           
            }
    }
Another trigger on Contact object update is written like :


trigger Trigger2 on Contact (after update) 
    {
        
        for(Contact con  : Trigger.New)
            {   
                //Trigger Action Logic
                List<Account> accList = [Select Phone from Account where id =: con.AccountId];      
                for(Account acc : accList)
                    {
                        acc.Phone = con.Phone;
                    }
                update accList;    
           
            }
    }

In Above example event in Trigger1 invokes Trigger2 and event in Trigger2 again invokes Trigger1.

Solution : If we use entry criteria as explained in earlier post then cyclic trigger problem will be solved.
Writing Apex Trigger : Issues and Solutions ( Entry Criteria)


Tuesday, 24 May 2011

Writing Apex Trigger : Issues and Solutions ( Bulk Upload )

Hi All,

I have been facing issue of exceeding limit even though applying every possible optimizing tech. that we discussed in earlier posts. This case is more often if not always is trigger invocation on bulk upload of records. Now to avoid such situations use a Static Variable on the start of trigger. And on action of bulk upload set this static variable to false.
Create a Class with Static Variable
public class Constants
    {
         //Constant to block execution of trigger
         public static Boolean runTrigger = true;
    }
trigger <name> on Account (<events>) 
    {
        if(Constants.runTrigger)
            {
                //logic to be executed by trigger
            }
    }
Now we should set static variable to false
public class BulkUpdateClass
    {
         //Method to do trigger event on bulk of records
         public void triggerBulkUpdate()
               {
                    //Set static variable to false
                    Constants.runTrigger = false;

                    //Bulk Update Action Logic
               }
    }

By this we can stop execution of trigger for bulk of records

Regards

Monday, 23 May 2011

Writing Apex Trigger : Issues and Solutions ( Entry Criteria)

Hi All,

Here are some issues that we face using triggers

1) Triggers Gets executed every time when the sObject gets inserted or updated , even though we don't want so and want our trigger gets executed only when any condition as per our requirement gets satisfied.
Solution : The condition of your requirement is the entry criteria for your trigger and that entry criteria should checked before executing any logic in the trigger.
Ex : We need to copy account fax field to fax field of contact records for that account when account gets updated
   
trigger TriggerWithoutEntryCriteria on Account (after update) 
    {
        
        for(Account acc : Trigger.New)
            {   
                //Trigger Action Logic
                List<Contact> listCon = [Select Fax from Contact where AccountId =: acc.id];      
                for(Contact con : listCon)
                    {
                        con.Fax = acc.Fax;
                    }
                update listCon;    
           
            }
    }

Now this trigger does not have entry criteria and will execute every time when account record gets updated regardless the fax field is updated or not. Now we will add entry criteria to this trigger.
trigger TriggerWithEntryCriteria on Account (after update) 
    {
        Integer index = 0;       
        for(Account acc : Trigger.New)
            {
                //Check entry criteria
                if(acc.Fax != Trigger.Old[index].Fax)                
                    {
                         //Trigger Action Logic
                         List<Contact> listCon = [Select Fax from Contact where AccountId =: acc.id];      
                         for(Contact con : listCon)
                             {
                                 con.Fax = acc.Fax;
                             }
                         update listCon;    
                    }
                index++;
            }
    }
After adding the entry criteria we have made our Trigger Action Logic to execute only when Fax field of account is updated.
In above example SOQL and DML are used in for loop that should also be removed using collections as discussed in earlier posts.

Regards

Sunday, 22 May 2011

Writing Apex Trigger : Order of Execution ( Structure your trigger )

Hi All,

In this post we will discuss how does a trigger gets executed. This is very important to know to structure the trigger when there are many triggers on a sObject Type. Lets take a example of a simple class with a static varibale triggerEntryCount
public class Constants
    {
         //Constant to keep track of entry in trigger
         public static Integer triggerEntryCount = 0;
        
    }

A trigger is written
trigger Test_TriggerEntry on Account ( after update , after insert , before insert , 
before update , after delete , before delete ) 
    {
        Constants.triggerEntryCount = Constants.triggerEntryCount + 1;
    }

Now we will write a test class
private static testmethod void testTriggerEntry()
            {
                
                List<Account> listAccInsert =  new List<Account>();
                
                Account a = New Account(Name = 'TestAccountA');
                listAccInsert.add(a);
                Account b = New Account(Name = 'TestAccountB');
                listAccInsert.add(b);
                // insert list of accounts
                insert listAccInsert;
                system.debug('Trigger Entry Count : '+ Constants.triggerEntryCount); 
                
            } 

When we run the test class, system debug shows

Trigger Entry Count : 2
In this trigger entries were made for before insert and after insert.
Sequence for entry : before insert and after insert

Now we change test class a bit to check upsert event where two records are updated and one is inserted
private static testmethod void testTriggerEntry()
            {
                
                List&lt;Account&gt; listAccInsert =  new List&lt;Account&gt;();
                
                Account a = New Account(Name = 'TestAccountA');
                listAccInsert.add(a);
                Account b = New Account(Name = 'TestAccountB');
                listAccInsert.add(b);
                // insert list of accounts
                insert listAccInsert;
                

                //Initialize triger count to zero
                Constants.triggerEntryCount = 0;
                Contact c = new Contact( LastName = ' Test Contat ' , AccountId = a.id , Email =   
                'testTrigger@testMethod.com');
                insert c;
                
                System.debug(' ******** Start Debug ********* ');
                
                List<Account> listAccUpsert =  new List<Account>();
                a.Name = 'New Test Account A';
                b.Name = 'New Test Account B';
                listAccUpsert.add(a);
                listAccUpsert.add(b);
                
                Account a1 = New Account(Name = 'TestAccount');
                listAccUpsert.add(a1);

                //upsert list of accounts
                upsert listAccUpsert;
                system.debug('Trigger Entry Count : '+ Constants.triggerEntryCount);
                
            }
This time in system debug :
Trigger Entry Count : 4
Sequence for entry : Before Insert , After Insert , Before Update , After Update

Now if we have triggers on a sObject for all of these events in that case we need to structure our code in a way that only appropriate code gets executed in a trigger entry.

Structure trigger like this :
trigger Test_Trigger on Account ( after update , after insert , before insert , 
before update , after delete , before delete ) 
    {
        
        if (Trigger.isBefore)
            {
               
                if (Trigger.isInsert)
                    {     
                        // Logic to be executed for Before Insert
                    }
                    
                if (Trigger.isupdate)
                    {   
                        // Logic to be executed for Before Update
                    }
                 
                 if (Trigger.isDelete)
                    {     
                        // Logic to be executed for Before Delete  
                    }
            }
            
        if (Trigger.isAfter)
            {
           
                if (Trigger.isInsert)
                    {     
                        // Logic to be executed for After Insert
                    }
                    
                if (Trigger.isupdate)
                    {   
                        // Logic to be executed for After Update  
                    }
                
                 if (Trigger.isDelete)
                    {     
                        // Logic to be executed for After Delete
                    }
            }    
            
        
    }

In case you have same trigger logic for more then one trigger context
1)Use trigger context variables with logical operator OR ( "||" )
Or
2)Create a method for the logic and use that in the all the contexts where you want it to execute

Regards

Saturday, 21 May 2011

Writing Apex Trigger : Order of Execution (Trigger Context Variable)

Hi All,

In Last post we discussed how can we optimiza SOQL and DML in our triggers. But there are cases where we do not use SOQL in loop still we face such issue. Following are the such cases
1) Bulk upload
2) Cyclic Trigger Invocation : When we have bigger triggers that have more then one SOQL and dml statements, again it might be posible that dml in one trigger invoke another trigger and again that trigger invoke some other.
3)Some time we have custom pages where we save more then one object in a single instance in that case triggers of all the object are also invoked in single instance.

Now to solve these issues we need to write triggers in a structured manner with taking care of order of execution of trigger.Before going ahead first we need to be familiar with some Trigger Context Variables

Variable

Description

 isInsert

Returns true if this trigger was fired due to an insert operation, from the Salesforce user
interface, Apex, or the API.

 isUpdate 


Returns true if this trigger was fired due to an update operation, from the Salesforce user
interface, Apex, or the API.

 isBefore

Returns true if this trigger was fired before any record was saved.

 isAfter 


Returns true if this trigger was fired after all records were saved.

 isUndelete

Returns true if this trigger was fired after a record is recovered from the Recycle Bin (that is,
after an undelete operation from the Salesforce user interface, Apex, or the API.)


Regards

Writing Apex Trigger : Save Limits in Trigger

Hi All,

If we do not write triggers in such a way where salesforce limits such as SOQL, dml statements etc are not optimized then you will always see errors like Too Many SOQL etc. Mainly that happens when we have any SOQL or dml in for loop(iteration). But there are cases where we do not use SOQL in loop still we face such issue. Following are the such cases
1) Bulk upload
2) When we have bigger triggers that have more then one SOQL and dml statements, again it might be posible that dml in one trigger invoke another trigger and again that trigger invoke some other.
3)Some time we have custom pages where we save more then one object in a single instance in that case triggers of all the object are also invoked in single instance.

So by this we know that optimizing a trigger to save limits is essential. Now To save limits we should always follows some basic practice :
In a trigger
1) No SOQL or dml in a loop

In this example SOQL and dml both are in loop so when ever this trigger will be fired with bulk of records then Limits will exceed.

trigger testReqTrigger on Account (after update) 
{
    for(Account acc : Trigger.New){
    List<Contact> listCon = [Select Fax from Contact where AccountId =: acc.id];        for(Contact con : listCon){
        con.Fax = acc.Fax;
        }
    update listCon;

    }

Solution :
trigger testReqTrigger on Account (after update) 
    {
        //Get all the contacts for all the accounts in one SOQL
        List< Contact > listCon = [Select Fax , AccountID from Contact where AccountId in: Trigger.New];
        system.debug('****** listContacts  :  '+ listCon ); 
        //Map with Key : Account Id and Value : List of contacts for that account 
        Map< ID , List< Contact > > map_AccID_ContactRecord = new Map< ID , List< Contact > >();
        List< Contact > tempListCon = new List< Contact >();
        //Fill the map
        for(Contact c : listCon)
            {
                if(map_AccID_ContactRecord.containsKey(c.AccountID)) 
                    {
                     
                        tempListCon = map_AccID_ContactRecord.get(c.AccountID);
                        tempListCon.add(c);
                        map_AccID_ContactRecord.put(c.AccountID , tempListCon); 
                    }
                else 
                    {
                        tempListCon = new List< Contact >();
                        tempListCon.add(c);
                        map_AccID_ContactRecord.put(c.AccountID , tempListCon);
                    }
            }
        //List of contacts that will be updated
        List< Contact > listConTBU = new List< Contact >();
        for(Account acc : Trigger.New)
            {
                //check account has list of contacts in map
                if(map_AccID_ContactRecord.containsKey(acc.id)) 
                    {
                       //Loop over the list of contacts
                       for(Contact con : map_AccID_ContactRecord.get(acc.id))
                          {
                              con.Fax = acc.Fax;
                              //Add contact that needed to be updated
                              listConTBU.add(con); 
                          }
                    }
            }
        
        //update list of all the contacts for all accounts
        update listConTBU;

    }


2)Only one SOQL and dml should be there for an object type
    Ex : We have to write a trigger for
           1) Contact Fax is not null  then copy account fax to contact fax field
           2) Contact Phone is not null then copy account phone to contact phone field
trigger testReqTrigger on Account (after update)
    {
        for(Account acc : Trigger.New)
            {
                List<Contact> listConForFaxUpdate = [Select Fax from Contact where Fax != null And AccountId =: acc.id];       
                for(Contact con : listConForFaxUpdate)
                    {
                         con.Fax = acc.Fax;
                    }
                   
                update listConForFaxUpdate;
               
                List<Contact> listConForPhoneUpdate = [Select Phone from Contact where Phone != null And AccountId =: acc.id];       
                for(Contact con : listConForPhoneUpdate )
                    {
                         con.Phone = acc.Phone;
                    }
                   
                update listConForPhoneUpdate;    
            }
          
    }
In above example Contact Object Type has two SOQL and dml, that is worng way of writing trigger

Solution : Query both fields in single SOQL

trigger testReqTrigger on Account (after update) 
    {
        for(Account acc : Trigger.New)
            {
                // Query for both Fax and Phone
                // List contains contact records which do not have both Fax or Phone as null
                List<Contact> listConForUpdate = [Select Fax , Phone from Contact where (Fax != null  OR Phone != null ) And AccountId =: acc.id];        
                for(Contact con : listConForUpdate)
                    {
                         if(con.Fax != null)
                             {
                                 con.Fax = acc.Fax;
                                 if(con.Phone != null)
                                     con.Phone = acc.Phone;
                             }
                         else
                             {
                                 con.Phone = acc.Phone;
                             }    
                    }
                update listConForUpdate;
            }
           
    }

In above example we have used SOQL in a loop that can be removed with our first problems solution.

So these two are the basic practice that we should do so triggers work appropriately with bulk data also. Now after covering this basic practice we will discuss some problems of complex triggers, cyclic triggers where one trigger invokes another and there solutions and order of execution of the trigger.

Regards

Saturday, 14 May 2011

Writing Apex Trigger : My First Trigger

Hi,

Before we write our first trigger let us discuss the basix syntax of a trigger and what are the database activities/events which fires a trigger.
Syntax :

trigger <name> on Account (<events>) {

}
Here
1. Name is the name of the trigger this is required to provide and has to be unique for the object on which trigger is written. By uniqueness I mean to say that no two triggers on the same object can have similar name.

2. Events are the database activities which fires a trigger, this again is required for a trigger. So by this we can say Trigger is Apex Code that gets executed before and after of these operations.

  • Insert : Before and After
  • Update : Before and After
  • Delete : Before and After
  • Merge : Not directly, but both insert and delete trigger get fired for winning and losing records.
  • Upsert : Not directly, but both insert and update trigger gets fired
  • Undelete : After


Requirement : Now lets take an example of a requirement that whenever an Account gets updated then Fax field of the account should be copied in the fax field of all the contacts those have reference of this account.

trigger testReqTrigger on Account (after update) {
    for(Account acc : Trigger.New){
    List<Contact> listCon = [Select Fax from Contact where AccountId =: acc.id];        for(Contact con : listCon){
        con.Fax = acc.Fax;
        }
    update listCon;

    }

}
In above example we have not written the trigger which will use resources in optimized way, we will discuss trigger optimization in detail later.

Regards

Writing Apex Trigger : Trigger vs Workflow

Hi All,

Triggers are very essential in any business logic. Triggers are fired when any event gets executed in database. These events can be insertion, update or deletion of rows in data tables in the data tables. In Apex triggers are fired when any DML statement gets executed that means a new record added, existing record updated or deleted. Triggers in salesforce triggers are extended form of workflows. They provide more complex logic to be added to any DML action. So before learning how to write an Apex trigger it is important to make a decision when to go for a trigger not for workflow.

Trigger vs Workflow

S. No. Trigger Workflow
1. Triggers can not be updated on production org after being created via a managed package. Actions in workflows can be edited,removed and new actions can be added
2. More complex logic can be added in the triggers like DML actions on other object than the object on which trigger is written Less Complex logic is supported
3. Trigger get fired on more actions like on insert , update , delete and undelete Workflow get fired on insert and update
4. You can decide excution of trigger whether it should be before or after the initiation action like ( on before insert trigger or on after update trigger) Workflow only gets executed after any insert or update

So by above comparison you may decide when to opt for a trigger over a workflow.


Regards

Friday, 13 May 2011

Salesforce made me a Better Programmer:


Hi All,



Salesforce made me a Better Programmer:
I started my career 5 years back with .Net. All my college projects were also in .Net. I am working on salesforce for last four years. When I started working on salesforce I was a bit afraid specially of governor limits.  But soon I realize that these limits are friend not foe.
Governor Limits Friend not Foe: When I faced too many SOQL, too many dml or to many query rows I thought why there are such limits. But when I started using collections for resolving them soon I realized these limits are for my help. Now it has become a general practice for me to take care of these limits. Now If I look back to my code that I developed in .Net applications I would definitely write efficient code to improve performance. Use of collections for performance is something I learned because of Governor Limits.  
Test Class Coverage is to make things easy: When we first time created a Managed package and did a runAll tset first time. We got around 75 test failures and 60% code coverage. Our initial thought was why is it necessary when we have already tested the functionality and QA has passed it. It took next 4-5 days to fix those test methods and improve code coverage. In those 5 days we not only changed the test methods but also changed our APEX Code as well as there were some issues those we missed to figure out in our testing. That was the first benefit that we discovered of test methods but It was just start. When we found that after any bug fix in regression testing or after any enhancement we just needed to run the test and we saved so much effort. Now it has become a practice for us that we like to follow to write test cases covering all scenarios. And let me tell you that when we see this “All Test Success” and Code Coverage 100% , It’s a great feeling.
There are so many other reasons that could be made here. My conclusion on all is that Limits in Salesforce has never stopped me from doing anything but have made me to think for a better way. And that is why I have started this blog to help the people if I can.

Blog Purpose : 


This blog is to share and discuss Salesforce knowledge, tricks, problems, solutions, findings, new release features. I invite you all to join this and share your knowledge with others and learn salesforce together.

Regards

Tweet