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


2 comments:

  1. I have same scenario with 4 different objects like grand parent, parent, child, grand child all are many to many relations. My scenario is to display and edit those records on the same page. Could you please help me how to do this type scenarios.

    ReplyDelete