Wednesday, January 25, 2012

Identifying SobjectType Dyanamically

getKeyPrefix of Schema.getGlobalDescribe can be used to identify dynamically the SobjectType in Apex.

String prefix = recordId.substring(0,3);
String objectType;
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
for(Schema.SObjectType s : gd.values()){
    if(prefix == s.getDescribe().getKeyPrefix()){
        objectType = s.getDescribe().Name;
    }
}

recordId consists the Id of the sobject Record for whose SobjectType needs to be identified. Above piece of code does it well.

Wednesday, January 11, 2012

Build your Own Standard set controller

Standard set controller can be used for many objects . Recently i found that it cannot be used with activity objects(Open activity and activity history). Also there are many other Restrictions placed on these objects. You cannot query on these objects directly. It has to be a nested SOQL within an object using a relationship name.

So coming back to my requirement i needed to roll up related list for all the activities in the account hierarchy for the topmost parent. For other related list i achieved it through standardset controller. But for activity alone i created a class which would behave like a standard set controller.

public class SetActivityClass {
        public integer pagenumber{get;set;}
        public integer totalpages{get;set;}
        public integer pagesize{get;set;}
        public list<sobject> sobjectList{get;set;}       
 public SetActivityClass(list<sobject> sobjectList){
        pagenumber =1;
        pagesize = 60;
        this.sobjectList=sobjectList;
        totalpages= Integer.valueof(math.ceil((double)sobjectList.size()/(double)pagesize ));
        }
        public boolean gethasprevious(){
          return (pagenumber != 1);
        }
        public boolean gethasnext(){
            return (pagenumber != totalpages);
        }
        public pagereference Previous(){
        if(gethasprevious())
            pagenumber--;
            return null;
        }
        public pagereference next(){
        if(gethasnext())
            pagenumber++;
            return null;
        }
        public list<sobject> getRecords(){
        list<sobject> Sactivity = new list<sobject>();       
            for(integer counter2=(pagenumber-1)*pagesize;counter2<(math.min(pagenumber*pagesize,sobjectList.size()));counter2++){
                Sactivity.add(sobjectList.get(counter2));
            }
            return Sactivity;
        }
          
    } 

oActivityHistory= new SetActivityClass(ActivityHistoryList);
        oOpenActivity= new SetActivityClass(OpenActivityList); 


public List<OpenActivity> getGoToListOpenActivities() {
    return oOpenActivity.getRecords();       
    }

public List<ActivityHistory> getGoToListActivityHistories() {
    return oActivityHistory.getRecords();       
    }

Just like the standard set controller, this SetActivityClass has methods to return next set or previous set of records. These can be added to command links as they are pagereference method. Also Hasprevious and Hasnext can be called from the page to check if the previous or next set of records exist.Pagenumber denotes the current page number. Pagesize determines no of records to be displayed in the page. I would recommend a size of 40 -60 in a page for better readability by Users(I have hardcoded it as 60). Total pages is calculated based on this pagesize.

Also note that getRecord function accepts and returns generic sobject. I used the same class for both activityhistory and openactivity.This Class can be slightly tweaked to handle list of objects of your custom class  as well.

Here is how i would display it in the page

<apex:panelGrid columns="2">                 
 <apex:commandLink action="{!oOpenActivity.previous}" rendered={!oOpenActivity.hasPrevious}"> Previous </apex:commandLink>
  <apex:commandLink action="{!oOpenActivity.next}" rendered="{!oOpenActivity.hasNext}" >Next </apex:commandLink>           
  </apex:panelGrid>

<apex:pageBlockTable id="tableMasterAccountOpenActivities" var="openact"  value="{!GoToListOpenActivities}">
 <apex:column .....
.......
</apex:pageblocktable>

And whenever the next and previous is click make sure atleast the pageblock tabele is rerendered if not the whole page based on your logic. I  have shown the VF for openactivity. similarly u can use it for activity history. Also you can use the same logic in building your own custom class wrapper object standard set controller this way.

Saturday, January 7, 2012

Javascript for Ghost Text in Salesforce

There will be a need to add ghost text which will be like a help text or format in which the value needs to be there for a particular input field in visual force. I would suggest use visual force help text for it. But if ghost text is required use the following script.



Trick here use the script after all the component is loaded preferably before </apex:page> tag.

        <script type="text/javascript">  
            var txtContent  = document.getElementById("{!$Component.theform.thepb.thepbs.mp}");
            var defaultText = '+91 - *** *** ****';
            txtContent.value = defaultText;           
            txtContent.style.color = '#CCC';           
            txtContent.onfocus = function() {
              if (this.value == defaultText) {   
                this.value = '';
                this.style.color = '#000';
              }
            }
            txtContent.onblur = function() { 
              if (this.value == '') {   
                this.value = defaultText;
                this.style.color = '#CCC';
              }
            }
        </script>  

Also Make sure to handle the save if the field is filled with ghost text(Default text here).