1

Here's what my page looks like:

 <apex:actionRegion ><!-- wrapping the queue selection list in an action region allows us to rerender a different section via ajax -->


                <apex:selectList id="ProjectSelectList" value="{!selectedProject}" size="1">
                    <b>Project:</b>
                    &nbsp;&nbsp;<apex:selectOptions value="{!Projects}" />
                    &nbsp;&nbsp;<apex:actionStatus startText="(working...)" stopText="" id="getChartsStatus"/>
                </apex:selectList>

                <apex:selectList id="StatusSelectList" value="{!selectedStatus}" size="1">
                    <b>Chart Queue:</b>
                    &nbsp;&nbsp;<apex:selectOptions value="{!getStatuses}" />
                    &nbsp;&nbsp;<apex:actionStatus startText="(working...)" stopText="" id="getChartsStatus"/>
                    <apex:actionSupport event="onchange" action="{!searchCharts}" reRender="chartList" status="getChartsStatus" />
                </apex:selectList>

            </apex:actionRegion>

What I'm trying to do is cause an Ajax action and rerender anytime either of the above SelectList's are updated, but only if both of them have been set.

Right now I just get an immediate attempt at rerender the moment I change either one.

2
  • where is your chartList section?
    – highfive
    Commented Mar 14, 2014 at 5:49
  • 1
    Starting the Ajax action only when both fields have been set will require some javascript to be called when one of the selections is changed, which will check if both fields are filled and will call an apex:actionMethod to do the {!searchCharts} and the rerender. To prevent making the page unnecessarily complex, couldn't you just default the SelectLists to the first value in the list? Then you will never have unset values.. Commented Mar 14, 2014 at 12:45

1 Answer 1

3

I realize this question is old but I feel it at least deserves an answer or some solution. The best way to handle this using Visualforce IMHO is to use some form of JS code. I prefer jquery library as it saves time and is easier to work with but you can use pure-JS here pretty easily as well. First in your controller you would have something like the following:

public with sharing virtual class BothPicklistsChange {
    public String selectedProject { get; set; }
    public String selectedStatus { get; set; }
    public String chartSearchResult { get; set; }

    public BothPicklistsChange() {
        chartSearchResult = 'Content here to be re-rendered';
    }

    public void searchCharts() {
        // TODO perform search logic here
        chartSearchResult = 'Chart results ...';
    }

    public static List<SelectOption> getProjects() {
        List<SelectOption> options = new List<SelectOption>();

        options.add(new SelectOption('', '-None-'));
        options.add(new SelectOption('Project 1', 'Project 1'));
        options.add(new SelectOption('Project 2', 'Project 2'));
        options.add(new SelectOption('Project 3', 'Project 3'));

        return options;
    }

    public static List<SelectOption> getStatuses() {
        List<SelectOption> options = new List<SelectOption>();

        options.add(new SelectOption('', '-None-'));
        options.add(new SelectOption('Planning', 'Planning'));
        options.add(new SelectOption('Active', 'Active'));
        options.add(new SelectOption('On-hold', 'On-hold'));

        return options;
    }
}

Then in your VF page using your code I included the full visualforce page for contextual purposes and to show how the pieces fit together. Your example was missing the chartList element. I made a few key changes here.

  1. I created an action function called searchCharts
  2. I removed your apex:actionSupport element from the second picklist as it is no longer necessary
  3. I used jquery (can be done in pure javascript if you prefer though I don't recommend) to listen to changes to the picklists. As soon as both have a non-default value it will call the new apex:actionFunction I added to the VF markup triggering the re-render as per your requirement.

<apex:page controller="BothPicklistsChange">
    <!-- IT IS NOT REQUIRED TO USE JQUERY, YOU COULD USE PLAIN JAVASCRIPT -->
    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <apex:form>
        <apex:outputPanel id="chartList">
            {!chartSearchResult}
        </apex:outputPanel>

        <apex:actionRegion ><!-- wrapping the queue selection list in an action region allows us to rerender a different section via ajax -->

            <apex:selectList id="ProjectSelectList" value="{!selectedProject}" size="1">
                <b>Project:</b>
                &nbsp;&nbsp;<apex:selectOptions value="{!Projects}" />
                &nbsp;&nbsp;<apex:actionStatus startText="(working...)" stopText="" id="getChartsStatus"/>
            </apex:selectList>

            <apex:selectList id="StatusSelectList" value="{!selectedStatus}" size="1">
                <b>Chart Queue:</b>
                &nbsp;&nbsp;<apex:selectOptions value="{!Statuses}" />
                &nbsp;&nbsp;<apex:actionStatus startText="(working...)" stopText="" id="getChartsStatus2"/>
            </apex:selectList>

            <script>
                $(document).ready(function() {
                    // get reference to picklists
                    var $projectSelectList = $(document.getElementById("{!$Component.ProjectSelectList}")),
                        $statusSelectList = $(document.getElementById("{!$Component.StatusSelectList}"));

                    // on-change event-handler
                    function onPicklistChanged() {
                        // call searchCharts controller method ONLY if both picklists contain a non-whitespace value selected.
                        if($projectSelectList.val() != "" && $statusSelectList.val() != "") {
                            // trigger chart search and re-render charts!
                            searchCharts();
                        }
                    }

                    // hook up JS on-change events for each picklist
                    $projectSelectList.on("change", onPicklistChanged);
                    $statusSelectList.on("change" , onPicklistChanged);
                });    
            </script>
        </apex:actionRegion>

        <apex:actionFunction name="searchCharts" 
            action="{!searchCharts}" 
            reRender="chartList" 
            status="getChartsStatus, getChartsStatus2" />
     </apex:form>
</apex:page>

I hope this helps someone

You must log in to answer this question.

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