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
Manoj Maraka 18Manoj Maraka 18 

Issue working with Multiselect picklists

Hi All,

I am very new to Salesforce. I am trying to implement 2 multiselect picklists, Left picklist takes contacts from Contact object and on clicking ">>" button selected contacts should be moved from left picklist to right picklist. And on hitting 'Save', a message should be displayed saying so and so contacts are selected.
The issue here is the contacts are not getting added in right picklist. I dont know where I am going wrong. Could anyone please help? Here's the code I used.

VF Page:

<apex:page controller="multiselect2">
    <apex:form >
    <apex:pageBlock >
    
        <apex:outputLabel value="   Available List"> </apex:outputLabel>
      
        
        <apex:panelGrid columns="3" id="abcd">
        
            
            <apex:selectList id="sel1" value="{!leftselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!unselectedvalues}" />
            </apex:selectList>
                <apex:panelGroup >
                    <br/>
                    
                        <apex:commandbutton value=">>" action="{!selectclick}" reRender="abcd"></apex:commandbutton>
                    
                    
                    <br/><br/>
                    <apex:actionRegion >
                        <apex:commandbutton value="<<" action="{!unselectclick}" reRender="abcd">  </apex:commandbutton>  
                    </apex:actionRegion>
                         
                </apex:panelGroup>
                
            <apex:selectList id="sel2" value="{!rightselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!rightselected}" />
            </apex:selectList>
        </apex:panelGrid>
        
        <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}"/>
                
            </apex:pageBlockButtons>
          </apex:pageBlock>
         
    </apex:form>
</apex:page>

Controller:
public class multiselect2 {
    
    Public List<Contact> leftselected{get;set;}
    Public List<Contact> rightselected{get;set;}
    Set<Contact> leftvalues = new Set<Contact>();
    Set<Contact> rightvalues = new Set<Contact>();
    
    public multiselect2(){
        List<Contact> ov = [SELECT Id, Name FROM Contact]; 
        Set<Contact> originalValues = new Set<Contact>(ov);
        leftselected = new List<Contact>();
        rightselected = new List<Contact>();
        leftvalues.addAll(originalValues);
    }
     
    public PageReference selectclick(){
        rightselected.clear();
        for(Contact c : leftselected){
       
            leftvalues.remove(c);
            rightvalues.add(c);
            
        }
        return null;
    }
     
    public PageReference unselectclick(){
        leftselected.clear();
        for(Contact c : rightselected){
            rightvalues.remove(c);
            leftvalues.add(c);
        }
        return null;
    }
 
    public List<SelectOption> getunSelectedValues(){
        List<SelectOption> options = new List<SelectOption>();
        List<Contact> tempList = new List<Contact>();
        tempList.addAll(leftvalues);
        tempList.sort();
        for(Contact c : tempList)
            options.add(new SelectOption(c.id,c.name));
        return options;
    }
 
    public List<SelectOption> getSelectedValues(){
        List<SelectOption> options1 = new List<SelectOption>();
        List<Contact> tempList = new List<Contact>();
        tempList.addAll(rightvalues);
        tempList.sort();
        for(Contact c : tempList)
            options1.add(new SelectOption(c.id,c.name));
        return options1;
    }
    public PageReference save() {
    
        
    return null;
    }
}


 
Best Answer chosen by Manoj Maraka 18
mritzimritzi
Made few changes in the code, works perfectly as required

Apex:
public class multiselect2{
    public List<Id> leftSelected{get;set;} // holds contact ids of left selected values
    // holds contact ids of right selected values, in case you want to use it.
    public List<Id> rightSelected{get;set;}
    public List<SelectOption> leftPLValues{get;set;}
    public List<SelectOption> rightPLValues{get;set;}
     
