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

Tweet