Thursday, October 18, 2012

Updating sObject Dynamically in Salesforce

Recently I came across a requirement where I have to update the sobject dynamically.
Everybody is familiar with inserting the sobject dynamically.

It is very simple and the solution is :

Schema.SObjectType t = Schema.getGlobalDescribe().get('Account');
SObject sObjectAccount = t.newSObject('0013000121Bclpu');
sObjectAccount.put('Name', 'Account Update');
Update sObjectAccount;
 
Just we have to pass the Id in the method newSObject.
  

Wednesday, October 10, 2012

Pagination with maintaing the state of selected records

Hi All,

I have seen many people implemented pagination using salesforce, but recently I have come across a situation where I have to select list of records using pagination and process the records which are selected.

If use the StandardSetController, the check-boxes don’t maintain state if you check one and then go to the next page.
To solve this problem I have implemented custom Iterator.

You can run this demo in my developer org 



First Class Code:
global class CustomIterable implements Iterator<list<AccountInner>>{

   List<Account> accs {get; set;}
   list<AccountInner> accInnerList {get; set;}
   list<AccountInner> accInnerListRequested {get; set;}
   AccountInner accInnerObj;
   Integer i {get; set;}
   public Integer setPageSize {get; set;}

   public CustomIterable(string sQuery){
       //accs = [SELECT Id, Name, NumberOfEmployees FROM Account Limit 36];
       accs = Database.Query(sQuery);
       accInnerList = new list<AccountInner>();
       accInnerListRequested = new list<AccountInner>();    
       for(Account a : accs) {
            accInnerObj = new AccountInner(false, a);
            accInnerList.add(accInnerObj);
       }
       setPageSize = 10;
       i = 0;
   }  

   global boolean hasNext(){
       if(i >= accInnerList.size()) {
           return false;
       } else {
           return true;
       }
   }
  
   global boolean hasPrevious(){
       system.debug('I am in hasPrevious' + i);
       if(i <= setPageSize) {
           return false;
       } else {
           return true;
       }
   }  

   global list<AccountInner> next(){      
       system.debug('i value is ' + i);
       accInnerListRequested = new list<AccountInner>();
       integer startNumber;
       integer size = accInnerList.size();
       if(hasNext())
       { 
           if(size <= (i + setPageSize))
           {
               startNumber = i;
               i = size;
           }
           else
           {
               i = (i + setPageSize);
               startNumber = (i - setPageSize);
           }
          
           system.debug('i value is =====' + i);
           system.debug('i value is 2==== ' + (i - setPageSize));
          
           for(integer start = startNumber; start < i; start++)
           {
               accInnerListRequested.add(accInnerList[start]);
           }
       }
       return accInnerListRequested;
   }
  
   global list<AccountInner> previous(){     
       accInnerListRequested = new list<AccountInner>();
       system.debug('i value is previous before =====' + i);
       integer size = accInnerList.size();
       if(i == size)
       {
           if(math.mod(size, setPageSize) > 0)
           {   
               i = size - math.mod(size, setPageSize);
           }
           else
           {
               i = (size - setPageSize);
           }
       }
       else
       {
           i = (i - setPageSize);
       }
      
       system.debug('i value is previous =====' + i);
       system.debug('i value is 2previous ==== ' + (i - setPageSize));
      
       for(integer start = (i - setPageSize); start < i; ++start)
       {
           accInnerListRequested.add(accInnerList[start]);
       }
       return accInnerListRequested;
   }  
}

Second Class:
global Class AccountInner
{
    public boolean isSelected {get;set;}
    public Account acc {get;set;}
   
    public AccountInner(boolean isSelected, Account acc)
    {
        this.isSelected = isSelected;
        this.acc = acc;
    }
}

Visual force page :
<apex:page controller="Example1">
  <apex:form >
      <apex:sectionHeader title="Pagination" subtitle="Hi"/>
      <apex:pageBlock >
          <apex:pageBlockSection >
              <apex:pageBlockTable value="{!accInnerObj}" var="inner">
                  <apex:column >
                      <apex:inputCheckbox value="{!inner.isSelected}"/>
                  </apex:column>
                  <apex:column headerValue="Account">
                      <apex:outputText value="{!inner.acc.Name}" />
                  </apex:column>   
              </apex:pageBlockTable>
          </apex:pageBlockSection>
      </apex:pageBlock>
     
      <br/>
      <apex:commandButton value="<<Previous" action="{!previous}" rendered="{!hasPrevious}"/>
      <apex:commandButton value="Next >>" action="{!next}" rendered="{!hasNext}"/>
     
  </apex:form>
</apex:page>

Corresponding Controller:
public class Example1 {
   
    CustomIterable obj;
    public list<AccountInner> accInnerObj {get;set;}
   
    public Example1 () {      
        string sQuery = 'SELECT Id, Name, NumberOfEmployees FROM Account Limit 36';
        obj = new CustomIterable(sQuery);
        obj.setPageSize = 10;
        next();
    }
   
    public Boolean hasNext {
        get {
            return obj.hasNext();
        }
        set;
    }
   
    public Boolean hasPrevious {
        get {
            return obj.hasPrevious();
        }
        set;
    }
   
    public void next() {
        accInnerObj = obj.next();
    }
   
    public void previous() {
        accInnerObj = obj.previous();
    }
}