    Map<Id,Contact> contactMap;
    Set<Id> contactIds;
    public multiselect2(){
        leftSelected = new List<Id>();
        rightSelected = new List<Id>();
        leftPLValues = new List<SelectOption>();
        rightPLValues = new List<SelectOption>();
        try{
            // fetch contact records and store in contactMap variable
            contactMap = new Map<Id,Contact>([SELECT id,Name FROM Contact LIMIT 100]);
            // store ids of fetched contact records in contactIds set
            contactIds = contactMap.keyset();
            //populate left Picklist for the first time
            for(Id i:contactIds)
                leftPLValues.add(new SelectOption(i,contactMap.get(i).Name));
        }catch(Exception e){
            System.debug(e);
        }
    }
    /*
    * removed getLeftValues & getRightValues function
    * reintroduced submitClick function, added leftPLValues & rightPLValues
    */
    public void selectClick(){
        while(leftSelected.size()>0){
            rightPLValues.add(new SelectOption(leftSelected[0],contactMap.get(leftSelected[0]).Name));
            leftPLValues.remove(0);
            leftSelected.remove(0);
        }
    }
    public void unselectClick(){
        while(rightSelected.size()>0){
            leftPLValues.add(new SelectOption(rightSelected[0],contactMap.get(rightSelected[0]).Name));
            rightPLValues.remove(0);
            rightSelected.remove(0);
        }
    }
    public PageReference save(){
        return null;
    }
}

VF:
<apex:page controller="multiselect2">
    <apex:form >
    <apex:pageBlock >
        <apex:outputLabel value="   Available List"> </apex:outputLabel>
        <apex:panelGrid columns="3" id="abcd">
                   
            <apex:selectList id="sel1" value="{!leftselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!leftPLValues}" />
            </apex:selectList>
                <apex:panelGroup >
                    <br/>
                        <apex:commandbutton value=">>" action="{!selectClick}"/>                   
                    <br/><br/>
                    <apex:actionRegion >
                        <apex:commandbutton value="<<" action="{!unselectClick}" />  
                    </apex:actionRegion>
                         
                </apex:panelGroup>
            <apex:selectList id="sel2" value="{!rightselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!rightPLValues}" />
            </apex:selectList>
        </apex:panelGrid>
        <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}"/>
            </apex:pageBlockButtons>
          </apex:pageBlock>
    </apex:form>
</apex:page>
Note: The values removed from right picklist are added back at the end of left picklist

Mark this as Best Answer, if this solves your problem.

All Answers

Nayana KNayana K
<apex:page controller="multiselect2">
    <apex:form >
    <apex:pageBlock >
    
        <apex:outputLabel value="   Available List"> </apex:outputLabel>
      
         
        
        <apex:panelGrid columns="3" id="abcd">
        
            
            <apex:selectList id="sel1" value="{!leftselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!leftvalues}" />
            </apex:selectList>
                <apex:panelGroup >
                    <br/>
                    
                        <apex:commandbutton value=">>" action="{!selectclick}" reRender="abcd"></apex:commandbutton>
                    
                    
                    <br/><br/>
                    <apex:actionRegion >
                        <apex:commandbutton value="<<" action="{!unselectclick}" reRender="abcd">  </apex:commandbutton>  
                    </apex:actionRegion>
                         
                </apex:panelGroup>
                
            <apex:selectList id="sel2" value="{!rightselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!rightvalues}" />
            </apex:selectList>
        </apex:panelGrid>

        <apex:pageBlockButtons >
                <!--<apex:commandButton value="Save" action="{!save}"/>-->
                
            </apex:pageBlockButtons>
          </apex:pageBlock>
         
    </apex:form>
</apex:page>
 
public class multiselect2 
{
    public List<SelectOption> leftvalues { get;set;}
    public List<SelectOption> rightvalues { get;set;}
    Public List<String> leftselected{get;set;}
    Public List<String> rightselected{get;set;}
    private Map<Id, Contact> mapContact;
    
    public multiselect2()
    {
        mapContact = new Map<Id, Contact>([SELECT Id, Name FROM Contact]); 
        
        leftvalues = new List<SelectOption>();
        rightvalues = new List<SelectOption>();
        leftselected = new List<String>();
        rightselected = new List<String>();
        
        fillLeftValues();
    }
     
