function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SabinaSabina 

selectList value doesn't change / returns null

Hello,

I am trying to create dependent select lists: when the first one is changed, the second one updates its options and so on.
But for the life of me I cannot figure out how to get the value of the first select list to not return null.

My VF page:
<apex:page controller="TryCtrl">
    <apex:form>
        <apex:pageBlock title="Filters">
            <apex:pageMessages />
            <apex:pageBlockSection>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Product Family" />
                    <apex:actionRegion>
                        <apex:selectList value="{!family}" size="1" id="ffamily">
                            <apex:selectOptions value="{!familyList}" />
                            <apex:actionSupport event="onchange" rerender="fproduct" />
                        </apex:selectList>
                    </apex:actionRegion>
                </apex:pageBlockSectionItem> 
                
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Product"/>
                    <apex:actionRegion >
                        <apex:selectList value="{!product}" id="fproduct" size="1" >
                            <apex:selectOptions value="{!productList}"/>
                        </apex:selectList>
                    </apex:actionRegion>
                </apex:pageBlockSectionItem> 
                    
            </apex:pageBlockSection>
		</apex:pageBlock>
    </apex:form>
</apex:page>

My controller:
public class TryCtrl {
	private final Id accId = '001g000000cnDTb';
    private List<Custom__c> objects;
    public String family {get;set;}
    public String product {get;set;}
    
    public TryCtrl() {
        this.objects = [select ...];
    }
    
    public Set<SelectOption> getFamilyList() {
        Set<SelectOption> options = new Set<SelectOption>{new SelectOption('', '--All--')};
        for(Custom__c o : this.objects) {
            options.add(new SelectOption(o.Product_Family__c, o.Product_Family__c));
        }
        return options;
    }
    
    public Set<SelectOption> getProductList() {
        Set<SelectOption> options = new Set<SelectOption>{new SelectOption('', '--All--')};
        for(Custom__c o : this.objects) {
            if(String.isBlank(family) || o.Product_Name__c == family)
            	options.add(new SelectOption(o.Product_Name__c, o.Product_Name__c));
        }
        return options;
    }
}

When the page loads, the two are populated correctly. Changing the first select list is rerending the second one, but the 'family' variable is still set to null, so the products list is the same as before. I tried removing actionRegion, but didn't help. Can anyone please help? Thanks.
Best Answer chosen by Sabina
Sumit Kumar Singh 9Sumit Kumar Singh 9
Hello Sabina,
Pls, add one more line to the visualforce page-
<apex:page controller="TryCtrl">
<apex:pageMessages></apex:pageMessages>
<apex:form>
...
.
</apex:page>
It will list any standard error.
I suspect, "Set" is the culprit, you should use List instead -
List<SelectOption> options = new List<SelectOption>{new SelectOption('', '--All--')};
Thanks,
Sumit Kumar Singh
 

All Answers

Sumit Kumar Singh 9Sumit Kumar Singh 9
Hello Sabina,
Pls, add one more line to the visualforce page-
<apex:page controller="TryCtrl">
<apex:pageMessages></apex:pageMessages>
<apex:form>
...
.
</apex:page>
It will list any standard error.
I suspect, "Set" is the culprit, you should use List instead -
List<SelectOption> options = new List<SelectOption>{new SelectOption('', '--All--')};
Thanks,
Sumit Kumar Singh
 
This was selected as the best answer
mritzimritzi
Try following code and let me know how it works

Apex:
public class TryCtrl {
	private final Id accId = '001g000000cnDTb';
    private List<Custom__c> objects;
    public String family {get;set;}
    public String product {get;set;}
    
    public TryCtrl() {
        this.objects = [select ...];
    }
    
    public Set<SelectOption> getFamilyList() {
        Set<SelectOption> options = new Set<SelectOption>{new SelectOption('', '--All--')};
        for(Custom__c o : this.objects) {
            options.add(new SelectOption(o.Product_Family__c, o.Product_Family__c));
        }
        return options;
    }
    public void emptyFn(){
		//empty method to allow Apex to get values from VF
	}
	
    public Set<SelectOption> getProductList() {
        Set<SelectOption> options = new Set<SelectOption>{new SelectOption('', '--All--')};
        for(Custom__c o : this.objects) {
            if(String.isBlank(family))
            	options.add(new SelectOption(o.Product_Name__c, o.Product_Name__c));
			// I assume that you want to filter records based on selected value of first pickList
			else if(o.Product_Name__c == family)
				options.add(new SelectOption(o.Product_Name__c, o.Product_Name__c));
        }
        return options;
    }
}

