Thursday, September 19, 2013

Tree view in visualforce

Climbing Tree structure in salesforce

This is going to be my first post on the web. Thanks to my crazy South Indian friend  +george thomas  to push me for this. This post is dedicated to ‘Abha Rani’ and ‘Bushra’.

One of our clients wanted to have a tree structure view of all the contact related to an Account such that the contacts who don’t  report to any-other contact become the parent node and the one reporting to a contact become its child node. The final tree structure that we will achieve following this post will look like this:



Follow the below steps :
Step 1: Download the j-query plug-in from the following link:
                                                     http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
and the files necessary for us are treeview.css, jquery.js, jquery.cookie.js, jquery.treeview.js now put these files in a folder and give it some name. I have named it “Jquerytreeview”. Now upload it as a static resource in salesforce and give it some name(Jtreeview).
Step 2:  The Visual Force Page code is given below:

<apex:page sidebar="true" Standardcontroller="Account" Extensions="ContactHierarchy" showheader="true">
<!-- Include the Jquery Script files -->
    <link rel="stylesheet" href="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.treeview.css')}"/>
    <script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.js')}" type="text/javascript"></script>
    <script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.cookie.js')}" type="text/javascript"></script>
    <script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.treeview.js')}" type="text/javascript"></script>
<!-- End of Javascript files -->
<script type="text/javascript">
        $(function() {
            $("#tree").treeview({
                collapsed: true,
                animated: "fast",
                control:"#sidetreecontrol"                
            });
        })
</script>
<br/> <br/> <br/>
<!-- Tree -->
<apex:pageBlock >
<div class="treeheader" style="height:0px;"> </div>
<div id="sidetreecontrol"><a href="?#"><font style="color:grey;">Collapse All</font></a> | <a href="?#"><font style="color:grey;">Expand All</font></a></div>
<ul id='tree'>
    <apex:repeat value="{!mainnodes}" var="parent1">
        <li><strong><apex:outputLink style="color:black;" value="/{!parent1.gparent.id}">{!parent1.gparent.firstName}</apex:outputLink></strong>
             <ul>
                 <apex:repeat value="{!parent1.parent}" var="child1">
                    <li><span class="formattextcon">
                    <apex:outputLink style="color:black;" value="/{!child1.id}">{!child1.FirstName}</apex:outputLink>
</span>
                <ul>
                 <apex:repeat value="{!parent1.child[child1.id]}" var="child2">
                    <li><span class="formattextcon">
                    <apex:outputLink style="color:black;" value="/{!child2.id}">{!child2.FirstName}</apex:outputLink>
                    </span>      
                        <ul>
                           <apex:repeat value="{!parent1.allchild[child2.id]}" var="child3">
                             <li><span class="formattextcon">
                             <apex:outputLink style="color:black;" value="/{!child3.id}">{!child3.FirstName}</apex:outputLink>
</span>
                                <ul>
                                    <apex:repeat value="{!parent1.allchild[child3.id]}" var="child4">
                                   <li><span class="formattextcon">
                                     <apex:outputLink style="color:black;" value="/{!child4.id}">{!child4.FirstName}</apex:outputLink>                                   
</span>
                                   </li>    
                                   </apex:repeat>
                               </ul>
                             </li>
                        </apex:repeat>
                       </ul>
                  </li>                 
                        </apex:repeat>
                </ul> </li>             
                        </apex:repeat>                     
             </ul>                             
        </li>
    </apex:repeat>
</ul>
</apex:pageBlock>
<!-- End of Tree -->       
</apex:page>

This page can show five level of parent-child relationship. If you want to go deeper just try putting some more repeat blocks in the visual force code.
Step 3: The controller for the above Visual force page is as follows:
public class ContactHierarchy {
public id accId;
public List<Contact> Root=new
List<Contact>();
Public ContactHierarchy(ApexPages.StandardController controller) {
accId=ApexPages.currentPage().getParameters().get('id');
    }
/* Wrapper class to contain the nodes and their children*/
public class cNodes
{
 public Contact gparent
{get; set;}
 Public List<Contact> parent {get;set;}
 Public Map<ID,List<Contact>> child {get;set;}
 Public Map<ID,List<Contact>> allchild {get;set;}
 Public cNodes(Contact gp,List<Contact> p, Map<ID,List<Contact>> c,Map<ID,List<Contact>> gc)
 {
     parent = p;
     gparent = gp;
     child=c;
     allchild=gc;
 }
}
/* end of Wrapper class */ 
Public List<cNodes> hierarchy;
Public List<cNodes> getmainnodes()
     {
hierarchy = new List<cNodes>();    
map<Id,list<Contact>> element = new
map<Id,list<Contact>>();
List<Contact> tempparent = [Select Id, FirstName,
LastName,ReportsTo.Id from Contact where AccountId=:accId ];
For(Contact c:tempparent)                   
{                   
if(c.ReportsTo.Id==null)                     
{
                            root.add(c);                     
}                  
}                   
System.Debug('root----->'+root);                 
for(Contact c: tempparent)                 
{
if(c.ReportsTo.Id!=null)                       
{
if(!element.containskey(c.ReportsTo.id))
                                {
             List<Contact>conlist = new List<Contact>();                                   
conlist.add(c);
element.put(c.ReportsTo.id, conlist );
                                }
                                else
                                {
List<Contact> templist=element.get(c.ReportsTo.Id);
element.remove(c.ReportsTo.Id);
 templist.add(c);
element.put(c.ReportsTo.Id,templist);
                                }
}
}
System.Debug('element------->'+element);  
integer i=0;  
Map<id,List<Contact>> element1 = new
Map<id,List<Contact>>();
Set<Contact> Con_list= new Set<Contact>();
          for(id ids : element.keyset())              
              Con_list.addall(element.get(ids));
for( contact con : Con_list)
{
if(element.containskey(con.id))
{
element1.put(con.id,element.get(con.id));
}
ELSE
{
RecordType rt = [Select id from RecordType where Name ='School' limit1];
contact newcon = new Contact();
newcon.RecordTypeId=rt.id;
newcon.CurrencyIsoCode='AUD';
newcon.FirstName='';
newcon.LastName='dummy';
List<Contact> tempc= new List<Contact>();
tempc.add(newcon); 
element1.put(con.id,tempc);
}
}
Map<ID,List<Contact>> icon_map= new  Map<ID,List<Contact>>();   
for(Contact cont : root)


                {
            
List<contact> parnt = element.get(cont.id);
            if(parnt != Null)
            {
for(contact ccd: parnt)
                            {
                List<Contact> icon = new List<Contact>();
                icon =element1.get(ccd.id);
                     IF(icon !=null && icon.size()>0)
                       icon_map.put(ccd.id,icon);
                       else
                               {
                                RecordType rt =[Select id from RecordType where Name ='School' limit 1];
                                contact newcon = new Contact();
                                newcon.RecordTypeId=rt.id;
                                newcon.CurrencyIsoCode='AUD';
                                newcon.FirstName='';
                                newcon.LastName='dummy';
                                icon = new List<Contact>();
                                icon.add(newcon);
                                icon_map.put(ccd.id,icon);  
                               }
                            }
            }
hierarchy.add(new cNodes(CONT,parnt,icon_map,element1)); 
i++;            
                 }
return
hierarchy;
    }   
}