+ Start a Discussion
neckrneckr 

Nested Data List Example

Hi, does anyone have an example or sample code of how I can create a list of Cities grouped by Province/State and Country within Visual Force.

 

I have my data in Service_Area__c object with populated records that have Country__c, Province_State__c and City__c  fields the object Name is a unique combination of Country Code, Province Code and City combined. For example CAD_ON_TORONTO.

 

I would like the vf page to look like:

 

Country X

      Province/State A

           City 1

           City 2

           etc

 

       Province/State B

             City 1

             City 2

             etc

 

Country Y

      Province/State A

           City 1

           City 2

           etc

 

       Province B

             City 1

             City 2

             etc

 

 

  thanks

Best Answer chosen by Admin (Salesforce Developers) 
Shashikant SharmaShashikant Sharma

Hi neckr,

 

I have created an example for Showing Hierarchy In VFP on my Blog Force School.

 

Please check http://forceschool.blogspot.com/2011/06/show-hierarchy-in-visualforce-page.html

 

Replicate your case with the example that i used there, Please ask any question if any confusion

All Answers

Shashikant SharmaShashikant Sharma

Create a List<List<String>> listOfCountriesWithInfo = 

 

inner list will have Country,State,Cities in this sequesnce

 

add values in inner list like this

 

list.add('CountryName')

 

list.add('&nbsp;StateName')

 

list.add('&nbsp;&nbsp;CityNameName')

 

 

Use

<Repeat value="{!listOfCountriesWithInfo}" var="countryInfo">

      <Repeat value="{!countryInfo}" var="info">

    <apex:oututLabel value="{!addspace}{!info}" escape="false">

     </Repeat>

</Repeat>

 

 

neckrneckr

Can you please expand on the controller code, I am a bit lost on implementing your suggestion.

 

This is my attempt that isn't completely logical.

 

 

List<List<String>> listofCountriesWithInfo;
List<Service_Area__c> ServiceAreas;

Private List<List<String>> getlistofCountriesWithInfo() {

ServiceAreas =[SELECT Country__c, Province_State__c, City__c FROM Service_Area__c];

for(String list :ServiceAreas){
list.add('Info.Country__c');
list.add('&nbsp','Info.Province_State__c');
list.add('&nbsp','&nbsp','Info.City__c');
}

return listofCountriesWithInfo ;

}

 

 

Shashikant SharmaShashikant Sharma

Hi neckr,

 

I have created an example for Showing Hierarchy In VFP on my Blog Force School.

 

Please check http://forceschool.blogspot.com/2011/06/show-hierarchy-in-visualforce-page.html

 

Replicate your case with the example that i used there, Please ask any question if any confusion

This was selected as the best answer
neckrneckr

This worked great for my use case! Thanks for sharing this on your blog!

3 expansion questions:

1) My case is Countries, States and Cities as Parent, Child, GrandChild Respectively. I would like to have Data Display by States Alphabetically and then City Alphabetically. How can I achieve this? I tried

 

mapHierarchy = new Map<Id , Service_Area__c>([Select Name , Parent_Hierarchy__c From Service_Area__c ORDER BY NAME ASC]); 

 

 
but it did not change anything.

2)  I need my data to be used as links, and the escape attribute is not supported in the <apex:commandLink value="{!item.itemValue}" />.  How would I use Apex:Variable and calculate space with help of it?

3) If I want to display the number of cities in 4 columns, do you have any thoughts on an easy solution to achieve this?  Lets say I displayed each country list in a separate pageblocksection and I distributed the list of cities over 4 columns. Any suggestions

Shashikant SharmaShashikant Sharma

1) My case is Countries, States and Cities as Parent, Child, GrandChild Respectively. I would like to have Data Display by States Alphabetically and then City Alphabetically. How can I achieve this? I tried

 

mapHierarchy = new Map<Id , Service_Area__c>([Select Name , Parent_Hierarchy__c From Service_Area__c ORDER BY NAME ASC]); 

 

 
but it did not change anything.

 

[Shashikant Sharma] : Use Sort method of list before you add States and Cities

 