    private void fillLeftValues()
    {
        for(Contact objContact : mapContact.values())
        {
            leftvalues.add(new SelectOption(objContact.Id, objContact.Name));
        }
    }
    
    public void selectclick()
    {
        system.debug('===selectclick===');
        selectOrDeselect(leftselected, leftvalues, rightselected, rightvalues);
    }
    
    public void unselectclick()
    {
        system.debug('===unselectclick===');
        system.debug('===rightselected==='+rightselected);
        selectOrDeselect(rightselected, rightvalues, leftselected, leftvalues);
    }
    
    private void selectOrDeselect(List<String> lstSelectedFrom, List<SelectOption> lstFrom, List<String> lstSelectedTo, List<SelectOption> lstTo)
    {
        system.debug('====lstSelectedFrom==='+lstSelectedFrom);
        system.debug('====lstFrom==='+lstFrom);
        system.debug('====lstSelectedTo==='+lstSelectedTo);
        system.debug('====lstTo==='+lstTo);
        
        lstSelectedTo.clear();
        
        Set<String> setSelectedIds = new Set<String>();
        
        for(String strSelectedId : lstSelectedFrom)
        {
            lstTo.add(new SelectOption(strSelectedId, mapContact.get(strSelectedId).Name));
        }
        
        setSelectedIds.addAll(lstSelectedFrom);
        
        for(Integer i=0; i< lstFrom.size(); i++)
        {
            if(setSelectedIds.contains(lstFrom[i].getValue()))
            {
                lstFrom.remove(i);
                i--;
            }
        }
        
        lstSelectedFrom.clear();
    }
    
   
    public PageReference save() {
    
        
    return null;
    }
}



'>>' click is working properly but '<<' click is not setting rightselected value that is why unselect is not working (line 38 is not giving selcted value on right side) . Need to figure it out the reason or any someother alternative way .
mritzimritzi
Hi Manoj,
I have modifed your code a bit, and tried to make it sleek. please have a look
Apex:
public class multiselect2{
    public List<Id> leftSelected{get;set;} // holds contact ids of left selected values
    // holds contact ids of right selected values, in case you want to use it.
    public List<Id> rightSelected{get;set;} 
    Map<Id,Contact> contactMap;
    Set<Id> contactIds;
    public TestClass2(){
        leftSelected = new List<Id>();
        rightSelected = new List<Id>();
        try{
            // fetch contact records and store in contactMao variable
            contactMap = new Map<Id,Contact>([SELECT id,Name FROM Contact LIMIT 100]);
            // store ids of fetched contact records in contactIds set
            contactIds = contactMap.keyset();
        }catch(Exception e){
            System.debug(e);
        }
    }
    //removed selectClick function as clicking ">>" button simply reRenders the page
    //function to populate left picklist
    public List<SelectOption> getLeftValues(){
        List<SelectOption> options = new List<Selectoption>();
        for(Id i:contactIds)
            options.add(new SelectOption(i,contactMap.get(i).Name));
        return options;
    }
    // function to populate right picklist
    public List<SelectOption> getRightValues(){
        List<SelectOption> options = new List<Selectoption>();
        for(Id i:leftSelected)
            options.add(new SelectOption(i,contactMap.get(i).Name));
        return options;
    }
    // function to clear right picklist values
    public void unselectClick(){
        rightSelected.clear();
        leftSelected.clear();
    }
    public PageReference save(){
        return null;
    }
}

VF:
<apex:page controller="multiselect2">
    <apex:form >
    <apex:pageBlock >
        <apex:outputLabel value="   Available List"> </apex:outputLabel>
        <apex:panelGrid columns="3" id="abcd">
                   
            <apex:selectList id="sel1" value="{!leftselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!LeftValues}" />
            </apex:selectList>
                <apex:panelGroup >
                    <br/>
                        <apex:commandbutton value=">>" reRender="abcd"/>                   
                    <br/><br/>
                    <apex:actionRegion >
                        <apex:commandbutton value="<<" action="{!unselectclick}" />  
                    </apex:actionRegion>
                         
                </apex:panelGroup>
            <apex:selectList id="sel2" value="{!rightselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!RightValues}" />
            </apex:selectList>
        </apex:panelGrid>
        <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}"/>
            </apex:pageBlockButtons>
          </apex:pageBlock>
    </apex:form>
