Pages

Wednesday, October 22, 2008

How to Create Custom Related-List on Visualforce Pages

In the past few weeks in many cases I came across the requirement to add a custom list to the Object's detail page.

The list should be just like related-lists such as "Open Activities" or "Google Docs, Notes, & Attachments", however it is suppose to view a list of data which is somehow relevant to the object but not necessarily from an object directly related to the current object's page.

Let's consider this example, imagine we need to view a list of opportunities related to a Contact through it's Account relationship (not the ones that are directly linked to the Contact).



This is to say that if Contact A is linked to Account X and Account X has 5 opportunities linked to it, by viewing Contact A's details we would be able to view those opportunities as well.

Ok, now action, in order to do this we will need to create a new Visualforce Page and Controller extension.

So I add this text in front of http://yourOrg.salesforce.com/apex/SampleDetailPage and create the new page instantly (This is only possible when you profile is set to work in developer mode).


I set the page's Controller attribute to "Contact" and call my extension "SampleDetailPageCon".
On the page all I need to do is to show the existing Contact details based on whatever active layout target user has chosen and then add my related-list to the bottom of the page. The page code goes like this:


<apex:page standardController="Contact" extensions="sampleDetailPageCon">
<style>
.fewerMore { display: none;}
</style>
<apex:form >
<apex:pageMessages />
<apex:detail relatedList="true"></apex:detail>
<apex:pageblock id="CustomList" title="Related Opportunities" >
<apex:pageBlockTable value="{!oppz}" var="o" rendered="{!NOT(ISNULL(oppz))}">
<apex:column value="{!o.Name}"/>
<apex:column value="{!o.Account.Name}"/>
<apex:column value="{!o.Type}"/>
<apex:column value="{!o.Amount}"></apex:column>
<apex:column value="{!o.CloseDate}"/>
</apex:pageBlockTable>
<apex:outputLabel value="No records to display" rendered="{!(ISNULL(oppz))}" styleClass="noRowsHeader"></apex:outputLabel>
</apex:pageblock>
</apex:form>
</apex:page>



A few tips, normally at the end of detail page Salesforce publishes a component for viewing a few more or a few less records to adjust the size of the page.

Since our related list will be rendered under this component it might not be a bad idea to get rid of it. If you pay attention to be page's code you will see that a style tag has been added to the page that will just do that.

Apart from this everything else is very straight forward. Now all we need to do is to extend the Contact's standard controller and make it able to generate a list of related Opportunities as well.

Here is the Controller's Code:



public class sampleDetailPageCon {
private List<Opportunity> oppz;
private Contact cntact;
public sampleDetailPageCon(ApexPages.StandardController controller) {
this.cntact= (Contact)controller.getRecord();
}
public List<Opportunity> getOppz()
{
Contact con = [Select id, Account.id FROM Contact where id = :cntact.id];
if (con.Account == null)
return null;
oppz = [Select id, Name, Account.Name, CloseDate, Amount, Type from Opportunity where Account.id = :con.Account.id];
return oppz;
}
}




As you can see this also very simple. In the above code, I have just added a method called "getOppz()" in which I first try to see if the Contact is linked to any accounts and if yes then use the Account id to get a list of its Opportunities.



That's it! Now if you need your page to be used by Salesforce as default detail page all you need to do is:
  • Go to: Setup -> Customize -> Contacts -> Buttons and Links
  • Click on "override" next to "View" label
  • Select "Visualforce Page" and then your page from the drop down list

Now there is only one thing left, as you all have noticed every related-list has a hover feature on the top of the page where user can quickly view all the related-lists without scrolling down the whole page.



In my next article I will show you how you can go through the backdoor to add your related-list on the top of the page!