2)  I need my data to be used as links, and the escape attribute is not supported in the <apex:commandLink value="{!item.itemValue}" />.  How would I use Apex:Variable and calculate space with help of it?

 

[Shashikant Sharma] : You can use a outputLabel before your command link like this 

<apex:outputLabel value="{!item.spaceForChildItem}" escape="false"></apex:outputLabel> 

Here spaceForChildItem is the &nbsp; from wrapper class.


3) If I want to display the number of cities in 4 columns, do you have any thoughts on an easy solution to achieve this?  Lets say I displayed each country list in a separate pageblocksection and I distributed the list of cities over 4 columns. Any suggestions

[Shashikant Sharma] : Will you always get 4 cities, my question is how will you get show if 5th city comes.

 

 

 

neckrneckr

1) Is this where you were suggesting to do the sort? I receive an error trying to use the function

 

 //Method to get child records  
        private List<hierarchyItem> getChildHierarchy(Id parentId , List<hierarchyItem> currentHierarchyItemList)  
        {  
            hierarchyIndex = hierarchyIndex + 1;  
            for(Service_Area__c h : mapHierarchy.values())  
                {  
                    if(h.Parent_Hierarchy__c == parentId)  
                        {  
                            //hierarchyItemList.Sort(); //List type does not allow //sorting: LIST<CusServiceAreaHierarchyController.hierarchyItem> 
                            hierarchyItemList.add(new hierarchyItem( h.Name , hierarchyIndex));  
                            mapHierarchy.remove(h.id);  
                            //Get child records of child  
                            hierarchyItemList = getChildHierarchy(h.id , hierarchyItemList);  
                        }  
                      
                }  
            hierarchyIndex = hierarchyIndex - 1;      
            return currentHierarchyItemList;      
        }  

 

 

2) I was thinking I could use the SpaceCount string value from your example like:

 

<apex:outputLabel value="{!item.spaceCount}" escape="false" />
                    <apex:commandLink value="{!item.itemValue}"/> 

 However its not connecting to Hieracrchy Item list once I take it away from itemValue.  Your example suggested to use SpaceFor ChildItem which is the &nbsp from wrapper class.  I am not sure if I am missing something but I do not see that variable in your example.  Can you please clarify for please.

 

 

 //Inner class for maintaing hierarchy items  
        public class hierarchyItem {  
              
            public String itemValue{get;set;}   
            public String hirarchyIndexNo{get;set;}  
            public String spaceCount{get;set;}  
            public hierarchyItem(String itemValue , Integer hirarchyIndexNo)
            
                {  
                    spaceCount = '';  
                    for(integer i = 0 ; i < hirarchyIndexNo ; i++)  
                        spaceCount = spaceCount  + '&nbsp;&nbsp;&nbsp;&nbsp;';  
                          
                    this.itemValue = itemValue;  //spaceCount + 
                }  
        }  

 

3) Not sure if this question was clear, I am looking for 4 columns not 4 cities.  Instead of having the list display over 1 column, I would like to display the same list over 4 columns.

 

 

 

 

neckrneckr

4) The idea of creating a list with its own data type is completely new to me.  Considering it is its own data type can I capture

other fields from the map into the list when its being built and use in VF page. (h.Service_Area_ID__c, h.Active__c, h.Header_Type__c)

 

mapHierarchy = new Map<Id , Service_Area__c>([Select Name , Parent_Hierarchy__c, Service_Area_ID__c, Active__c, Header_Type__c From Service_Area__c ORDER BY NAME ASC]); 

 

 

for(Service_Area__c h : mapHierarchy.values())  
                    {  
                        if(h.Parent_Hierarchy__c  == null)  
                        {  

                            hierarchyItemList.add(new hierarchyItem( h.Name , 0));  
                            mapHierarchy.remove(h.id);  
                            hierarchyItemList = getChildHierarchy(h.id , hierarchyItemList);  
                        }  
                          
                    }  

 

My thought was to keep the Map data and reference in VF page based on associated ItemValue, but even then the list only captures the name and not ID. 

 

 

