When building a custom Visualforce page, the need may arise to include a combo-box input based on a picklist field inside a Salesforce object. This is easy to achieve using an apex:inputField, as in the following example, where an Invoice Statement object contains a picklist field called Status.
VisualForce Page:
<apex:page controller="NoNoneForPicklistController"> Please select required status: <apex:form > <apex:inputField value="{!invoiceStatement.Status__c}"/> </apex:form> </apex:page>
public class NoNoneForPicklistController{ public Invoice_Statement__c invoiceStatement {get;set;} }
Screen-shot:
As you can see, the default value on the combo-box on the page is "-None-", which represents an empty value. It may be a preference to not display the empty value, but rather frustratingly, no configuration of the picklist object field can avoid this inclusion. There is no way to mark a picklist field as "required", and setting an option as default makes no difference either. That said, there are already ways to prevent an empty value being processed, using validation and feedback, but I have always been one to believe that prevention is better than cure.
Thankfully, there is a way to effectively create a picklist on a Visualforce list with no empty value. This can be achieved by using the Schema.DescribeFieldResult Salesforce standard class to retrieve all the possible field label value pairs for a picklist field. The retrieved value pairs are then stored inside a collection of select option objects, which can be used as the basis of a select list. Below is a snapshot of the code from the apex controller, and also the Visualforce page. As an added bonus, the default value specified in the picklist field object configuration can be used to set the initially selected value of the select list.
VisualForce Page:
<apex:page controller="NoNoneForPicklistController"> Please select required status: <apex:form > <apex:selectList size="1" value="{!invoiceStatement.Status__c}"> <apex:selectOptions value="{!statusOptions}"/> </apex:selectList> </apex:form> </apex:page>
public class NoNoneForPicklistController{ public Invoice_Statement__c invoiceStatement {get;set;} public List<SelectOption> statusOptions {get;set;} // Constructor called when page is accessed. public NoNoneForPicklistController() { invoiceStatement = new Invoice_Statement__c(); statusOptions = new List<SelectOption>(); // Use DescribeFieldResult object to retrieve status field. Schema.DescribeFieldResult statusFieldDescription = Invoice_Statement__c.Status__c.getDescribe(); // For each picklist value, create a new select option for (Schema.Picklistentry picklistEntry: statusFieldDescription.getPicklistValues()){ statusOptions.add(new SelectOption( pickListEntry.getValue(),pickListEntry.getLabel())); // obtain and assign default value if (picklistEntry.defaultValue){ invoiceStatement.Status__c = pickListEntry.getValue(); } } } }
Screen-shot:
Thanks, excellent post. Saved me hours of head-scratching!
ReplyDeleteJohn O'
آصف آریا خاطره
DeleteGood one!....Cheers mate!
ReplyDeletePlease tell me How to get which value is selected by user in picklist in visual force
ReplyDeleteAnnu -
ReplyDeleteThe value the user selects is assigned to the variable in the 'value' attribute of the select list definition.
In the above example, the value the user selects will be placed in the status field of the invoice statement object defined in the controller. You can access this in the controller by using invoiceStatement.Status__c
Christopher -- thanks for putting this together, just wanted to say I just used it and it works great.
ReplyDeleteRay
http://raydehler.com/cloud/
No problem Ray, glad to help!
ReplyDeletehi
ReplyDeletei tried the same as follows but i am getting the following error could u plz help me
Please select required status:
Invalid identifier: MyContact__c it is the error
Hello Suree,
DeleteThe error suggests that you may not be populating the select options incorrectly. Without seeing your code it is hard to know. If you post your code here or email it to me I can give you some pointers!
MyContact__c is the custom object and the Security_Question is the Picklist field on the MyContact__c object then how can i populate it from the object on to the visual force pages
DeletePlease select required status:
Suree,
DeleteThis is how your code should look if you are using a custom object called MyContact and a field called Security Question
VisualForce Page:
<apex:page controller="NoNoneForPicklistController">
Please select required security question:
<apex:form >
<apex:selectList size="1" value="{!myContact.Security_Question__c}">
<apex:selectOptions value="{!securityOptions}"/>
</apex:selectList>
</apex:form>
</apex:page>
Controller:
public class NoNoneForPicklistController{
public MyContact__c myContact {get;set;}
public List<SelectOption> securityOptions {get;set;}
// Constructor called when page is accessed.
public NoNoneForPicklistController() {
myContact = new MyContact__c();
securityOptions = new List<SelectOption>();
// Use DescribeFieldResult object to retrieve status field.
Schema.DescribeFieldResult securityFieldDescription = MyContact__c.Security_Question__c.getDescribe();
// For each picklist value, create a new select option
for (Schema.Picklistentry picklistEntry: securityFieldDescription.getPicklistValues()){
securityOptions.add(new SelectOption( pickListEntry.getValue(),pickListEntry.getLabel()));
// obtain and assign default value
if (picklistEntry.defaultValue){
myContact.Security_Question__c = pickListEntry.getValue();
}
}
}
}
hope that helps,
Chris
i wrote the above code but it is giving the following error
DeleteError: Unknown property 'String.Security_Question__c'
Suree, my suggestion would be to first check that you have defined "myContact" as an object of type My_Contact__c in your controller. The above message seems to suggest you have defined it as a string.
DeleteHi
ReplyDeleteSuppose if there are two fields namely RequestedBy and Status in an Invoice Statement object.
Picklist values of RequestedBy field are
John
Bob
Ram
Picklist values of Status field are
Open
Closed
In Progress
Cancelled.
Can you please help me in getting these picklist values for the two fields in Visual force page. I tried but in one field only all the picklist values are showing(in one filed it is showing other field picklist values also).
Regards,
Jagadeesh
Hi Jagadeesh,
DeleteThe following code should satisfy your requirements:
*Page Code*
<apex:page controller="NoNoneForPicklistController">
<apex:form >
Please select required status:
<apex:selectList size="1" value="{!invoiceStatement.Status__c}">
<apex:selectOptions value="{!statusOptions}"/>
</apex:selectList>
<br/><br/>
Who was this invoice requested by?:
<apex:selectList size="1" value="{!invoiceStatement.Requested_By__c}">
<apex:selectOptions value="{!requestedByOptions}"/>
</apex:selectList>
</apex:form>
</apex:page>
*Controller Code*
public class NoNoneForPicklistController{
public Invoice_Statement__c invoiceStatement {get;set;}
public List<SelectOption> statusOptions {get;set;}
public List<SelectOption> requestedByOptions {get;set;}
public NoNoneForPicklistController() {
invoiceStatement = new Invoice_Statement__c();
statusOptions = new List<SelectOption>();
requestedByOptions = new List<SelectOption>();
Schema.DescribeFieldResult statusFieldDescription = Invoice_Statement__c.Status__c.getDescribe();
for (Schema.Picklistentry picklistEntry: statusFieldDescription.getPicklistValues()){
statusOptions.add(new SelectOption(pickListEntry.getValue(),pickListEntry.getLabel()));
if (picklistEntry.defaultValue){
invoiceStatement.Status__c = pickListEntry.getValue();
}
}
Schema.DescribeFieldResult requestedByFieldDescription = Invoice_Statement__c.Requested_By__c.getDescribe();
for (Schema.Picklistentry picklistEntry: requestedByFieldDescription.getPicklistValues()){
requestedByOptions.add(new SelectOption(pickListEntry.getValue(),pickListEntry.getLabel()));
if (picklistEntry.defaultValue){
invoiceStatement.Requested_By__c = pickListEntry.getValue();
}
}
}
}
I hope that helps. If you have any problems let me know.
Cheers,
Chris.
P.S. Thanks for the questions, you have given me a great idea for my next post :D
Hi
ReplyDeleteany body knows this scenario.when deptname has been selected in
dropdown list ,then respective employees must be displayed in List.How can do this?
This may work
Deleteonce you select a department from picklist, create another picklist with the list of employees and make it dependent to the department picklist
Hi KSR. I have created an example of what you are describing based on the Invoice Statement model in the post above. In the example, when a user selects a status value from a picklist, the invoice statements that have the selected status value are displayed in a table below.
DeleteThe code uses an action support Visualforce tag to automatically reload the list with the relevant objects when the picklist value is changed.
Copy the following code, substituting your object/field names in, and let me know how you get on.
Visualforce Page:
<apex:page controller="NoNoneForPicklistController">
<apex:form >
<apex:pageblock >
<apex:pageBlockButtons location="top">
Please select required status:
<apex:selectList size="1" value="{!selectedStatus}">
<apex:selectOptions value="{!statusOptions}"/>
<apex:actionSupport event="onchange" action="{!loadInvoiceStatements}"/>
</apex:selectList>
</apex:pageBlockButtons>
<apex:pageBlockTable value="{!invoiceStatements}" var="inv">
<apex:column value="{!inv.Name}"/>
<apex:column value="{!inv.Invoice_Value__c}"/>
<apex:column value="{!inv.Description__c}"/>
<apex:column value="{!inv.Status__c}"/>
</apex:pageBlockTable>
</apex:pageblock>
</apex:form>
Controller Code:
public class NoNoneForPicklistController
{
public String selectedStatus {get;set;}
public List<SelectOption> statusOptions {get;set;}
public List<Invoice_Statement__c> invoiceStatements {get;set;}
public NoNoneForPicklistController()
{
statusOptions = new List<SelectOption>();
Schema.DescribeFieldResult statusFieldDescription = Invoice_Statement__c.Status__c.getDescribe();
for (Schema.Picklistentry picklistEntry: statusFieldDescription.getPicklistValues())
{
statusOptions.add(new SelectOption(pickListEntry.getValue(),pickListEntry.getLabel()));
if (picklistEntry.defaultValue){
selectedStatus = pickListEntry.getValue();
}
}
loadInvoiceStatements();
}
public void loadInvoiceStatements()
{
invoiceStatements = [SELECT Name, Invoice_Value__c, Description__c, Status__c
FROM Invoice_Statement__c
WHERE Status__c = :selectedStatus];
}
}
</apex:page>
Cool Post.. Thanks!
ReplyDeleteHi,
ReplyDeleteThanks for your cool post, helped me a lot, but one minor thing couldn't add with this, can you please help me to implement it.
I have remove None value, but I want to show red line(required) on picklist field, but it is not showing by putting Required = true.
Hi sem7114,
DeleteI'm not sure how possible that is without applying some custom styling: see this thread here for more info
http://boards.developerforce.com/t5/Visualforce-Development/required-attribute-not-working-correctly-on-apex-selectList/m-p/171987#M21771
Regards,
CAL
Hi Chris,
ReplyDeleteI have a question can we show the recordtype name as picklist value using the schema.DescribeFieldResult.
After looking at the schema.DescribeFieldResult methods I felt it is not possible. If i am wrong guide me please.
Thanks.
Suresh
Hi Suresh,
DeleteWhen entering the record type of an object using the Visualforce input field tag in a form, despite actually being a reference field, the record type appears on the page as a picklist. Even better, if the record type has an associated value for the object (is not blank) then the picklist will not appear with a "-none-" option.
note: To include this picklist on a page, the tag is
If for whatever reason you still want to get all of the possible values for the record type field, then this is possible using SOQL. It is not possible to get the values using describe field result, as the record type is a reference field rather than a picklist. Here is a great blog post on the subject, I hope it helps should you need it:
http://www.salesforcefast.com/2009/06/look-up-record-type-ids-with-one-query.html
Regards,
CAL
Error: Samp Compile Error: unexpected token: 'bucketlevel__c' at line 2 column 7
ReplyDeleteI had tried both methods as u posted:
Hi Prasad
DeleteCan you possibly post the code you have created, I may be able to point out any problems.
This comment has been removed by the author.
ReplyDelete