4

I'm pretty sure I'm missing something really simple here. I've done this a number of times, but even using my past examples I just can't seem to get this to work.

Scenario: I have a Page using a StandardController and Extension. This page has two Select List components. The Second SelectList (MajorCategory) has it's options set based on the value in the first SelectList (UserType).

When the User picks a value for UserType I want the MajorCategory to rerender and display values based on the selected value from UserType. I've done two methods to do this.

The first was an ActionFunction that has the value passed as a Param and renders the OutputPanel for MajorCategory.

The Second is an ActionSupport on the UserType that rerenders the Outputpanel for MajorCategory.

Neither Method seems to set the value of UserType and therefore my second picklist never gets updated with selectOptions. I added a system.debug in the SelectOptions method for MajorCategory and everytime it shows that UserType hasn't been set based on the value on the page.

<apex:page showheader="false" sidebar="false" standardStylesheets="false" standardController="Case" extensions="Case_ContactUs_Ext">
<style>
    .MyClass{font-weight:bold;}
</style>
<apex:form >
  <apex:actionFunction name="RefreshCategories" rerender="MajorCategory, CategoryPanel" >
      <apex:param name="firstParam" assignTo="{!UserType}" value="" />
  </apex:actionFunction>

    <apex:outputlabel value="User Type Prototype:" style="padding-right:5px;" />
    <apex:SelectList value="{!UserType}" required="true" size="1" onchange="RefreshCategories(this.value)">
            <apex:selectoptions value="{!UserTypes}" />  
       <!-- <apex:actionsupport event="onchange" rerender="MajorCategory, CategoryPanel" /> -->
    </apex:SelectList>
    <br/>  
    <apex:outputpanel id="CategoryPanel">
        ViewMe: {!ViewMe}<br/>
        <apex:outputlabel value="Major Category ProtoType:" style="padding-right:5px;" />
        <apex:SelectList value="{!MajorCategory}" required="true" size="1" id="MajorCategory">
            <apex:selectOptions value="{!Categories}" />
        </apex:SelectList>
    </apex:outputpanel>
</apex:form>

ViewME is a test Boolean that is set to confirm the outputpanel is rendered properly.

Here's the controller:

public class Case_ContactUs_Ext {

    private final Case c;
    private final ID vOwnerID;
    public string vContactFirstName{get;set;}
    public string vContactLastName {get;set;}
    public string vEmail {get;set;}
    public string vCity {get;set;}
    public string vState {get;set;}
    public string vComment {get;set;}
    public static boolean ErrorTest = false;

    /*Constructor Method
        */
    public Case_ContactUs_Ext(ApexPages.StandardController con) {        
        ViewMe = false; UserType ='IHaventChanged!';
        this.c = (Case)con.getRecord();
        list<Group> Queues = [SELECT DeveloperName,Email,Id,Name,OwnerId,RelatedId,Type
                              FROM Group WHERE Type = 'Queue' AND DeveloperName = 'CustomerSupportQueue'];
        if(Queues != null && Queues.size()>0 && ErrorTest == false){
            vOwnerID = Queues[0].id;            
        }else{
            list<User> lUser = [SELECT Id,Name,ProfileId,Profile.Name FROM User where Profile.Name = 'System Administrator'];
            vOwnerID = lUser[0].id;
        }
    }
    /*SetDefaults on Case based on Page Params
        */     
    public void SetCaseDefaults(){
        map<string,string> PageParams = ApexPages.currentPage().getParameters();
        c.Subject = c.Reason_L1__c;
        c.OwnerID = vOwnerID;
        string pwid = PageParams.get('PWID');
        string sponsor = PageParams.get('Sponsored');
        string vDesc = 'Contact First Name: ' + vContactFirstName + '\r\n Contact Last Name: ' +  vContactLastName +
            '\r\n Contact Email: ' + vEmail + '\r\n PWID: ' + pwid + '\r\n Sponsored: ' + Sponsor + '\r\n Comment: '  + vComment;
        C.Case_Web_Source__c = PageParams.get('Source');
        C.Origin = 'Web';
        c.Contact_City__c = vCity;
        c.Contact_State__c = vState;
        c.Description = vDesc;

    }
    public string UserType {get; set;}
    /*Usertype Picklist Values
        */
    public list<SelectOption> getUserTypes(){
        list<SelectOption> options = new list<SelectOption>();
        map<String, Custom_Picklist_Values__c> mValues = Custom_Picklist_values__c.getAll();
        options.add(new SelectOption('',''));
        integer i=0;
        for(Custom_Picklist_Values__c value : mvalues.values()){
           options.add(new SelectOption('Test'+i, value.Name)); i++;
        }
        return options;
    }

