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
ArpiArpi 

Iterate without using repeat in visualforce

hello,

 

I have tables for sections,questions and response with master detail relationship between sction and question, question and response table. I want to display all of them with response under question and all questions under section.

 

Apex code 

public class QuestionnaireFieldsReport
{

public List<Question_Template__c> questionsLists { get; set; }
public List<Section_Template__c > sectionsLists{ get; set; }
public List<Questionnaire_Response__c> QuestionResponse{get;set;}
public List<QuestionDisplay> listQuestWithOptions;

 

//create a new inner class 
public class QuestionDisplay
{

public Question_Template__c newquestFormat{get;set;}
public List<Question_Template__c > qlistss {get;set;}
public List<Questionnaire_Response__c> rlistss{get;set;}
public Section_Template__c secObj{get;set;}



public QuestionDisplay(Section_Template__c sobj,List<Question_Template__c > ql,List<Questionnaire_Response__c> rl)
{
secObj= new Section_Template__c ();
qlistss =new List<Question_Template__c>();
rlistss= new List<Questionnaire_Response__c>();
this.secObj=sobj;
this.qlistss =ql;
this.rlistss=rl;
}
}//end inner class


public List<QuestionDisplay> getquestionsList()
{
Integer i=0;
listQuestWithOptions= new QuestionDisplay[]{};
accountId=System.currentPageReference().getParameters().get('accId');//to get the school or account id
//System.debug('!!!!!!!!!!!!!!!!~~~~~~~~~~~~~acct id from diff page :'+accountid);
sectionsLists = [Select Id, Name,status__c,Section_label__c,Order_No__c from Section_Template__c];
QuestionResponse=[Select id,Response__c,Question_Template__r.id,Question_Template__r.Question_Label__c,Account_to_Response__c,Questionnaire_Taker_user__c from Questionnaire_Response__c where Account_to_Response__c= :accountId] ;


for(integer w=0;w<sectionsLists.size();w++)
{
List<Question_Template__c > qlists= new List<Question_Template__c>();
List<Questionnaire_Response__c> rlists= new List<Questionnaire_Response__c>();
questionsLists = [SELECT Id,Section_Question__r.id,Question_Label__c,Question_Order_No__c FROM Question_Template__c where Section_Question__r.id=:sectionsLists[w].id order by Question_Order_No__c];

for(integer w1=0;w1<questionsLists.size();w1++)
{
Questionnaire_Response__c resp=new Questionnaire_Response__c();
if((QuestionResponse==null)||(QuestionResponse.size()==0))
{

rlists.add(resp);
qlists.add(questionsLists[w1]);
}
else
{
integer checkflag=0;
for(integer k=0;k<QuestionResponse.size();k++)
{
if(QuestionResponse[k].Question_Template__r.id==questionsLists[w1].id)
{
checkflag=1;resp=QuestionResponse[k];break;
}
}

rlists.add(resp);
qlists.add(questionsLists[w1]);
}

}

//r is reponse list and qlists is question list
listQuestWithOptions.add(new QuestionDisplay(sectionsLists[w],qlists,rlists) );

}


}

 

Visualforce code

I want the response and questions list to iterate alternatively

 

<apex:repeat value="{!questionsList}" var="section">
<apex:variable var="rlists" value="{!section.rlistss}"/>
<apex:pageBlockSection id="subsection" columns="1" title="{!section.secObj.Section_label__c}">
<apex:repeat value="{!section.qlistss}" var="qlist">
<apex:outputField value="{!qlist.Question_Label__c}" />
<apex:outputField value="{!rlists.Response__c}" /> <!-- this fails as i do not know how to iterate both together-->
<br> </br>

</apex:repeat>

 

 

Thanks

Best Answer chosen by Admin (Salesforce Developers) 
Thiyagarajan SelvarajThiyagarajan Selvaraj

Apex code:

 

public with sharing class QuestionsList {
    
    
    
    // Creates section List
    public List<Sections> getSections(){
        Map<Id, Sections> mapSections = new Map<Id, Sections>();
        
        // Add Section Records
        for (Section__c sec : [SELECT Id, Name FROM Section__c]){
            mapSections.put(sec.Id, new Sections(sec));
        }
        
        // Add Question Records
        for (Question__c ques : [SELECT Id, Name, Section__c FROM Question__c]){
            // Add question records to section
            Sections section = mapSections.get(ques.Section__c);
            section.questions.add(ques);

        

           // Here i added all the question Ids in to the map
            section.response.put(ques.Id, new Answer__c());  


            mapSections.put(ques.Section__c, section);
        }
        
        
        // Add Answer Records
        Map<Id, Answer__c> mapAnswer = new Map<Id, Answer__c>();
        for (Answer__c ans : [SELECT Id,Name, Question__c, Question__r.Section__c FROM Answer__c]){
            Sections section = mapSections.get(ans.Question__r.Section__c);
            section.response.put(ans.Question__c, ans);
            mapSections.put(ans.Question__r.Section__c, section);
            
        }
        
        
        return mapSections.values();
    }
    
    // Create an inner class
    public class Sections{
        public Section__c                     section         {get; set;}
        public Question__c[]                 questions        {get; set;}
        public Map<Id, Answer__c>            response        {get; set;}
        
        
        public     Sections(Section__c sec){
            section = sec;
            questions = new Question__c[]{};
            response = new Map<Id, Answer__c>();
        }
        
    }

}

 

 

Visualforce

 

<apex:page Controller="QuestionsList" >
        <apex:pageBlock title="Questions List" >
            <apex:repeat value="{!Sections}" var="sec" >
                <!-- display section  -->
                <apex:outputText value="{!sec.section.Name}" />
                <apex:repeat value="{!sec.questions}" var="q" >
                    <!-- display questions  -->
                    <apex:outputText value="{!q.Name}" />
                    <!-- display answer -->
                    <apex:outputText value="{!sec.response[q.Id].Name}"

