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:
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; } }