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