32 comments:

  1. Great tutorial. It saddens me that Salesforce doesn't provide things like this on their site from users. I'm definitely going to pay attention to this blog.

    I wanted to complete the look of what you started and was stuck when I got to Open Activities and Activity History. What would the SQL query be for Activities since it includes both Tasks and Events?

    ReplyDelete
  2. Mike, since you have two types of objects Tasks and Events the only way you can simulate the Salesforce Open Activities list is to:

    Create an apex class with your final lists' properties, such as: Action, Subject, Owner Name, Due Date, etc.

    Then using two loop commands create a list of this Object from Events and Tasks and pass it to a PageBlockTable.

    All you will need to do after this, is cosmetic stuff!
    Good luck!

    ReplyDelete
  3. Hi Sam. I noticed that you are having similar issues with your output that I am getting when trying to accomplish a similar task. The line that underlines the row seems to disappear when the columns don't have any data to display as in your type column. Have you been able to (or thought about) any way to fix this?

    Great tutorial by the way, I wish I would have found this before I started. :)

    ReplyDelete
  4. Looking forward to the follow-up post explaining how to get the custom related list added to the hover links at the top of the page...

    ReplyDelete
  5. This comment has been removed by a blog administrator.

    ReplyDelete
  6. I used your code and made some mods to show the contracts related list on the case detail page. When I set the cases view page to override and use the new vf page I lose the inline editing capability. Did you lose any inline functionality when you implemented this?


    Thanks
    Mike

    ReplyDelete
  7. Hi Mike,
    unfortunately, inline editing is not yet supported by Salesforce. I am hoping that they would add this feature to their system soon at least for object detail component.
    Regards,
    Sam

    ReplyDelete
  8. Here is screenshot of my issue:
    http://tinypic.com/view.php?pic=r8fds9&s=5

    Problem I'm facing is: EVENT standard object is not displaying my custom Related List properly as related list.

    can you have a look at it and guide me ?

    Thanks.

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. This is very nice of you Mr.Sam. I have a situation that i need to add custom button for the related list control how could add that.


    Aravind.Sriramaneni
    Appshark
    Hyderabad

    ReplyDelete
  11. Hello Sam,
    Great example. Is it possible to override only one section of related list.
    I have Contacts and cases on Account and want to add custom object as related with.

    Your example override all view, not just one related list.
    Thanks

    ReplyDelete
  12. Sam -
    In your original post you indicated you would follow-up with a method to place the hyperlink for the new related list at the top. Have you a solution for this as yet?

    ReplyDelete
  13. I am New in SalesForce APEX What I need to know is ....................
    I make a Apex:pageBlockTable which is working fine. I have data like this..

    id# Name RollNumber

    1 A 01
    2 B 02
    3 C

    Above u can see "C" has no Roll number so I want to create a link just infront of "C" so that user can create Roll number for "C".
    in .Net we can achive this task in rowdatabound event but how can it be in Salesforce means apex......
    I am waiting for ur kind response plz help me out.........

    ReplyDelete
  14. Hi Sam,

    This was extremely helpful. In fact, I have written a custom list very similar to the example below, to iterate through contacts from all child accounts for a Parent Account.

    My problem is that I have a list of 200 "child contacts" under some parent accounts. How do I create pagination for something of this sort? I saw your pagination post, but found it difficult to integrate with this example.

    See the code below:

    public class childAccount {

    private List acctz;
    private Account acct;

    public childAccount(ApexPages.StandardController controller) {
    this.acct= (Account)controller.getRecord();
    }

    public List getAcctz() { Account act = [Select id FROM Account where id = :acct.id];
    acctz = [Select id, Name, Address_Street__c, Address_City__c, Office__c, Type from Account where parentid = :act.id];
    return acctz;
    }

    }

    The Apex page, simply displays this list, as in your example.

    Any help wwould be much appreciated! thanks!

    Pranav

    ReplyDelete
  15. Very helpful, thank you.
    Please follow-up with a solution to place the custom related list at the top of the page (hoverlinks).

    ReplyDelete
  16. Nice effort, very informative, this will help me to complete my task.

    ReplyDelete
  17. how do i sort the in the same extension

    ReplyDelete
  18. Hi Sam,
    This was really great, I learned a lot from this article. Could you help me in creating "New Opportunity" custom button on "Related Opportunity" related list. I have created a custom button but a bit confuse how to open new Opportunity page by the click of custom button.

    ReplyDelete
  19. Hi Sam,

    Thanks for your Post!

    Regards,
    Mayank Joshi.

    ReplyDelete
  20. Thanks!! This post was very useful to me.Could you kindly provide the solution for creating hover links for the custom related list on the top of page.

    rock_thilak@yahoo.co.in

    ReplyDelete
  21. where is your article on hover links?

    ReplyDelete
  22. Nice article - but it is a bit of a limited solution. What if you want two custom related lists on your page (but don't want to merge the visualforce pages). Or perhaps you have two apps installed that each provide this functionality. You can only point the "view" setting to one visualforce page.

    ReplyDelete
  23. Hi Sam,

    Great post! I am trying to re-purpose your code to only exclude Opptys of a specific record type on the Contacts & Account Object but I am very new to code. Could you help me out with the queries? carlama8@hotmail.com

    ReplyDelete
  24. Hi Sam,

    Thank you for great post. It is really helpful. Can you please provide the code for implementing hover links?

    Thanks

    ReplyDelete
  25. Hi All,
    Any one has code for implementing hover links?

    Thank You.

    ReplyDelete
  26. How Can I display the Same Related List Table Inbetween the two related lists.
    I had to dispaly this list of table exactly after one of the related lists.

    ReplyDelete