</apex:page>

Mark this as Best Answer, if this solves your problem.
Manoj Maraka 18Manoj Maraka 18
Hi mritzi,

Your code gives following compile error. Error: Compile Error: Invalid constructor name: TestClass2 at line 7 column 12
mritzimritzi
LIne 7: Change TestClass2 to multiselect2
Manoj Maraka 18Manoj Maraka 18
Thanks Rizwan. One last thing. Left pick list values aren't removed after moving to right picklist. Meaning if a contact is moved to right, that contacts exists in both the picklists.
mritzimritzi
Made few changes in the code, works perfectly as required

Apex:
public class multiselect2{
    public List<Id> leftSelected{get;set;} // holds contact ids of left selected values
    // holds contact ids of right selected values, in case you want to use it.
    public List<Id> rightSelected{get;set;}
    public List<SelectOption> leftPLValues{get;set;}
    public List<SelectOption> rightPLValues{get;set;}
     
    Map<Id,Contact> contactMap;
    Set<Id> contactIds;
    public multiselect2(){
        leftSelected = new List<Id>();
        rightSelected = new List<Id>();
        leftPLValues = new List<SelectOption>();
        rightPLValues = new List<SelectOption>();
        try{
            // fetch contact records and store in contactMap variable
            contactMap = new Map<Id,Contact>([SELECT id,Name FROM Contact LIMIT 100]);
            // store ids of fetched contact records in contactIds set
            contactIds = contactMap.keyset();
            //populate left Picklist for the first time
            for(Id i:contactIds)
                leftPLValues.add(new SelectOption(i,contactMap.get(i).Name));
        }catch(Exception e){
            System.debug(e);
        }
    }
    /*
    * removed getLeftValues & getRightValues function
    * reintroduced submitClick function, added leftPLValues & rightPLValues
    */
    public void selectClick(){
        while(leftSelected.size()>0){
            rightPLValues.add(new SelectOption(leftSelected[0],contactMap.get(leftSelected[0]).Name));
            leftPLValues.remove(0);
            leftSelected.remove(0);
        }
    }
    public void unselectClick(){
        while(rightSelected.size()>0){
            leftPLValues.add(new SelectOption(rightSelected[0],contactMap.get(rightSelected[0]).Name));
            rightPLValues.remove(0);
            rightSelected.remove(0);
        }
    }
    public PageReference save(){
        return null;
    }
}

VF:
<apex:page controller="multiselect2">
    <apex:form >
    <apex:pageBlock >
        <apex:outputLabel value="   Available List"> </apex:outputLabel>
        <apex:panelGrid columns="3" id="abcd">
                   
            <apex:selectList id="sel1" value="{!leftselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!leftPLValues}" />
            </apex:selectList>
                <apex:panelGroup >
                    <br/>
                        <apex:commandbutton value=">>" action="{!selectClick}"/>                   
                    <br/><br/>
                    <apex:actionRegion >
                        <apex:commandbutton value="<<" action="{!unselectClick}" />  
                    </apex:actionRegion>
                         
                </apex:panelGroup>
            <apex:selectList id="sel2" value="{!rightselected}" multiselect="true" style="width:150px" size="7">
                <apex:selectOptions value="{!rightPLValues}" />
            </apex:selectList>
        </apex:panelGrid>
        <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}"/>
            </apex:pageBlockButtons>
          </apex:pageBlock>
    </apex:form>
</apex:page>
Note: The values removed from right picklist are added back at the end of left picklist

Mark this as Best Answer, if this solves your problem.
This was selected as the best answer