Dynamically add values to picklist using Visualforce

3:58 AM

Many a times we come across situations in which we want data to be added to a picklist dynamically.

By saying dynamic i mean that you do not want an Administrator to go to the field level setup and add values to the picklist...

Here is a detailed description of a scenario from one of my friends...


Scenario..

Problem explanation with Example: A picklist field "City" with values:Delhi,Mumbai,Chennai,Kolkata(4 picklist values) and a textbox nearby to enter any other city. Supposing if Bangalore has to be entered, the user has to use the textbox. Now next time when a record is created, the "City" field should show "Bangalore" as 5th value.

Screenshots:
As you can see below, there are only three values available for selection.


I am selecting 'Other' from the dropdown, this action displays a text box for the new value and a button called "Add".



I am entering a new value called "Bangalore" and i am clicking on "Add"


Done!! Now you can see that the new value "Bangalore" is also added to the dropdown..



We will achieve this functionality using visualforce. You can then extend the code provided here to as many Visualforce pages as you want.


Step 1:

First of all, we will have to create an object to hold all the picklist values. So, go ahead and create the following..

Object name : DynamicPicklist
Field Names:
Name (Datatype : Autonumber)
PicklistValue (Datatype: text)

Step 2:

Add picklist values to the object created.. (ie) Add records to the newly created object...

For example..

Record 1: PicklistValue= 'Delhi'
Record 2: PicklistValue = 'Mumbai'

and so on...........

Now also add a value called '--Other--'. This value will be used for the user to enter a new value.

Step 3:

Creation of the Visualforce page and the Apex Class.

Apex Code.. Save this first

public class dynamicpicklist
{
public String city{get; set;}

public List<SelectOption> getcitynames()
{
List<SelectOption> options = new List<SelectOption>();
List<DynamicPicklist__c> citylist = new List<DynamicPicklist__c>();
citylist = [Select Id, PicklistValue__c FROM DynamicPicklist__c ];
options.add(new SelectOption('--None--','--None--'));
for (Integer j=0;j<citylist.size();j++)
{
options.add(new SelectOption(citylist[j].PicklistValue__c,citylist[j].PicklistValue__c));
}
return options;
}
public String newpicklistvalue{get; set;}

public void saverec()
{
DynamicPicklist__c newrec = new DynamicPicklist__c(PicklistValue__c=newpicklistvalue);
insert newrec;
newpicklistvalue=NULL;
}

}


Visualforce code...

<apex:page controller="dynamicpicklist" sidebar="false" >
<apex:form >
<apex:sectionHeader title="Dynamic Picklist" subtitle="Reusable code"/>
<apex:pageblock >
<apex:pageBlockSection title="Dynamic picklist" columns="1">
<apex:pageblocksectionItem >
<apex:outputlabel value="City" for="values" />
<apex:selectList value="{!city}" size="1" id="values">
<apex:actionSupport event="onchange" reRender="newvalue" />
<apex:selectOptions value="{!citynames}"/>
</apex:selectList>
</apex:pageblocksectionItem>
<apex:outputpanel id="newvalue">
<apex:outputpanel rendered="{!city == '--Other--'}">
<div style="position:relative;left:75px;">
<apex:outputlabel value="New value" for="newval" />
<apex:inputText value="{!newpicklistvalue}" id="newval"/>
<apex:commandbutton action="{!saverec}" value="Add!"/>
</div>
</apex:outputpanel>
</apex:outputpanel>
</apex:pageblocksection>
</apex:pageblock>
</apex:form>
</apex:page>

How to extend this code???

Are you wondering if you will have to create one object for one picklist and suppose you have ten picklists like these, then ten objects... That is really a mess...

So, why not create ten fields in the same object.. Field1 represents picklist1, field2 picklist2 and so on...

But, be clear on the way you retrieve values and insert values into this object... For ex: I have not performed the validation to check if the newly entered value already exists..

Comments and Queries most welcome!!!!

25 comments

  1. Hey validation against the already existing values is important. Also simple.

    Before invoking the class which inserts the new records, just query the 'to be inserted' value and insert it only if null is returned. Also maintain the Title Casing format, [meaning --> if the user enters bangalore, Bangalore, BANGALORE, BanGalore, etc only "Bangalore" should be entered].

    If you could incorporate this part of code, i could use it.

    ReplyDelete
  2. Is it possible to create picklist base on query results.
    appreciate your comments

    ReplyDelete
  3. Yes it is possible (in Visualforce).. You will have to pass the query results to your SelectList and display it as a Picklist in your Visualforce Page..

    ReplyDelete
  4. I implemented the your dynamicpicklist in my Developer Edition and it works perfectly. I need to move the whole thing to an Enterprise Edition. To do that though there must be a test method in the Apex code. I have done that before using a trigger to make the code run. In this case there is no trigger, so I do not know how to formulate the test method. Can you help?

    ReplyDelete
  5. Are you trying to say that this is a trick you discovered? Isn't this the typical way of creating/displaying records using visualforce pages? Try finding a solution to modify the real picktlist field (a field defined as picklist type) and that would be something.

    ReplyDelete
  6. Hi.. I wouldn't say that this is a trick but rather a better approach to handling picklists that accept dynamic values.. I believe Salesforce comes with an option of adding values dynamically to a picklist field type in the future.. Thanks for your comments and will let you know if i find a solution for your query

    ReplyDelete
  7. good well done !! can we add values to multipicklist dynamically ???

    ReplyDelete
  8. This information was really very helpful

    ReplyDelete
  9. it would be nice if detail explanation regarding....

    1)selectlist and selectoption tags of visualforce.

    and

    2)how to get the selected picklist value into the controller and assign it to a string.
    is given.

    ReplyDelete
  10. Excelent Work ( please can any one tell me about the Dependent picklist by visualforce pages )

    ReplyDelete
  11. Am getting the below error...why should i overcome ....
    Visualforce Error

    System.NullPointerException: Argument 1 cannot be null
    External entry point

    ReplyDelete
    Replies
    1. You need to create some records for DynamicPicklist__c and insert the picklist values

      Delete
  12. I want to change the layout of a visual force page which has a pickl ist that gets its values dynamically and I want to use CSS style sheet for this..How can I change the alignment the fields that are coming to the page dynamically using CSS

    ReplyDelete
  13. I got the following error.....
    System.NullPointerException: Argument 1 cannot be null...

    ReplyDelete
    Replies
    1. You need to create some records for DynamicPicklist__c and insert the picklist values

      Delete
  14. tring to retrive values from model to vf page and i got the following error System.NullPointerException: Argument 1 cannot be null ... can anyone help me with this issue

    ReplyDelete
    Replies
    1. You need to create some records for DynamicPicklist__c and insert the picklist values

      Delete
  15. This comment has been removed by the author.

    ReplyDelete
  16. when u enter a value it will create a record i will not add in sobject

    ReplyDelete
  17. in step1 what I have to do , created 1object named DynamicPicklist and trying to create 2 fields -Datetype -Text named as picklistvalue and another one is Autonumber named as Name but from where I have to enter the picklist values as I didn't select picklist

    ReplyDelete
  18. good post but i am looking for a dynamic page creation that work with same site url.

    ReplyDelete
  19. Excellent and very useful information! The only thing I'd add clarification on is how to add this snippet to a standard page (this blog post helped me: http://blog.jeffdouglas.com/2009/05/08/inline-visualforce-pages-with-standard-page-layouts/).

    FYI: I added the "--Other--" option in code rather than as a value in the object to prevent overwriting or editing of the value. And I added it to the beginning to make it easier for users who don't need to scroll the picklist if they don't have to.

    ReplyDelete

AD