+ Start a Discussion
ArpiArpi 

Pdf generation of a page

Hello,

 

I have a visualforce page below which displays part of the data but skips the response.

Belo is the code

 

<apex:page sidebar="false" standardStylesheets="true" Controller="QuestionnaireFieldsReport" renderAs="pdf">
<apex:panelGrid columns="1" id="theGrid" title="{!templateName}">
<apex:repeat value="{!Sections}" var="sec" >
<br/>
<!-- display section -->
<apex:panelGrid columns="2" title="{!sec.section.Section_label__c}">
<br/>
<apex:repeat value="{!sec.questions}" var="q" >
<!-- display questions -->
<apex:outputField value="{!q.Question_Label__c}" /> <br/>


<!-- display answer  BELOW TEXT IS NOT DISPLAYED-->
<apex:outputText value="{!sec.response[q.Id].Response__c}" rendered={!IF(NOT(ISNULL(sec.response[q.Id])),'true','false')}" /> 
</apex:repeat>

</apex:panelGrid>

</apex:page>

 

Thanks

 

Best Answer chosen by Admin (Salesforce Developers) 
ArpiArpi

Thanks all I got it to work, I chnaged my controller code and pushed everything there.

All Answers

joshbirkjoshbirk

PDF only renders the page as loaded in the initial DOM state.  To capture anything dynamic, you need to do the changes in VF, then you can flip the renderAs.

 

In theory, at least, you could:

 

<apex:page sidebar="false" standardStylesheets="true" Controller="QuestionnaireFieldsReport" renderAs="{!render}">

 

And then in your controller set a string of render to HTML initaily, and then flip to PDF.  However, the tricky part is still getting a fresh DOM with all they dynamic parts you need.  You can't just setRedirect to false or return null off the PageReference return.  So you have to design your controller in a way that is can see everything you need as if it was loading for the first time.  Maybe via query params, storing it as an attachment or Custom Object, etc.

MJ Kahn / OpFocusMJ Kahn / OpFocus

The rendered attribute in your outputText tag is returning string values of 'true' and 'false.' Try returning Boolean values instead.

ArpiArpi

Thanks for the response I tried changing the rendered atribute of outputText but stll its the same.

 

The outputtext field I wanted to be static but because I use two repeat which I couldnt at the same level so I had to put everything in MAP( which messes my order).Is there any other way so that I could change my Controller so that its not dynamic for and also it doesnt mess my order.Below is my controller

 

public with sharing class QuestionnaireFieldsReport{

public List<Question_Template__c> questionsLists { get; set; }
public List<Section_Template__c > sectionsLists{ get; set; }
public List<Main_questionaire__c> templateLists { get; set; }
public String templateName{get;set;}
public List<Questionnaire_Response__c> QuestionResponse{get;set;}
    
// Creates section List
public List<Sections> getSections()
    {
      
        templateLists = [Select Id, Name from Main_questionaire__c limit 1];
        if(templateLists!=NULL && templateLists.size()>=1)
         {
        templateName = templateLists.get(0).Name; 
        
        }
        List<Sections> sectionsList = new List<Sections>();
        Map<Id, Sections> mapSections = new Map<Id, Sections>();
        // Add Section Records
        for (Section_Template__c sec : [SELECT Id, Section_label__c,Order_No__c from Section_Template__c where Questionnaire_Section__c=:templateLists.get(0).Id order by Order_No__c])

{
//BECAUSE   I COULDNT FIND ANOTHER WAY SO I PUT IN MAP WHICH MESSES THE ORDER AS MAP DOEST PRESERVER ORDER        

mapSections.put(sec.Id, new Sections(sec));
        }
     
        // Add Question Records
        Map<Id, Sections> mapQuestions = new Map<Id, Sections>();
        for (Question_Template__c ques : [SELECT Id, Section_Question__r.id,Question_Label__c,Question_Order_No__c FROM Question_Template__c order by Question_Order_No__c])
        {
            
            // Add question records to section
            Sections section = mapSections.get(ques.Section_Question__r.id);
            section.questions.add(ques);

            // added all the question Ids to the map
            section.response.put(ques.Id, new Questionnaire_Response__c()); 

            mapSections.put(ques.Section_Question__r.id, section);
        }
   
        // Add Answer Records this PART IS NOT DISPLAYING FOR PDF
        Map<Id, Questionnaire_Response__c> mapAnswer = new Map<Id, Questionnaire_Response__c>();
     
        for (Questionnaire_Response__c ans : [SELECT Id,Name, Response__c,Account_to_Response__c,Question_Template__r.id,Question_Template__r.Section_Question__r.id FROM Questionnaire_Response__c ){
            Sections section = mapSections.get(ans.Question_Template__r.Section_Question__r.id);
            section.response.put(ans.Question_Template__r.id, ans);
            mapSections.put(ans.Question_Template__r.Section_Question__r.id, section);
            
        }
    
        // Add Question Records
       
        return mapSections.values();
}
    
    // Create an inner class
        public class Sections
        {
            public Section_Template__c   section {get; set;}
            public Question_Template__c[]  questions  {get; set;}
            public Map<Id, Questionnaire_Response__c>  response {get; set;}
            
            
            public Sections(Section_Template__c sec)
            {
                section = sec;
                questions = new Question_Template__c[]{};
                response = new Map<Id, Questionnaire_Response__c>();
            }
            
    }

 

Thanks a lot to both of you for helping ,I really appreciate it.

ArpiArpi
Also I wanted to mention I am clicking a button on another page which call this vf page with the controller
MJ Kahn / OpFocusMJ Kahn / OpFocus

First, I suspect this isn't a PDF issue. If you temporarily remove the renderAs="pdf" from the code and just render it as HTML, you'll probably see the same results.

 

Second, without knowing the schema in more detail, I can't really tell, but it looks like you're populating a Sections' response map using the Questionnaire_Response__c record's Question_Template__r.id value - is that the same ID as the ID of the Question in sec.Questions?

 

Third, the VF code you provided is missing the close of one of the apex:repeat tags. I suspect it should go right afterr the existing </apex:repeat> just before the end of the panelGrid - if not, that might be a problem.

 

Finally, if it's still a problem, I'd put in some debug statements. Inside the inner repeat block, display the values of q.id and sec.response[q.Id] and see what you can tell from that. 

ArpiArpi

Thanks again for helping.

 

1)Yes even if I render as pdf or word or html it doesnt give me the response data but if its a normal vf page everything displays fine properly(without any render or contentType attributes)

 

2)Sorry for not explaining the model, all of them are master detail.

Main_questionaire__c is parent of all than --> Section_Template__c --->Question_Template__c --->  Questionnaire_Response__c.

Now each section can have multiple questions and each question has 1 response.

 

3)Ya end of repeat is there ,I must have missed copying it here.

 

 

ArpiArpi

Thanks all I got it to work, I chnaged my controller code and pushed everything there.

This was selected as the best answer