    public boolean ViewMe {get;set;}
    /*
        */
    public string MajorCategory {get;set;}
    public list<SelectOption> getCategories(){
        system.debug('Updating Categories with values for: ' + UserType);
        ViewMe = true;
        list<SelectOption> options = new list<SelectOption>();
        map<string, Custom_Picklist_Contraints__c> mvalues = Custom_Picklist_Contraints__c.getAll();
        for(Custom_Picklist_Contraints__c value : mvalues.values()){
            if(UserType != null && value.Master_Value__c == UserType){
                options.add(new SelectOption(value.Dependent_Value__c, value.Dependent_Value__c));
            }
        }
        return options;
    }    
//EOF    
}

Update 2/8/2013 Okay now I'm really confused. I removed all the other fields on the page. I still got the same behavior.

Then in my extension, I added this:

options.add(new SelectOption(UserType, UserType));

To the method that builds the MajorCategories selection options. When this is there, the picklist gets refreshed properly!

At first I thought it was because there was no values in the picklist at all when the page first renders. So I replaced the above option.add with just 'Test','test'. This time the picklist fails to render.

Update to the Update Okay... I'm not very weirded out. Without making a single change it suddenly started working.

2
  • Hey - wanted to thank you. Your code snippet helped me figure out how to pass a parameter from a select list, to the controller when using an Action Support. Thanks! (pass the param via an ActionFunction).
    – RC82
    Commented Oct 16, 2015 at 17:03
  • Last time I got the error without changing anything, and the next day the error gone without changing any code. It wasted me lots of my time. Now I got the problem without changing anything. Hoping that it will gone next Monday. The good news is I have multiple selections on the page, when I select value for some of them (no a single one), the controller got the value. I can continue on other part, and wait until next day.
    – user25563
    Commented Oct 16, 2015 at 18:18

3 Answers 3

2

No need to set the userType as a param on the action function....since the action function and the select list is within the same form section, userType will automatically get set. Also, you can set actionFunction's action="{!null}". It wants an action in there, but all we're really saying is "do the post and rerender the screen". Also note that field validation will occur before the sets...so if you had an input field set to required within the same form tags, your process would fail with no feedback (unless you had a pageMessages tag within the rerendered section)

1
  • I thought about the required issue. I had actually removed all the required statements in a test after I had posted - still didn't make a difference. Tried adding action="{!null}" to the actionfunction - still receive the same behavior. The rerender is happening (ViewMe changes to true) but the UserType still doesn't get set. Commented Feb 8, 2013 at 1:25
1

I dont see the action attribute on your apex:actionFunction?

1
0

Kevin made some good points. Also, I noticed that you have the value of the SelectOption as 'Test'+i. The first arg to the SelectOption constructor is the value and the second arg is the label. Double check that's what you have in the value.Master_Value__c values.

Also, make sure that you don't have immediate="true" on your actionFunction or actionSupport because that causes the setters not to be called.

Other than that, your code looks like it would work to me with either the actionFunction or actionSupport. You could try adding in an apex:actionRegion. That narrows what is processed by the server. Based on your current code posted, I don't see why it would make a difference, but I've seen it make a difference, particularly in Internet Explorer, when it shouldn't.

For example:

<apex:actionRegion>
    <apex:actionFunction name="RefreshCategories" rerender="MajorCategory, CategoryPanel" >
      <apex:param name="firstParam" assignTo="{!UserType}" value="" />
  </apex:actionFunction>

    <apex:outputlabel value="User Type Prototype:" style="padding-right:5px;" />
    <apex:SelectList value="{!UserType}" required="true" size="1" onchange="RefreshCategories(this.value)">
            <apex:selectoptions value="{!UserTypes}" />  
       <!-- <apex:actionsupport event="onchange" rerender="MajorCategory, CategoryPanel" /> -->
    </apex:SelectList>
</apex:actionRegion>
3
  • Peter, Thanks for the answer. The test+i was just temporary filler that in case the value was coming back as null (which it shouldn't be). I tried the Action Region suggestion and I did not get any behavior change. I'm not using the immediate attribute. Glad you said it looks like it would work. I've been scratching my head on this for hours Commented Feb 8, 2013 at 14:43
  • Sorry it didn't work...I created a gist: gist.github.com/peterknolle/4742979 with my own sort of reproduction of your code and it worked. It doesn't have the custom settings...just code. My other thought was to just double check to see if it works in other browsers. Commented Feb 8, 2013 at 23:58
  • The weird thing is I tried it later this afternoon - after no changes - and it worked. Don't get it! Commented Feb 9, 2013 at 3:36

You must log in to answer this question.

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