                               rendered="{!IF(NOT(ISNULL(sec.response[q.Id])),'true','false')}" />                                                                           
                </apex:repeat>
            </apex:repeat>
        </apex:pageBlock>
</apex:page>

 

 

Hope, this will work for you.

All Answers

Thiyagarajan SelvarajThiyagarajan Selvaraj

Hi,

 

Assume, I created 3 objects. Section, Question, Respone. Question has a master detail relationship with Section and Answer has master detail relationship with Quesiton. If you want to get the reponse for the particular question without using repeat,

 

Apex

 

public with sharing class QuestionsList {
    
    // Creates section List
    public List<Sections> getSections(){
        Map<Id, Sections> mapSections = new Map<Id, Sections>();
        
        // Add Section Records
        for (Section__c sec : [SELECT Id, Name FROM Section__c]){
            mapSections.put(sec.Id, new Sections(sec));
        }
        
        // Add Question Records
        Map<Id, Sections> mapQuestions = new Map<Id, Sections>();
        for (Question__c ques : [SELECT Id, Name, Section__c FROM Question__c]){
            
            // Add question records to section
            Sections section = mapSections.get(ques.Section__c);
            section.questions.add(ques);
            mapSections.put(ques.Section__c, section);
        }
        
        
        // Add Answer Records
        Map<Id, Answer__c> mapAnswer = new Map<Id, Answer__c>();
        for (Answer__c ans : [SELECT Id,Name, Question__c, Question__r.Section__c FROM Answer__c]){
            Sections section = mapSections.get(ans.Question__r.Section__c);
            section.response.put(ans.Question__c, ans);
            mapSections.put(ans.Question__r.Section__c, section);
            
        }
        
        
        return mapSections.values();
    }
    
    // Create an inner class
    public class Sections{
        public Section__c                     section         {get; set;}
        public Question__c[]                 questions        {get; set;}
        public Map<Id, Answer__c>            response        {get; set;}
        
        
        public     Sections(Section__c sec){
            section = sec;
            questions = new Question__c[]{};
            response = new Map<Id, Answer__c>();
        }
        
    }

}

 

 

Visualforce

 

<apex:page Controller="QuestionsList" >
        <apex:pageBlock title="Questions List" >
            <apex:repeat value="{!Sections}" var="sec" >
                <!-- display section  -->
                <apex:outputText value="{!sec.section.Name}" />
                <apex:repeat value="{!sec.questions}" var="q" >
                    <!-- display questions  -->
                    <apex:outputText value="{!q.Name}" />
                    <!-- display answer -->
                    <apex:outputText value="{!sec.response[q.Id].Name}" />
                </apex:repeat>
            </apex:repeat>
        </apex:pageBlock>
</apex:page>

 

 

 

ArpiArpi

Thanks a ton for writing the code and explaining it clearly.

 

I have 1 issue though, some of my response may be null that means no response record for a particular question.

That is why it may be giving me the error as

 

"Map key a02d0000006afMBAAY not found in map".

 

Is there a way we can check that so the response is output as blank if there is no record for it.

 

Thanks again

Arpi

 

 

Thiyagarajan SelvarajThiyagarajan Selvaraj

Apex code:

 

public with sharing class QuestionsList {
    
    
    
    // Creates section List
    public List<Sections> getSections(){
        Map<Id, Sections> mapSections = new Map<Id, Sections>();
        
        // Add Section Records
        for (Section__c sec : [SELECT Id, Name FROM Section__c]){
            mapSections.put(sec.Id, new Sections(sec));
        }
        
        // Add Question Records
        for (Question__c ques : [SELECT Id, Name, Section__c FROM Question__c]){
            // Add question records to section
            Sections section = mapSections.get(ques.Section__c);
            section.questions.add(ques);

        

           // Here i added all the question Ids in to the map
            section.response.put(ques.Id, new Answer__c());  


            mapSections.put(ques.Section__c, section);
        }
        
        
        // Add Answer Records
        Map<Id, Answer__c> mapAnswer = new Map<Id, Answer__c>();
        for (Answer__c ans : [SELECT Id,Name, Question__c, Question__r.Section__c FROM Answer__c]){
            Sections section = mapSections.get(ans.Question__r.Section__c);
            section.response.put(ans.Question__c, ans);
            mapSections.put(ans.Question__r.Section__c, section);
            
        }
        
        
        return mapSections.values();
    }
    
    // Create an inner class
    public class Sections{
        public Section__c                     section         {get; set;}
        public Question__c[]                 questions        {get; set;}
        public Map<Id, Answer__c>            response        {get; set;}
        
        
        public     Sections(Section__c sec){
            section = sec;
            questions = new Question__c[]{};
            response = new Map<Id, Answer__c>();
        }
        
    }

}

 

 

Visualforce

 

<apex:page Controller="QuestionsList" >
        <apex:pageBlock title="Questions List" >
            <apex:repeat value="{!Sections}" var="sec" >
                <!-- display section  -->
                <apex:outputText value="{!sec.section.Name}" />
                <apex:repeat value="{!sec.questions}" var="q" >
                    <!-- display questions  -->
                    <apex:outputText value="{!q.Name}" />
                    <!-- display answer -->
                    <apex:outputText value="{!sec.response[q.Id].Name}"

                               rendered="{!IF(NOT(ISNULL(sec.response[q.Id])),'true','false')}" />                                                                           
                </apex:repeat>
            </apex:repeat>
        </apex:pageBlock>
</apex:page>

 

 

Hope, this will work for you.

This was selected as the best answer
newbiembanewbiemba

great soultion ,can anyone tell how to maintain the order of section and questions.The map is unordered so please guide.

 

 

Thanks

mba