Friday, December 18, 2009

Creating a multilevel dependent picklist on Visualforce inside a Data table

Recently on working on a project I cam across a serious issue, creating a multilevel picklist with N-Level dependency.
e.g., Picklist one, select option, picklist two displays related values, select a value and the data for Picklist 3 are filtered based on picklist 1 and 2 and this goes on.
Lets increase the complexity a bit, you want to have this functionality in a data table with multiple rows.

The code for this seems tricky, but I did manage to write some.

The trick is create a wrapper class within you Apex:Class and bind it with the SelectList.

VF Page:

<apex:actionRegion >
<apex:pageBlockSection id="theSection" rendered="{!noLob}"> 
<apex:dataTable value="{!packages}" var="field" id="thetable" cellpadding="3px" id="dt">
<apex:column headerValue="Action">
<apex:CommandButton action="{!copyRow}" value="Copy" rerender="theSection" status="pleasewait">
<apex:param name="Assignment" Assignto="{!SelIndex}" value="{!field.index}"/>
<apex:column headerValue="Product Group">
<apex:selectList value="{!field.level1}" size="1" >
<apex:selectOptions value="{!field.level1Options}" /> 
<apex:actionSupport event="onchange" reRender="level2" status="pleasewait"> 
<apex:column headerValue="Products" >  
<apex:selectList id="level2" value="{!field.level2}" size="1" disabled="{!field.disable_level2}">
<apex:selectOptions value="{!field.level2Options}"/>     

And now the controller:

public class AddNewProductsController { 
public class myObject{
 public string level1 {get;set;} // The selected Level1 value in the Product Picklist on the modal panel
 public string level2 {get;set;}// The selected Level2 value in the Product Picklist on the modal panel
 public boolean disable_level2{get;set;}// The determines if Level2 value in the Product Picklist is disabled
 public boolean disable_level3{get;set;}// The determines if Level3 value in the Product Picklist is disabled
 public boolean FormRendered{get;set;}
 public myObject(){
 public List getLevel1Options(){
 List options = new List();
 Options.add(new SelectOption('','--None--'));
 Options.add(new SelectOption('Product Group 1','Product Group 1')); 
Options.add(new SelectOption('Product Group 2','Product Group 2')); 
 Options.add(new SelectOption('Product Group 3','Product Group 3')); 
 Options.add(new SelectOption('Product Group 4','Product Group 4')); 
 return options;
 public List getLevel2Options(){
 List options = new List();
 options.add(new SelectOption('', '--None--')); 
 if(level1 == 'Product Group 1'){
 options.add(new SelectOption('Product1', 'Product1'));
 options.add(new SelectOption('Product2', 'Product2'));
 }else if(level1 == 'Product Group 2'){
 options.add(new SelectOption('Product1', 'Product1'));
 options.add(new SelectOption('Product15', 'Product15'));
 }else if(level1 == 'Product Group 3'){
 options.add(new SelectOption('Product2', 'Product2'));
 options.add(new SelectOption('Product23', 'Product23'));
 }else if(level1 == 'Product Group 4'){
 options.add(new SelectOption('Product16', 'Product16'));
 options.add(new SelectOption('Product12', 'Product12'));
 }else if(level1 == 'Product Group 5'){
 options.add(new SelectOption('Product16', 'Product16'));
 options.add(new SelectOption('Product1', 'Product1'));
 return options;

This code will do your trick.

Hope it helps,