1

I would like to be able to group a custom list that I have built with the help of an inner class. This list looks like the following array when I send it to json serialize json = json.serialize(eSummary);

[
  {
    "TypeName": "Type 1",
    "Times": "9am - 10am",
    "Name": "Event 1",
    "Description": "This is the description for type name: type 1",
    "Id": "a09N0000002R0oeIAC"
  },
  {
    "TypeName": "Type 1",
    "Times": "9am - 5pm",
    "Name": "Event 2",
    "Description": "This is the description for type name: type 1",
    "Id": "a09N0000002R0p4IAC"
  },
  {
    "TypeName": "Type 1",
    "Times": "9am - 5pm",
    "Name": "Event 3",
    "Description": "This is the description for type name: type 1",
    "Id": "a09N0000002R0dpIAC"
  },
  {
    "TypeName": "Type 2",
    "Times": "6:30pm - 9.00pm",
    "Name": "Event 4",    
    "Description": "This is description for the second type of typename",
    "Id": "a09N0000003LxoEIAS"
  }
]

I think I will need to group this list by TypeName in order to be able to displayed a VF page like this:

TypeName: Type 1

Description:This is the description for type name: type 1

  • Event 1
  • Event 2
  • Event 3

TypeName: Type 2

Description: This is description for the second type of typename

  • Event 4

I found a similar display grouping in the following blog URL: http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/

I am not sure if I have to modify my list, or if I dont need to modify the list and somehow using the visualforce components I can create this type of grouping

I found this similar question Display grouping in a Vf page however I dont want to modify the construction of my list as I will probably have to change the whole controller, now that the list is formed I prefer maybe to manipulate it to create the grouping, if necessary.

  • Hi Manza. I updated your question to properly format the JSON. Here is a link to do that in the future - salesforce.stackexchange.com/editing-help#code - Other than that, great question providing an example of what you want to do as well as links to research you have done. – Jesse Altman Jun 19 '14 at 11:24
1

I would write have two inner classes:

public class TypeWrapper{
    public String typeName {get;set;}
    public String description {get;set;}
    public List<EventWrapper> eventWrappers {get;set;}
    public TypeWrapper(String typeName, String description, List<EventWrapper> eventWrappers){
        this.typeName = typeName;
        this.description = description;
        this.eventWrappers = eventWrappers;
    }
}

public class EventWrapper{
    public String eventName {get;set;}
    public String times {get;set;}
    public Id eventId {get;set;}
    public EventWrapper(String eventName, String times, Id eventId){
        this.eventName = eventName;
        this.times = times;
        this.eventId = eventId;
    }
}

These inner classes could live anywhere, but for the sake of simplicity, I'll just throw them on the controller.

public MyController{
    private Map<String, TypeWrapper> typeWrapperByTypeName {get;set;}
    public MyController(){
        // I don't know what your object type is, but I am going to assume they are of type Random_Object__c and there is a list of them on randomObjects
        setTypeWrapperByTypeName(randomObjects);
    }

    private void setTypeWrapperByTypeName(List<Random_Object__c> randomObjects){
        typeWrapperByTypeName = new Map<String, TypeWrapper>();
        for(Random_Object__c random:randomObjects){
            if(typeWrapperByTypeName.containsKey(random.TypeName)){
                typeWrapperByTypeName.get(random.TypeName).eventWrappers.add(new EventWrapper(random.Name, random.Times, random.Id));
            }else{
                typeWrapperByTypeName.put(random.TypeName, new TypeWrapper(random.TypeName, random.Description, new List<EventWrapper>());
                typeWrapperByTypeName.get(random.TypeName).eventWrappers.add(new EventWrapper(random.Name, random.Times, random.Id));
            }
        }
    }

    public List<TypeWrapper> getAllTypeWrappers(){
        return typeWrapperByTypeName.values();
    }

    public class TypeWrapper{
        public String typeName {get;set;}
        public String description {get;set;}
        public List<EventWrapper> eventWrappers {get;set;}
        public TypeWrapper(String typeName, String description, List<EventWrapper> eventWrappers){
            this.typeName = typeName;
            this.description = description;
            this.eventWrappers = eventWrappers;
        }
    }

    public class EventWrapper{
        public String eventName {get;set;}
        public String times {get;set;}
        public Id eventId {get;set;}
        public EventWrapper(String eventName, String times, Id eventId){
            this.eventName = eventName;
            this.times = times;
            this.eventId = eventId;
        }
    }
}

The general idea above is that you are creating a Map on your key, which in this case is your TypeName. The reason for this is you only want a single TypeWrapper created for each TypeName. Once it gets created once, you just add EventWrappers to it until you run through your whole list. This can all be seen in the setTypeWrapperByTypeName() method.

When you want to retrieve that List, simply call the values() method on your Map. This can be seen in the getAllTypeWrappers() method. Once you have that set up, it should be as simple as using two <apex:repeat> on your Visualforce page.

<apex:repeat value="{!allTypeWrappers}" var="typeWrapper">
    <apex:outputText value="{!typeWrapper.typeName}"/>
    <apex:outputText value="{!typeWrapper.description}"/>
    <ul>
        <apex:repeat value="{!typeWrapper.eventWrappers}" var="eventWrapper">
            <li><apex:outputText value="{!eventWrapper.eventName}"/></li>
        </apex:repeat>
    </ul>
</apex:repeat>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.