7

I have been trying to dig deeper apex:include tag and its behavior when multiple <apex:include>'s exist within a page and the pages in the include tag share the same controller. My observation has been that the variable values are preserved across the different apex: include tags that have pages sharing the same controller. I would like to understand this phenomenon from the first principles, say View State. Or is it just straightforward and I have missed something very trivial.

Let's take the following pages for us to have a discussion.


1. Consider two pages "generalQuestions" and "specificQuestions". Let us say that both of them share "generalQuestionsController".

 public with sharing class generalQuestionsController {
   public String question{get;set;}
    public String question2{get;set;}
    public String selectedAnswer{get;set;}
    public String selectedAnswer2{get;set;}
    public List<SelectOption> getGeneralQuestions(){
        List<String> answers = new List<String>{'Yes, we love them', 'No, we hate them', 'It is a love and hate situation'};
        List<SelectOption> options = new List<SelectOption>();
        if(options.isEmpty()){
         for(String s  : answers){
               options.add(new SelectOption(s,s));
         }
        }
        return options;
    }
    public generalQuestionsController() {
        question=  'Do you like our product?';
        question2= 'Do you like our campaigns?';
    }
    public void moveNext(){

    }
}
  1. The markup of the two pages is as follows:

GENERAL Questions page

<apex:page  title="GeneralQuestions" standardStylesheets="false" showHeader="false" sidebar="false" controller="generalQuestionsController">
<apex:outputText value="1 . {!question}"/>
<apex:form>
    {!selectedAnswer2}
   <apex:selectRadio value="{!selectedAnswer}" layout="pageDirection">
      <apex:selectOptions value="{!GeneralQuestions}"/>
      </apex:selectRadio>
     <apex:commandButton value="Next" action="{!moveNext}"/>
     </apex:form>
</apex:page>

Specific Questions Page:

<apex:page showHeader="false" sidebar="false" standardStylesheets="false" controller="generalQuestionsController">
   <apex:outputText value="2 . {!question2}"/>
       {!selectedAnswer}
 <apex:form>
    <apex:selectRadio value="{!selectedAnswer2}" layout="pageDirection">
             <apex:selectOptions value="{!GeneralQuestions}"/>
    </apex:selectRadio>
  <apex:commandButton value="Submit" action="{!moveNext}"/>
  </apex:form>
 </apex:page>
  1. Consider a third page called "FeedbackForm" which holds both these pages.

    <apex:page showHeader="false" sidebar="false">
        <h1 style="margin-bottom:20px;display:block;">This is our MAIN          PAGE</h1>
        <apex:include pageName="{!$Page.generalQuestions}" />
        <apex:include pageName="{!$Page.specificQuestions}"/>
    

  2. When you click Next button generated by include component of the generalQuestions, you observe that the specific questions page include component, reflects the value of the answer selected. How can one explain all this in terms of a GET Request/ VF Page execution?

I hope the question isn't trivial and helps us understand VF execution from a more basic standpoint.

Thanks

1 Answer 1

1

As far as I know:

  1. As a background: the view state is an encoded representation of a set of controller variables (to be more specific: all variables that are non-transient). So for a visualforce page it will contain all variables for all relevant controllers for that page. In your case, the viewstate will contain all the variables from the generalQuestionsController controller.
  2. If a page renders, the view state is created and sent along to the browser.
  3. If a page calls the server again, the viewstate is uploaded from the browser to the server (and not changed on the client!), and additionally the page will send a list of all the input values from checkboxes, inputs, etc etc. In your case, this latter list will contain {!selectedAnswer} and the newly set value that was assigned to it. Note: the viewstate will still have the original value of {!selectedAnswer} and not the new value. Indeed, the viewstate is just an encoded form of all variables at the time the page was generated.
  4. On the server, first the viewstate is decoded and the controllers and their state are restored (so yes, no server state is kept in-between requests, they are regenerated from the viewstate). In your case, because you have only one (shared) controller, this process will create one controller, and the variable state that existed when the page was initially rendered.
  5. Then, the list of input values is applied. Now, {!selectedAnswer} on the controller will become the selected value.
  6. Then, when the page is rendered again, the specific page will render out the value that is at that moment stored in {!selectedAnswer} here <apex:outputText value="2 . {!question2}"/>{!selectedAnswer} and so it will display the value selected in the general questions page.

Does that explain the question? Or did you possibly mean to display {!selectedAnswer2} instead of {!selectedAnswer} and the whole question is the result of a typo? :-)

1
  • Wow! This is good. You have been very detailed in your reasoning. I have question though. The fact that the controllers state is being shared is intriguing to me. That means, somewhere behind the scenes, the VF rendering engine has persisted the fact that I have already initialized the controller in one of the page includes, and I shouldn't be re-initializing it. I hope my question makes sense to you Mar 31, 2017 at 13:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .