sObject Describe Result for Visualforce Picklist

More than a while ago, I wrote about populating query results to a picklist for use in a Visualforce page. That post receives a lot of traffic and I get some additional emails regarding that topic. So I thought I would put together another post similar to that one but with a bit of a twist.

In the sample I will cover in this post I am going to show you how to use the methods for the Describe Result sObject in order to create picklists within Visualforce pages.

This could come in handy if you wanted to do something like provide criteria for searching Salesforce objects using a Visualforce page. So that you can make the best use of this code I am going to use the standard User object so that you can simply cut and paste the code from this sample into your Sandbox or Developer org.

The first thing we need to create for this sample is the Class that we will use in the Visualforce page, which we will build afterwards. Since we will be using this as an extension to our standard User sobject controller, I will be titling the class as "extension_user". The code is below:

/*
	Created by: Greg Hacic
	Last Update: 17 January 2011 by Greg Hacic
	Questions?: greg@interactiveties.com
	
	Notes:
		- uses the describe method in order to populate a visualforce picklist
*/
public with sharing class extension_user {
	private String first_picklist_option = '- All -'; //first value to display in picklist
	private final User user_object; //User sobject
	
	public extension_user(ApexPages.StandardController stdController) {
		this.user_object = (User)stdController.getRecord();
	}
	
	//builds a picklist of values based upon the passed information
	public List<selectOption> getPickValues(Sobject object_name, String field_name, String first_val) {
		List<selectOption> options = new List<selectOption>(); //new list for holding all of the picklist options
		if ( first_val != null ) { //if there is a first value being provided
			options.add(new selectOption(first_val, first_val)); //add the first option
		}
		Schema.sObjectType sobject_type = object_name.getSObjectType(); //grab the sobject that was passed
		Schema.DescribeSObjectResult sobject_describe = sobject_type.getDescribe(); //describe the sobject
		Map<String, Schema.SObjectField> field_map = sobject_describe.fields.getMap(); //get a map of fields for the passed sobject
		List<Schema.PicklistEntry> pick_list_values = field_map.get(field_name).getDescribe().getPickListValues(); //grab the list of picklist values for the passed field on the sobject
		for (Schema.PicklistEntry a : pick_list_values) { //for all values in the picklist list
			options.add(new selectOption(a.getLabel(), a.getValue())); 	//add the value and label to our final list
		}
		return options; //return the List
	}
	
	//return the picklist options for User.TimeZoneSidKey
	public List<selectOption> getTimeZones() {
		return getPickValues(user_object, 'TimeZoneSidKey', first_picklist_option);
	}
	
	//return the picklist options for User.LocaleSidKey
	public List<selectOption> getLocales() {
		return getPickValues(user_object, 'LocaleSidKey', first_picklist_option);
	}

}

The real meat of the code is the getPickValues method in the class above. This is the portion of the code that populates the list, which will be used as picklist options in the Visualforce page. Although I could have hard-coded the object and the field for which I want to grab values, I did not. This was done so that I could reuse the code in order to grab picklist values via the describe call for more than one object or more than one field. You can see the application of this concept with the getLocales, & getTimeZones portions of the logic.

Also, I wanted to illustrate how you could place a default value or something within your picklist. This was done above by passing the first_val string to the getPickValues method. If, in fact, I was going to use the picklists that I build in a Visualforce search page or something then I would want to provide my users with the option of selecting "All" vallues from the picklist. Although I didn't include the logic here you could check if the selection was for All downstream in order to facilitate a more usable Visualforce page.

Anyway, the next part of the code is the Visualforce page itself. That code is here:

<apex:page standardController="User" extensions="extension_user">
<!--
	Created by: Greg Hacic
	Last Update: 17 January 2011 by Greg Hacic
	Questions?: greg@interactiveties.com
	Copyright (c) 2011 Interactive Ties LLC
-->
	<apex:sectionHeader title="Visualforce Sample" subtitle="Describe for Picklist Values" help="/help/doc/user_ed.jsp?loc=help"></apex:sectionHeader>
	<apex:form >
		<apex:pageBlock title="Criteria" mode="edit">
			<apex:pageBlockSection title="Information" columns="1">
				<apex:pageBlockSectionItem>
					<apex:outputLabel value="Time Zones" for="time_zones"></apex:outputLabel>
					<apex:selectList id="time_zones" size="1" title="Time Zones">
						<apex:selectOptions value="{!TimeZones}"></apex:selectOptions>
					</apex:selectList>
				</apex:pageBlockSectionItem>
				<apex:pageBlockSectionItem>
					<apex:outputLabel value="Locales" for="locale"></apex:outputLabel>
					<apex:selectList id="locale" size="1" title="Locale">
						<apex:selectOptions value="{!Locales}"></apex:selectOptions>
					</apex:selectList>
				</apex:pageBlockSectionItem>
			</apex:pageBlockSection>
		</apex:pageBlock>
	</apex:form>
</apex:page>

The main piece of this code is the selectOptions tag, which we use twice. Visualforce knows to iterate over the list of values that were built in the extension class and drop them into the picklist field on the page. Since we provided a default value of - All - in the methods we used to build the picklists, we will see that as the first option in each of our lists on the Visualforce page. Please see the illustration below:

Visualforce Page for Describe Sobject Result picklist

If you copied and pasted the code in this sample into one of your orgs then you should see the page that I have illustrated above.

The last part and the most dreadful at least in the opinion of most new Apex developers, is the test class for the page and extension provided in this post. That test class is below:

/*
	Created by: Greg Hacic
	Last Update: 17 January 2011 by Greg Hacic
	Questions?: greg@interactiveties.com
	Copyright (c) 2011 Interactive Ties LLC
*/
@isTest
private class test_extension_user {
	
	@isTest //defines method for use during testing only
	static void test_logic() {
		User u = [SELECT Id FROM User LIMIT 1]; //grab a user
		
		//create a reference to the Visualforce page we just made
		PageReference sample_page = Page.describe_picklist_sample;
		Test.setCurrentPage(sample_page);
		
		ApexPages.currentPage().getParameters().put('id', u.Id); //populate the Visualforce page with the Id of the user from above
		
		//create an instance of the controller extension as if editing the user's details
		ApexPages.StandardController standard_controller = new ApexPages.standardController(u);
		extension_user extension_to_standard_controller = new extension_user(standard_controller);
		
		//call the method for populuating the Locale picklist
		List<selectOption> locale_picklist_options = extension_to_standard_controller.getLocales();
		System.AssertNotEquals(0, locale_picklist_options.size()); //assert that the size of our picklist is not 0
		
		//call the method for populuating the Locale picklist
		List<selectOption> time_zone_picklist_options = extension_to_standard_controller.getTimeZones();
		System.AssertNotEquals(0, time_zone_picklist_options.size()); //assert that the size of our picklist is not 0
	}
}

This test will provide 100% coverage for the code as it is provided in this sample. I know you will tweak it so the test class is really just a starting point.

Again, this is just another way to populate a picklist in a Visualforce page but this time using the methods for the Describe Result sObject.

Automated Exchange Rates in Salesforce.com

Reduce Repetitive Tasks, Eliminate Errors & Free Up Your Administrators.

Birthday Reminders for Salesforce.com

It might lead to a sale. Or it might make you feel good.