VF:
<apex:page controller="TryCtrl">
    <apex:form>
        <apex:pageBlock title="Filters">
            <apex:pageMessages />
            <apex:pageBlockSection>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Product Family" />
                    <apex:actionRegion>
                        <apex:selectList value="{!family}" size="1" multiselect="false" id="ffamily">
                            <apex:selectOptions value="{!familyList}" />
							// added action attribute below
                            <apex:actionSupport event="onchange" action="{!emptyFn}" rerender="fproduct" />
                        </apex:selectList>
                    </apex:actionRegion>
                </apex:pageBlockSectionItem> 
                
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Product"/>
                    <apex:actionRegion >
                        <apex:selectList value="{!product}" id="fproduct" size="1" multiselect="false">
                            <apex:selectOptions value="{!productList}"/>
                        </apex:selectList>
                    </apex:actionRegion>
                </apex:pageBlockSectionItem> 
                    
            </apex:pageBlockSection>
		</apex:pageBlock>
    </apex:form>
</apex:page>

 
Amit Chaudhary 8Amit Chaudhary 8
Hi Sabina,

Please check below post . I hope that will help you
1) https://www.minddigital.com/how-to-create-dynamic-dependent-picklist-of-objects-within-salesforce/
2) http://www.infallibletechie.com/2012/10/dependent-picklist-using-apex-in.html
3) http://blog.deadlypenguin.com/blog/2012/07/09/dynamic-dependent-picklists-in-salesforce/

I Updated your code and tested in my org which is working fine. Only one minor change  you need to do just update your list from Set to List.

Code which i tested in my org
<apex:page controller="DynamicPicklistController">
    <apex:form >
        <apex:pageBlock title="Filters">
            <apex:pageMessages />
            <apex:pageBlockSection >
            
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Product Family" />
                    <apex:actionRegion >
                        <apex:selectList value="{!family}" size="1" id="ffamily">
                            <apex:selectOptions value="{!familyList}" />
                            <apex:actionSupport event="onchange" reRender="fproduct" />
                        </apex:selectList>
                    </apex:actionRegion>
                </apex:pageBlockSectionItem> 
                
                <apex:pageBlockSectionItem id="ListProd">
                    <apex:outputLabel value="Product"/>
                    <apex:actionRegion >
                        <apex:selectList value="{!product}" id="fproduct" size="1" >
                            <apex:selectOptions value="{!productList}"/>
                        </apex:selectList>
                    </apex:actionRegion>
                </apex:pageBlockSectionItem> 
                    
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>
public with sharing class DynamicPicklistController {

    public String family {get;set;}
    public String product {get;set;}
    
    public DynamicPicklistController() 
    {
    }
    
    public List<SelectOption> getFamilyList() 
    {
        List<SelectOption> options = new List<SelectOption>{new SelectOption('', '--All--')};
        options.add(new SelectOption('A', 'A'));
        options.add(new SelectOption('B', 'B'));
        options.add(new SelectOption('C', 'C'));

        return options;
    }
    
    public List<SelectOption> getProductList() 
    {
        List<SelectOption> options = new List<SelectOption>{new SelectOption('', '--All--') };
        if(String.isBlank(family) || 'A' == family)
        {
                options.add(new SelectOption('AA', 'AA'));
        }
        else
        {
                options.add(new SelectOption('BB', 'BB'));
        }
        return options;
    }

}

In your case please try to update your class like below

public class TryCtrl {
    private final Id accId = '001g000000cnDTb';
    private List<Custom__c> objects;
    public String family {get;set;}
    public String product {get;set;}
    
    public TryCtrl() {
        this.objects = [select ...];
    }
    
    public List<SelectOption> getFamilyList() {
        List<SelectOption> options = new List<SelectOption>{new SelectOption('', '--All--')};
        for(Custom__c o : this.objects) {
            options.add(new SelectOption(o.Product_Family__c, o.Product_Family__c));
        }
        return options;
    }
    
    public List<SelectOption> getProductList() {
        List<SelectOption> options = new List<SelectOption>{new SelectOption('', '--All--')};
        for(Custom__c o : this.objects) {
            if(String.isBlank(family) || o.Product_Name__c == family)
                options.add(new SelectOption(o.Product_Name__c, o.Product_Name__c));
        }
        return options;
    }
}


Please let us know if this will help you
SabinaSabina
Returning a Set of options was indeed what caused the problem. Thanks for pointing that out. I chose Sumit's answer as it was the first.