Just so my objective is clear and I am may not be aware of all the tools to achieve my objective easily. Here is what I want to achieve.

 

I want to capture the following in my VF page:

 

Service_Area_ID__c  - this will be the parameter passed through my command link to enter next page

 

Active__c - Checkbox field  to  use in rendered attribute for logic display city or not

 

Header_Type__c  - I provided a value of 0 for Parent records , 1 for Child records and 2 for Grandchild records as I am thinking ahead to differentiate list items for Styles and formatting.

 

 

 

 

 

 

 

 

Shashikant SharmaShashikant Sharma

1) try to sort mapHierarchy.values() and use that sorted list 

2)Have you created a public property in wrapper class

     public String spaceCount{get;set;}  

3) i got your question but waht I want to know is whether for all provinces there will be four cities. If so then it cab be done with some change in controller. You have to use map of state as key and  list of cities as values.And use PageBlockTable in VFP.

Shashikant SharmaShashikant Sharma

4)In that case use this sort of wrapper

 

//Inner class for maintaing hierarchy items  
    public class hierarchyItem{  
          
        public yourObjectType itemValue{get;set;}   
        public String itemValue{get;set;}  
        public String hirarchyIndexNo{get;set;}  
        public hierarchyItem(String itemValue , Integer hirarchyIndexNo , yourObjectType yourObjectAPIName)  
            {  
                String spaceCount = '';  
                for(integer i = 0 ; i < hirarchyIndexNo ; i++)  
                    spaceCount = spaceCount  + '&nbsp;&nbsp;';  
                      
                this.itemValue = spaceCount + itemValue;  
            }  
    }  

 

 

pass record of yourObjectType Object, in your case Service Area Objects record.

neckrneckr

1)  Can't sort MapHierarchy.Values().Sort() // Error: List type does not allow sorting: LIST<Service_Area__c>

Any other suggestions?

 

2) I have created a public property in wrapper class, it seems as though the outputlabel has no effect on the commandlink position. I tried both within pageblocksectionitem and without

 

 

<!-- <apex:pageBlockSectionItem > -->
                  <apex:outputLabel value="{!item.spaceCount}"  escape="false" /> 
                    <apex:commandLink value="{!item.itemValue}"/> 
              <!--  </apex:pageBlockSectionItem> -->

 

 

//Inner class for maintaing hierarchy items  
        public class hierarchyItem {  
              
            public Service_Area__c itemData{get;set;}
            public String itemValue{get;set;}   
            public String hirarchyIndexNo{get;set;}  
            public String spaceCount{get;set;}  
            public hierarchyItem(String itemValue , Integer hirarchyIndexNo, Service_Area__c itemData)
            
                {  
                    spaceCount = '';  
                    for(integer i = 0 ; i < hirarchyIndexNo ; i++){  
                        spaceCount = spaceCount  + '&nbsp;&nbsp;';  
                          }
                          
                    this.itemValue = itemValue;  //spaceCount + 
                    this.itemData = itemData;
                    this.spaceCount = spaceCount;
                }  
        }  

 

 

 

 

3) No there will noy be 4 cities per province. The number of cities per province will be a variable from 1 to X. 

 

4) Your wrapper changes worked and I passed the Service_Area__c object fields and can access in my VFP. Thanks!

 

Shashikant SharmaShashikant Sharma

Yes I checked that also, and rightly so, Even when I used ASC and DESC in query where we fill map it does not effect. So you need to create a List fill it using soql and then fill the map.Try with this. I will try to provide you code later as I will get time.

neckrneckr

1) I tried creating a list and then adding list to map as follows, oddly, the ORDER BY still has no effect.

 

 

 listHierarchy = [Select Id, Name , Parent_Hierarchy__c, Service_Area_ID__c, Active__c, Header_Type__c From Service_Area__c ORDER BY Name ASC];
                                      
                for(Service_Area__c l : listHierarchy){
                
                mapHierarchy.put(l.id, l);
                
                }
                

 

Any insight on the other 3 expansion questions to your example?