[SalesForce] Grouping of Accounts and contacts..

I want to group accounts and contact…on VF page..I have used a wrapper class for this..

VF Page

 <apex:pageBlock >
      <apex:repeat value="{!wrapperLst}" var="wr">
      <apex:pageBlockSection title="{!wr.acc.Name}"/>
          <apex:pageBlockTable value="{!wr.gpaList}" var="gp">
              <apex:column headerValue="Name" >
                  {!gp.name}
              </apex:column>
          </apex:pageBlockTable>
      </apex:repeat>
      </apex:pageBlock>

Class

 accSearch =[select id,name,Phone,(Select id,Name from Contacts)from Account ];

 for(Account accRec:accSearch)
 {
     for(Contact gpa:accRec.contacts)
     {
             wrapperLst.add(new wrapperAcc(accRec,new List<Contacts>{gpa}));   
     }
 }
public class wrapperAcc
{
   public account acc{get;set;}

    public List<Contact> gpaList{get;set;}

    public wrapperAcc(Account acc,List<Contact> gpaList)
    {
        this.acc=acc;
        this.gpaList=gpaList;
    }

}

This is the output i am getting.So it is not grouped correctly.As there are 2 Accounts so only 2 sections should be created but there are 4..

I know the problem when i am adding the value to the wrapper list i have 2 loops so for the same account 2 values are added to the list.I only want to use a wrapper class .

I know the the solution where i can add the list directly with only a single loop.Can someone please help me finding the solution of this with wrapper class.May be creating some MAP or SET in wrapper class.

for(Account accRec:accSearch)
     {
         for(Contact gpa:accRec.contacts)
         {
                 wrapperLst.add(new wrapperAcc(accRec,new List<Contacts>{gpa}));   
         }
     }

Working Fine

 for(Account accRec:accSearch)
 {
         wrapperLst.add(new wrapperAcc(accRec,accRec.contacts));     
 }

enter image description here

Best Answer

Not sure why you are not just using your "Working Fine" solution...

If you want to use two loops for some reason, then you need to create the wrapper in the outer loop once only and collect the Contacts in the inner loop on that wrapper. Here is one way to do that:

for(Account accRec : accSearch) {
    WrapperAcc w = new WrapperAcc(accRec);
    wrapperLst.add(w);
    for (Contact gpa : accRec.contacts) {
        w.addGpa(gpa);
    }
}
public class WrapperAcc {
    public Account acc {get; private set;}
    public List<Contact> gpaList {get; private set;}
    WrapperAcc(Account acc) {
        this.acc = acc;
        this.gpaList = new List<Contact>();
    }
    void addGpa(Contact gpa) {
        gpaList.add(gpa);
    }
}

Note that at the moment the wrapper serves no purpose because your query results include the relationship list and so the page can work directly from those results:

<apex:pageBlock>
    <apex:repeat value="{!accSearch}" var="a">
    <apex:pageBlockSection title="{!a.Name}"/>
        <apex:pageBlockTable value="{!a.Contacts}" var="c">
            <apex:column headerValue="Name">
                {!c.name}
            </apex:column>
        </apex:pageBlockTable>
    </apex:repeat>
</apex:pageBlock>

Wrapper classes are needed if you want to apply presentation methods to the data such as extra formatting, or to add extra data such as selected flags, or adapt differing data to a single presentation, or present related data where the data can't be queried in a single query.

Related Topic