+ Start a Discussion
John NeffJohn Neff 

Trying to dynamically group & display query results - trouble with Array

Hello, 

I am trying to create a page where I can dynamically group querry results, and am using the code in this blog post as a template: template (http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/)

The difference is that I am trying to do this with a custom object instead of a standard object. 

Here is my controller: 
 
public with sharing class DisplaySectionsController {

    public List<PI_Vendor__c> vendors {get;set;}
    public String[] states {get;set;}

    public void load() {
    
    vendors = [Select ID, Name, State__c from PI_Vendor__c WHERE State__c IN ('DE','PA','MD')];
    
    Set<String> stateSet = new Set<String>();
    for (PI_Vendor__c v : vendors)
        stateSet.add(v.State__c);
        
    states = new String[stateSet.size()];
    Integer i = 0;
    for (String state : stateSet) {
        states[i] = state;
        i++;
        }
       }
      }

and here is my vf page: 
 
<apex:page controller="DisplaySectionsController" action="{!load}" sidebar="false">  
  <apex:sectionHeader title="My Sample Display Page" subtitle="Group by States" 
    description="This page shows how you can dynamically group results by field value."/>

  <apex:repeat value="{!states}" var="state">

    <apex:pageBlock title="{!state}">

      <apex:repeat value="{!vendors}" var="vnd"> 

        <apex:outputPanel rendered="{!IF(state=vendors.State__c,true,false)}">
        {!vnd.Name} - {!vnd.State__c}<br/>
        </apex:outputPanel>

      </apex:repeat>

    </apex:pageBlock>

  </apex:repeat>

</apex:page>

but I am getting the following error: 
 
Error: Unknown property 'VisualforceArrayList.State__c'

What can I do to make this work with a custom object?  And more importantly, where am I currently going wrong? 

Thanks in advance!

John
 
Best Answer chosen by John Neff
CyberJusCyberJus
I forgot to initialize the Map. Add this before your for loop (after the stateSet initilization)

vendorMap = new Map<String, List<PI_Vendor__c> >();




 

All Answers

CyberJusCyberJus
Your issue is in line 11 of your Visualforce page. 
<apex:outputPanel rendered="{!IF(state=vendors.State__c,true,false)}">
In your usage, vendors is an array, so it does not have a State__c property. You probably want state=vnd.State__c which is your repeat variable.

However, I am not sure this is the most efficent way to get what you want. It would be more efficent to build a List of states and then a Map that corresponds. That would prevent pointless looping. I modified your code below:
public with sharing class DisplaySectionsController {
    public String[] states {get;set;}
    public Map<String, List<PI_Vendor__c> > vendorMap {get; set;}

    public void load() {
    
    List<PI_Vendor__c> vendors = [Select ID, Name, State__c from PI_Vendor__c WHERE State__c IN ('DE','PA','MD')];
    
    Set<String> stateSet = new Set<String>();
    for (PI_Vendor__c v : vendors) {
        states.add(v.State__c);
        if (!vendorMap.containsKey(v.State__c)) vendorMap.put(v.State__c, new List<PI_Vendor__c>());
       vendorMap.get(v.State__c).add(v);
    }
}
 
<apex:page controller="DisplaySectionsController" action="{!load}" sidebar="false">  
  <apex:sectionHeader title="My Sample Display Page" subtitle="Group by States" 
    description="This page shows how you can dynamically group results by field value."/>

  <apex:repeat value="{!states}" var="state">

    <apex:pageBlock title="{!state}">

      <apex:repeat value="{!vendorMap[state]}" var="vnd"> 

        <apex:outputPanel  layout="block">
        {!vnd.Name} - {!vnd.State__c}
        </apex:outputPanel>

      </apex:repeat>

    </apex:pageBlock>

  </apex:repeat>

</apex:page>



 
John NeffJohn Neff
Thank you CyberJus - this is very helpufl.  Though I am getting this error when I try to view the page: 
 
System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!load}' in component <apex:page> in page grouptest: Class.DisplaySectionsController.load: line 15, column 1

Class.DisplaySectionsController.load: line 15, column 1

 
CyberJusCyberJus
I forgot to initialize the Map. Add this before your for loop (after the stateSet initilization)

vendorMap = new Map<String, List<PI_Vendor__c> >();




 
This was selected as the best answer
John NeffJohn Neff
this is awesome, thank you so much!!