Question:

Need selectList value setter to be set after reRender

Everett: 2 weeks ago

I have 3 selectLists. A, B, and C. B is dependent on A, and C is dependent on B.

When selectList A changes, I rerender select list B, and C.

<apex:selectList id='listAId' value="{!valueListA}">
    <apex:selectOptions value="{!OptionsForPicklistA}" />
    <apex:actionSupport event="onchange" reRender="rerenderListB,rerenderListC" status="fetchStatus" action="{!onchangeListAAction}"/>
</apex:selectList>

<apex:selectList id="listBId" value="{!valueListB}"> 
    <apex:selectOptions value="{!OptionsForPicklistB}" />
    <apex:actionSupport event="onchange" reRender="rerenderListC" status="fetchStatus" action="{!onchangeListBAction}"/>
</apex:selectList>

<apex:selectList id="listBId" value="{!valueListC}"> 
    <apex:selectOptions value="{!OptionsForPicklistC}" />
    <apex:actionSupport event="onchange" action="{!onchangeListCAction}"/>
</apex:selectList>

In the controller the select list options are generated for selectList B by looking at what selectList A is set to. This works great. The problem is selectList C. It is supposed to be set based on what selectList B is, but it is coming in wrong. Namely off by 1, getting set based on what selectList B was set to.

What I want to have happen is this.

  1. onchange to selectList A.
  2. set value A
  3. rerender selectList B based on A.
  4. set value B
  5. rerender selectList C based on B.

What I think is happening is this:

  1. onchange to selectList A.
  2. set value A.
  3. rerender selectList B.
  4. rerender selectList C based on B. <-- rerender happens before value is set.
  5. set value B.

How would I avoid this? I am sure I am making a rookie mistake, but for the life of my, can't find it. Have looked extensively, but I can't find an example of setting an Apex value directly from a Visualforce page, nor can I find an example of calling a rerender on a Visualforce component from an Apex page.

Simplified controller looks like this:

public String valueListA {get; set;}
public String valueListB {get; set;}
public String valueListC {get; set;}

public List<SelectOption> getOptionsForPicklistA() {
    List<SelectOption> bunchOfOptions = new List<SelectOption>();

    for (getListOfAOptionsFromSOQL) {
        availObjects.add(new SelectOption(name, value));
    }

    return bunchOfOptions;
}

public List<SelectOption> getOptionsForPicklistB() {
    List<SelectOption> bunchOfOptions = new List<SelectOption>();

    for (lookUpStuffBasedOn(valueListA)) {
        availObjects.add(new SelectOption(name, value));
    }

    return bunchOfOptions;
}

public List<SelectOption> getOptionsForPicklistC() {
    List<SelectOption> bunchOfOptions = new List<SelectOption>();

    for (lookUpStuffBasedOn(valueListB)) {
        availObjects.add(new SelectOption(name, value));
    }

    return bunchOfOptions;
}

Answer:
Aaron: 2 weeks ago

OK, one way out of this is to surround each apex:selectList with apex:actionRegion components. (That is, three different and non-overlapping actionRegions)

Upon the onChange action, only the apex components inside the enclosing actionRegion are transmitted to the server (hence, only one setter will be invoked - the one for the selectList being changed)

By way of education, it is well worth reading the Visualforce Development Guide section on 'Order of Execution' (http://www.salesforce.com/us/developer/docs/pages/index_Left.htm#StartTopic=Content/pages_controller_lifecycle_example.htm?SearchType=Stem). It is also worth examining the debug log when you initiate an action on the page - this can help associate the log events with the aforementioned documentation

Another excellent resource is VF in Practice (http://www.developerforce.com/guides/Visualforce_in_Practice.pdf) - chapter 1 on View State is fundamental knowledge.

And finally, this helped me (and continues to help me) - Visualforce Development Cookbook by noted SFSE expert Keir Bowden - aka Bob Buzzard. Chapter 3 'Breaking up forms with action regions', pg 88 is relevant to you but the book is chock-o-block with recipes on common VF issues.