function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Michele Kleinhomer 10Michele Kleinhomer 10 

Display grouped data

I am hoping to produce Controller/VF pages to display data in the following manner.  I think I need to use wrappers, but I am not sure what I am doing.  I would really appreciate any help.  Thank you!  Michele

Account.tier
    Account.Name   Contact.Name
    Account.Name   Contact.Name
    Account.Name   Contact.Name

Account.tier
    Account.Name   Contact.Name
    Account.Name   Contact.Name
    Account.Name   Contact.Name


 
Dave_BoyceDave_Boyce
What is driving you towards doing this with Apex Controller/VF Pages vs a report in Salesforce or using Power BI which can talk directly to Salesforce Objects/Reports?
Michele Kleinhomer 10Michele Kleinhomer 10
We are currently displaying this information via a VF/controller to our Community users with the basic Community licenses. We like the way it looks. I don't know how to do the "group by" Account tier level. We are pretty happy with things the way they are but want to add the grouping feature so that we don't repeat the tier level for many accounts. Thank you, Michele
Dave_BoyceDave_Boyce
I'm assuming you have a SOQL call to get the data you are sending to an Apex visualization control.  You should be able to add the Group By on the SOQL call.
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_groupby.htm

Here is a potential link that might help using repeat to display in a simple format.
https://developer.salesforce.com/forums/?id=906F0000000BQCqIAO

If you share your SOQL w/ the Group By then that would help be able to give a more direct answer.
Michele Kleinhomer 10Michele Kleinhomer 10
I would love some guidance with my code. Below are the apxc and vfp pages. *DisplayGCMembers.vfp* body { background-color: white; } .pbTitle { white-space:nowrap; border:white; } {!c.account.tier_level_display__c} {!c.account.name} {!c.lastname} {!c.firstname} {!c.email}
********************************************************************************************** *DisplayGCMembers.apxc* public with sharing class DisplayGCMembers { ApexPages.StandardController con; account ee; Listlstaccount = new List(); Listlstcontacts = new List(); public DisplayGCMembers(ApexPages.StandardController controller) { con=controller; } public Listgetconts() { ee=(account)con.getRecord(); lstcontacts.clear(); accIds.clear(); lstaccount.clear(); if(ee.nameaccIds = new set(); }
Dave_BoyceDave_Boyce
Seems like based on your code you would need to add a SOQL call to get all the Account Names based on the Account Tier.  Either way seems like this link below would be a good example for a VF page using a group by on the account.tier_level_display__c
https://developer.salesforce.com/forums/?id=906F0000000BQCqIAO
Michele Kleinhomer 10Michele Kleinhomer 10
I am still struggling with this. Below is where I am. Can you provide guidance as to how to tie the lists together. Thank you! Michele I am attempting to display a VF page listing contacts under a Tier Level. Tier Level is a custom object that is a lookup field on the account record. For example, a contact belongs to an account. The account has an assigned Tier Level. I have the below controller. I am just putting the Contact, Account, and Tier Level records in three different lists. I then have a VF page that can print the lists individually. I need to tie together the Contact List and the Tier Level list so that it displays... Tier Level 1 Contact 1 Contact 2 Tier Level 2 Contact 3 Contact 4 I am not sure how to tie the lists together to accomplish this. Below is my code: - Controller public with sharing class TierList_CC { public List accountList{get;set;} public List contactList{get;set;} public List feeList{get;set;} public TierList_CC() { accountList = new List(); contactList = new List(); feeList = new List(); feeList = [select id, Name from Fee_and_Discount__c ]; contactList = [select id, LastName, FirstName, account.name, account.tier_level__r.name from Contact where GC_Rep__c=true order by account.name ]; } } VF Page**
Dave_BoyceDave_Boyce
I don't think there is a way in Apex to join Lists like there is in LINQ code Lists.  I suggest you do direct SOQL instead and you can build/test the SOQL in WorkBench before bringing into Apex/VF Page.  You can do joins in SOQL to get the related data into a single query.
https://developer.salesforce.com/page/A_Deeper_look_at_SOQL_and_Relationship_Queries_on_Force.com
Dave_BoyceDave_Boyce
Actually in APEX you might be able to accomplish with nested loops although I'd still recommend SOQL for joining the datasets.
Michele Kleinhomer 10Michele Kleinhomer 10
Thank you for the advice. I was able to get everything into an SOQL and then used code to display it in a table. I think this is pretty good stuff. When I have time, I want to try to move it out of a table into VF pageBlockTable if possibe. Below is the code. *VF Page* body { background-color: white; } .pbTitle { white-space:nowrap; border:white; } {!c.account.Tier_Level_Display__c} {!c.account.name} {!c.firstname} {!c.lastname} {!c.email} {!c.account.GC_Lottery_Winner_End_Date__c}
*Apex* public with sharing class DisplayGCMembers { ApexPages.StandardController con; account ee; Listlstaccount = new List(); Listlstcontacts = new List(); public DisplayGCMembers(ApexPages.StandardController controller) { con=controller; } public Listgetconts() { ee=(account)con.getRecord(); lstcontacts.clear(); accIds.clear(); lstaccount.clear(); if(ee.nameaccIds = new set(); }
Michele Kleinhomer 10Michele Kleinhomer 10
I sent the wrong code. Here is the VF page and Apex for grouping records on a field. body { background-color: white; } .pbTitle { white-space:nowrap; border:white; } table { border-collapse: collapse; border: 1px solid gray; } td { vertical-align: top; }
Tier Title Name Email
{!keyvalue.Account.Tier_Level__r.name} {!keyvalue.Account.Name} {!keyvalue.Name} {!keyvalue.Email}
Controller public class GCReps { public GCReps(ApexPages.StandardController controller) { } public Map getContactsByTierLevel(){ List result = [SELECT Account.Tier_Level__r.Name, Account.name, Name, Email FROM Contact where GC_Rep__c=true order by account.tier_level__r.Name,account.name,lastname,firstname ]; // Group Contacts by Account Map contactsByTierLevel = new Map(); for(Contact cont: result){ if(null == cont.Account.Tier_Level__r.Name) continue; contactosListWrapper empresa = contactsByTierLevel.get( cont.Account.Tier_Level__r.name); if(null == empresa){ contactsByTierLevel.put(cont.Account.Tier_Level__r.name, new contactosListWrapper(new List()) ); } contactsByTierLevel.get(cont.Account.Tier_Level__r.name ).contactList.add(cont); } return contactsByTierLevel; } // List of contacts and details class contactosListWrapper { public List contactList {get; set;} public Integer numOfContacts { get{ return contactList.size(); } set; } public Id firstOfList{ get{ return contactList[0].Id; } set; } public contactosListWrapper(List listContacts){ contactList = listContacts;} } }
Michele Kleinhomer 10Michele Kleinhomer 10
I am wondering if you can help with my test case for the code I wrote. I can't seem to get past 41%. Thank you! Michele Controller public class GCReps { public GCReps(ApexPages.StandardController controller) { } public Map getContactsByTierLevel(){ List accresult = [SELECT id FROM account ]; List result = [SELECT Account.Tier_Level__r.Name, Account.name, Name, Email FROM Contact where GC_Rep__c=true order by account.tier_level__r.Name,account.name,lastname,firstname ]; // Group Contacts by Account Map contactsByTierLevel = new Map(); for(Contact cont: result){ if(null == cont.Account.Tier_Level__r.Name) continue; contactosListWrapper empresa = contactsByTierLevel.get( cont.Account.Tier_Level__r.name); if(null == empresa){ contactsByTierLevel.put(cont.Account.Tier_Level__r.name, new contactosListWrapper(new List()) ); } contactsByTierLevel.get(cont.Account.Tier_Level__r.name ).contactList.add(cont); } return contactsByTierLevel; } // List of contacts and details class contactosListWrapper { public List contactList {get; set;} public Integer numOfContacts { get{ return contactList.size(); } set; } public Id firstOfList{ get{ return contactList[0].Id; } set; } public contactosListWrapper(List listContacts){ contactList = listContacts;} } }​ VF Page body { background-color: white; } .pbTitle { white-space:nowrap; border:white; } table { border-collapse: collapse; border: 1px solid gray; } td { vertical-align: top; }
Tier Title Name Email
{!keyvalue.Account.Tier_Level__r.name} {!keyvalue.Account.Name} {!keyvalue.Name} {!keyvalue.Email}
Current Test Class @isTest private class TestGCReps { static testMethod void TestGCReps() { PageReference pageRef = Page.GCReps; //Create test account Account acc = new Account(Name='Your Account Name', recruitment_begin_date__c= Date.valueOf('2008-01-01'), AccountSource='Website', tier_level__c='a0D6A000000SzO2', recruitment_primary_contact__c='0056A000000zP7Z', billingstate='North Carolina', priority__c='High'); insert acc; Account acc2 = new Account(Name='Cincinnati', recruitment_begin_date__c= Date.valueOf('2008-01-01'), AccountSource='Website', tier_level__c='a0D6A000000SzO2', recruitment_primary_contact__c='0056A000000zP7Z', billingstate='North Carolina', priority__c='High'); insert acc2; //Create test contact Contact cont = new Contact(firstname='Your first Name', Title='Admin2', lastName = 'Your last Name', AccountID=acc.id, GC_Rep__c=true);//if you have more contact field please put in here insert cont; Contact cont2 = new Contact(firstname='Smithy', title='Admin', lastName = 'Johnny', Accountid=acc2.id, GC_Rep__c=true);//if you have more contact field please put in here insert cont2; system.Test.startTest(); integer count; ApexPages.StandardController sc = new ApexPages.StandardController(acc); GCReps testIPF = new GCReps(sc); testIPF.getContactsByTierLevel(); // contactosListWrapper() wrap1 = new contactosListWrapper(); System.Test.stopTest(); } }
Dave_BoyceDave_Boyce
Can you use the "Add a Code Sample < >" widget on the editor bar?  Makes is easier to see the code.
Example below using the add a code sample...
Controller public class GCReps {
    public GCReps(ApexPages.StandardController controller) { }

    public Map getContactsByTierLevel() {
        List accresult = [SELECT id FROM account ];
        List result = [
            SELECT Account.Tier_Level__r.Name, Account.name, Name, Email 
            FROM Contact where GC_Rep__c=true 
            order by account.tier_level__r.Name,account.name,lastname,firstname];
:

 
Michele Kleinhomer 10Michele Kleinhomer 10
Controller:
-------------
public cla3ss GCReps {
public GCReps(ApexPages.StandardController controller) {
}
    
  
  
    public Map<String,contactosListWrapper> getContactsByTierLevel(){
      List<Account> accresult = [SELECT id FROM account ];  
      List<Contact> result = [SELECT Account.Tier_Level__r.Name, Account.name, Name, Email FROM Contact where GC_Rep__c=true order by account.tier_level__r.Name,account.name,lastname,firstname ];
    
      // Group Contacts by Account                                
      Map<String,contactosListWrapper> contactsByTierLevel = new Map<String,contactosListWrapper>();
      for(Contact cont: result){
        if(null == cont.Account.Tier_Level__r.Name) continue;
        contactosListWrapper empresa = contactsByTierLevel.get(cont.Account.Tier_Level__r.name);
        if(null == empresa){
            contactsByTierLevel.put(cont.Account.Tier_Level__r.name, new contactosListWrapper(new List<contact>()) );    
        }
        contactsByTierLevel.get(cont.Account.Tier_Level__r.name).contactList.add(cont);
      }
      
      return contactsByTierLevel;
    }
    
    
    
    
     // List of contacts and details  
   public class contactosListWrapper {
       
       public List<Contact> contactList {get; set;}
       
       public Integer numOfContacts {
          get{
            return contactList.size();
          }
          set;
       }
       
       public Id firstOfList{
          get{
            return contactList[0].Id;
          }
          set;
       }
             
       public contactosListWrapper(List<contact> listContacts){
           contactList = listContacts;}
}

           
}
 
VisualForce

<apex:page showHeader="false" standardStylesheets="true" standardController="contact" extensions="GCReps" sidebar="false" docType="html-5.0" applyBodyTag="False" applyHtmlTag="False">
 <style type="text/css">
        body {
    background-color: white;
}
        .pbTitle {
        white-space:nowrap;
        border:white;
    }
     table {
     border-collapse:  collapse;
     border: 1px solid gray;
     }
     
     td {
     vertical-align:  top;
     }


    </style>
      <table border="1" cellspacing="0" width="60%" id="tbl">
    <thead>
        <th> Tier </th>
        <th> Title </th>
        <th> Name </th>
        <th> Email </th>
    </thead>
              <apex:repeat value="{!contactsByTierLevel}" var="key" >      
      <apex:repeat value="{!contactsByTierLevel[key].contactList}" var="keyvalue" > 
          <tr>
                         <td vertical-align="top" rowspan="{!contactsByTierLevel[key].numOfContacts}" 
                             style="display:{!IF(CASESAFEID(keyvalue.id)==CASESAFEID(contactsByTierLevel[key].firstOfList), 'table-data','none' )};"> 
                             {!keyvalue.Account.Tier_Level__r.name} </td>
               <td> {!keyvalue.Account.Name} </td>
          <td> {!keyvalue.Name} </td>
          <td> {!keyvalue.Email} </td>  

          </tr>
                  </apex:repeat>
          </apex:repeat>
    </table>  
</apex:page>
 
Test Class

@isTest

private class TestGCReps {
    static testMethod void TestGCReps() {
        
     
        PageReference pageRef = Page.GCReps;
        
        //Create test account
        Account acc = new Account(Name='Your Account Name', 
                                  recruitment_begin_date__c= Date.valueOf('2008-01-01'),
                                 AccountSource='Website',
                                  tier_level__c='a0D6A000000SzO2',
                                 recruitment_primary_contact__c='0056A000000zP7Z',
                                 billingstate='North Carolina',
                                 priority__c='High');
        
        insert acc;
         Account acc2 = new Account(Name='Cincinnati', 
                                  recruitment_begin_date__c= Date.valueOf('2008-01-01'),
                                 AccountSource='Website',
                                  tier_level__c='a0D6A000000SzO2',
                                 recruitment_primary_contact__c='0056A000000zP7Z',
                                 billingstate='North Carolina',
                                 priority__c='High');
        
        insert acc2;
        
        //Create test contact
        Contact cont = new Contact(firstname='Your first Name', 
                                   Title='Admin2', lastName = 'Your last Name', AccountID=acc.id, GC_Rep__c=true);//if you have more contact field please put in here
        insert cont;
        
        Contact cont2 = new Contact(firstname='Smithy', title='Admin', lastName = 'Johnny', Accountid=acc2.id, GC_Rep__c=true);//if you have more contact field please put in here
        insert cont2;
        
        
        system.Test.startTest();
            integer count;
       
            ApexPages.StandardController sc = new ApexPages.StandardController(acc);
            GCReps testIPF = new GCReps(sc);
            
            testIPF.getContactsByTierLevel();
        List<Contact> testContactList = new List<Contact>();
        contactosListWrapper wr = new contactosListWrapper();
        // count = TestIPF.contactosListWrapper();
           

            
        System.Test.stopTest();
    }
}

 
Michele Kleinhomer 10Michele Kleinhomer 10
I got to 78% covered code. I think I am good. Thank you for your support/help. Michele
Dave_BoyceDave_Boyce
Great - don't forget to add some Asserts in your code in the spirit of UTs so you can help prevent a break in functionality later when code changes.

System.Assert*

Typically you should have a single Assert per test scenario to make it easier to manage test code and better trackdown functionality related to UT failures.