1

I'm having a VF page which shows a table, together with 2 dropdowns and a checkbox which function as filters. Whenever a picklist value or the checkbox changes, the table should get rerendered having the data filtered according to the selection specified.

The used actionSupport properly calls the method and the values are sent correctly according to the request info in the network tab in the browser. The variables in the controller though are not set properly, and usually take the values of a previous selection.

I suspect a race condition somewhere but I have no clue how to solve it or how to approach this.

Visualforce:

<apex:selectList value="{!selectedPeriod}"  label="Period" size="1" required="true">
    <apex:selectOptions value="{!filterPeriods}"/>
    <apex:actionSupport event="onchange" action="{!doFilter}" reRender="outpanel"/>
</apex:selectList>

<apex:selectList value="{!selectedStatus}" label="Status" size="1" required="true" multiSelect="false">
    <apex:selectOptions value="{!filterStatuses}"></apex:selectOptions>
    <apex:actionSupport event="onchange" action="{!doFilter}" reRender="outpanel"/>
</apex:selectList>

<apex:inputCheckbox value="{!showChildless}" label="Show records without childs">
    <apex:actionSupport event="onchange" action="{!doFilter}" reRender="outpanel"/>
</apex:inputCheckbox>

<apex:outputPanel id="outpanel">
    <!-- TABLE WITH DATA FROM {!recordMap} -->
</apex:outputPanel>

Controller:

public String selectedPeriod {get;set;}
public String selectedStatus {get;set;}
public Boolean showChildless {get;set;}
public Map<String, List<MyRecord__c>> recordMap {get;set;}

public MyController() {
    selectedPeriod = '';
    selectedStatus = '';
    showChildless = true;
}

public void doFilter() {
    System.debug(selectedPeriod); // outputs old value
    System.debug(selectedStatus); // outputs old value
    System.debug(showChildless); // outputs always true

    // populate recordMap
}

public List<SelectOption> getFilterPeriods() {
    // return period SelectOpion[]
}

public List<SelectOption> getFilterStatusOptions() {
    // return status SelectOption[]
}

Any ideas? Thanks!

2 Answers 2

1

If I take your example and display the values from the selectLists, then I do see the correct values...

Visualforce:

<apex:page controller="Steven">
    <apex:form >
        <apex:selectList value="{!selectedPeriod}"  label="Period" size="1" required="true">
            <apex:selectOptions value="{!filterPeriods}"/>
            <apex:actionSupport event="onchange" action="{!doFilter}" reRender="outpanel"/>
        </apex:selectList>

        <apex:selectList value="{!selectedStatus}" label="Status" size="1" required="true" multiSelect="false">
            <apex:selectOptions value="{!filterStatuses}"></apex:selectOptions>
            <apex:actionSupport event="onchange" action="{!doFilter}" reRender="outpanel" />
        </apex:selectList>

        <apex:inputCheckbox value="{!showChildless}" label="Show records without childs">
            <apex:actionSupport event="onchange" action="{!doFilter}" reRender="outpanel"/>
        </apex:inputCheckbox>

        <apex:outputPanel id="outpanel">
            {!selectedPeriod}<br/>
            {!selectedStatus}<br/>
            {!showChildless}
        </apex:outputPanel>
    </apex:form>
</apex:page>

And controller:

public class Steven {

    public List<SelectOption> filterPeriods { get; set; }
    public String selectedPeriod {get;set;}
    public List<SelectOption> filterStatuses { get; set; }
    public String selectedStatus {get;set;}
    public Boolean showChildless {get;set;}
    public Map<String, List<Account>> recordMap {get;set;}

    public Steven () {
        filterPeriods = new List<SelectOption>{new SelectOption('A','A'),new SelectOption('B','B')};
        filterStatuses = new List<SelectOption>{new SelectOption('C','C'),new SelectOption('D','D')};
        selectedPeriod = '';
        selectedStatus = '';
        showChildless = true;
    }

    public PageReference doFilter() {
        System.debug(selectedPeriod); // outputs old value
        System.debug(selectedStatus); // outputs old value
        System.debug(showChildless); // outputs always true

        // populate recordMap
        return null;
    }
}

What do you see on your side? Same issue still?

1
  • If you add a SelectOption('', 'Any') to one of the List<SelectOption>, you will get the same weird behaviour. That empty String value seems to mess it up for the other inputs. My example code didn't include that part... Thanks anyway!
    – Steven.B
    Commented Jul 27, 2017 at 14:28
1

First, as the default Status I created a SelectOption with key = ''.

Second, I initialised both the Period and Status apex:selectList with an empty string like this, which for Period didn't exist in the list of SelectOption I retrieved from getFilterPeriods().

My guess is that this let the component behave this way. Once I properly initialised both apex:selectOptions with an existing value which is not an empty string, everything worked smoothly.

You must log in to answer this question.

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