Wednesday, November 23, 2016

Display collapsible data in VF page

Use Case

We may need to display collapsible data in VF page. This can be easily achieved using the VF component <Apex:PageBlockSection> . However this component is not always useful and may distort the UI when used with some specific components – like <Apex:repeat>.

Solution

We can customize our code to enclose the rows to be collapsed using  HTML tag <TBODY> and set its id dynamically. Now, using JavaScript function we can get collapsible and expandable data rows.

Reusable Code

VF Page

<apex:page controller="CollapsibleClass" sidebar="false">
  <script>
   function switchMenu(obj,obj1,obj2)
        {
            var el = document.getElementById(obj);                                     
            if ( el.style.display != 'none' ) {
            el.style.display = 'none';
            }
            else {
            el.style.display = '';
            }
            var e2 = document.getElementById(obj1);                                      
            if ( e2.style.display != 'none' ) {
            e2.style.display = 'none';
            }
            else {
            e2.style.display = '';
            }
             var e3 = document.getElementById(obj2);                                      
            if ( e2.style.display != 'none' ) {
            e3.style.display = 'none';
            }
            else {
            e3.style.display = '';
            }

        }
  </script>
  <table border="0" width="50%" id="myTable">
   <tr>
     <td width="1%" bgcolor="grey"></td>
     <td width="19%" bgcolor="grey"><b> Account Name</b> </td>
     <td width="19%" bgcolor="grey"><b>Account Type</b> </td>  
   </tr> 
   <apex:variable value="{!0}" var="rowNum1"/>  
  <apex:repeat var="account" value="{!accountDataList}" id="rFirst">
     <tr>
       <td width="1%" bgcolor="Lightblue">
         <apex:outputpanel id="plusimage" style="{!IF(account.hideOrShow == '', "display:none;", "")}" >
            <apex:image url="{!URLFOR($Resource.Images, 'Plus_Image.gif')}" onclick="switchMenu('inlinetablesec{!rowNum1}','{!$Component.minusimage}','{!$Component.plusimage}')" title="Show TSF details"/>
         </apex:outputpanel>
         <apex:outputpanel id="minusimage" style="{!account.hideOrShow}">
            <apex:image url="{!URLFOR($Resource.Images, 'Minus_Image.gif')}" onclick="switchMenu('inlinetablesec{!rowNum1}','{!$Component.plusimage}','{!$Component.minusimage}')" title="Hide TSF details"/>
         </apex:outputpanel>
        </td>
        <td width="20%" bgcolor="Lightblue">
           <apex:outputLink value="/{!account.id}" id="accountLink" target="_blank">{!account.name}</apex:outputLink>
        </td>                  
        <td width="19%"  bgcolor="Lightblue">
          {!account.type}
        </td>
      </tr> 
      <tbody id="inlinetablesec{!rowNum1}" style="{!account.hideOrShow}">
       <tr>   
          <td width="1%"></td>                
            <td bgcolor="grey" width="20%"><b>Contact Name</b></td>
           <td bgcolor="grey" width="20%"><b>Contact Phone</b></td>              

         </tr>  
      <apex:variable value="{!0}" var="rowNum"/>
      <apex:repeat var="cont" value="{!account.contacts}" id="rSecond"> 
      
        <tr>   
          <td width="1%"></td>                
            <td bgcolor="LightGrey" width="20%">{!cont.name}</td>
           <td bgcolor="LightGrey" width="20%">{!cont.phone}</td>              

         </tr>          
      <apex:variable var="rowNum" value="{!rowNum + 1}"/>   
      </apex:repeat>
         </tbody>
      <apex:variable var="rowNum1" value="{!rowNum1 + 1}"/>
  </apex:repeat>
  </table>
</apex:page>

Controller Class

public class CollapsibleClass {
public list<AccountData> accountDataList {get;set;}
  Public CollapsibleClass(){
    accountDataList = new list<AccountData>();
    prepareData();
  }
   //Wrapper class used to hold date for alternate table 4
     public class AccountData
     { 
        public String id {get; set;}  
        public String name {get; set;} 
        public String type {get; set;}
         public String hideOrShow {get; set;}
        public List<Contact> contacts {get;set;}   
           
        public AccountData()
        {
        
        }
      }       
      private void prepareData() {
        for (Account acc : [SELECT Account.Name,Account.type,(SELECT Contact.Name,Contact.Phone FROM contacts) FROM Account WHERE Account.Id IN (SELECT Contact.accountId FROM Contact) limit 5]) {
          AccountData accData = new AccountData();
          accData.id= acc.id;
          accData.name = acc.name;
          accData.type = acc.type;
          accData.contacts = acc.contacts;
          accData.hideOrShow  = 'display:none;';
          accountDataList.add(accData);
        }
      }
}

Screen Shot



No comments:

Post a Comment