0

I need to take two SelectOption lists and create a third one which will be composed of the values which are in both lists.

I'm having trouble figuring out how to properly compare them in this code I have.

I've left out a good portion of the code in order to try and simplify it.

I need to compare the selectedSubs2 list to the getkeyTechValues list.

Here is the code :

selectedSubs2 = new list<SelectOption>();
String[] selectedvalues = selectedkeys.split(',');

        for (String selectedvalue: selectedvalues) 
            {
            selectedSubs2.add(new SelectOption(selectedvalue,selectedvalue));
            }


  public List<SelectOption> getkeyTechValues()
    {
        List<SelectOption> options=new List<SelectOption>();
            options.add(new SelectOption('--None--','--None--'));
            String[] picklistlines =new String[]{};

            for (String item : selectedMulPickKeyTech.split(',') )
             {

            if (!selectedItems.contains(item)) 
                {
                //add it to your iist
                options.add(new SelectOption(item,item));
                }
            }
        return options;
        }
    } 

    //somehow I need to compare the selectedSubs2 list to the getkeyTechValues 
    //and make a 3rd SelectOption list of only the values which are in both

Thank you very much for your help. I really appreciate it.

2
  • If applicable, try moving the select lists as picklist fields on an sobject. Using field dependencies, you can then dictate which values show up in the third picklist. If you need to reference them in Visualforce, then you should be able to use <apex:inputField /> for all three picklists to get what you want. Commented May 7, 2013 at 17:42
  • I wish I could do that but I can't. The individual lists are being formed through queries which are pulling in values from other records and relationships. Thanks though.
    – Zoom_v
    Commented May 7, 2013 at 17:53

3 Answers 3

1

Your controller will need to a lot of the work in terms of recalculating the third dropdown. I'm thinking the first and second select lists will call a method in your controller to clear out and re-generate the third dropdown, effectively creating a cascading or dependent drop down. See my controller example below.

public class MySelectListController{
    public List<String> firstSelections {get;set;}
    public List<String> secondSelections {get;set;}
    public List<String> thirdSelections {get;set;}

    public List<SelectOption> availableOptionsFirstList {get;set;}
    public List<SelectOption> availableOptionsSecondList {get;set;}
    public List<SelectOption> availableOptionsThirdList {get;set;}

    //Might have to modify if it's an extension, for instance
    public MySelectListController(){
        firstSelections = new List<String>();
        secondSelections = new List<String>();
        thirdSelections = new List<String>();

        //Populate your options lists here
        availableOptionsFirstList = new List<SelectOption>();
        availableOptionsFirstList.add(new SelectOption('A','A'));
        availableOptionsFirstList.add(new SelectOption('B','B'));
        availableOptionsFirstList.add(new SelectOption('C','C'));
        availableOptionsFirstList.add(new SelectOption('D','D'));


        availableOptionsSecondList = new List<SelectOption>();
        availableOptionsSecondList.add(new SelectOption('E','E'));
        availableOptionsSecondList.add(new SelectOption('F','F'));
        availableOptionsSecondList.add(new SelectOption('G','G'));
        availableOptionsSecondList.add(new SelectOption('H','H'));

        availableOptionsThirdList = new List<SelectOption>();        
    }

    public PageReference handleSelections(){
        availableOptionsThirdList.clear();
        addSelectedOptions(
            availableOptionsThirdList,
            availableOptionsFirstList,
            firstSelections);

        addSelectedOptions(
            availableOptionsThirdList,
            availableOptionsSecondList,
            secondSelections);

        //rerender current page
        return null;
    }

    private void addSelectedOptions(List<SelectOption> childOptions, List<SelectOption> parentOptions,List<String> selections){
         for(String current : selections){
            for(SelectOption opt : parentOptions){
                if(opt.getValue() == current){
                    childOptions.add(new SelectOption(opt.getValue(),opt.getLabel()));
                }
            }
        }
    }
}

Furthermore, you'll need to use an apex:actionFunction or call into the controller and rerender the visualforce page to pick up the changes incurred by calling the handleSelections method.

<apex:page controller="MySelectListController">
<apex:form id="theform">

    <apex:selectList value="{!firstSelections}" multiselect="true">
        <apex:selectOptions value="{!availableOptionsFirstList}"/>
        <apex:actionSupport action="{!handleSelections}" rerender="theform" event="onchange"/>
    </apex:selectList>
    <apex:selectList value="{!secondSelections}" multiselect="true">
        <apex:selectOptions value="{!availableOptionsSecondList}" />
        <apex:actionSupport action="{!handleSelections}" rerender="theform" event="onchange"/>
    </apex:selectList>
    <apex:selectList value="{!thirdSelections}" multiselect="true">
        <apex:selectOptions value="{!availableOptionsThirdList}" />
        <apex:actionSupport action="{!handleSelections}" rerender="theform" event="onchange"/>
    </apex:selectList>
</apex:form>
</apex:page>

Hope this helps get you on the right track.

4
  • DancinLlama, Thank you so much for this suggestion. I'm a little confused by it, but I'm trying to adapt it for myself. Right now I'm getting an error for the addSelectedOptions... method you have. It is saying this : "Compile Error: Method does not exist or incorrect signature: addSelectedOptions(LIST<System.SelectOption>, LIST<System.SelectOption>, LIST<String>)" - Is that a legit error or am I doing something wrong here ?
    – Zoom_v
    Commented May 8, 2013 at 0:05
  • 1
    Error's legit, I didn't actually try and run the code. You'll need to work through the errors and such yourself. The above is more pseudo code than anything. Commented May 8, 2013 at 13:25
  • There, fixed the compile errors out and tried it out. Commented May 8, 2013 at 13:33
  • Thank you very much for this DancinLlama. I really appreciate the help !
    – Zoom_v
    Commented May 9, 2013 at 12:39
2

What you are looking for is the intersection of the two sets of values. There is a method on the Set which allows for this intersection to be found.

Set<String> firstSetValues = new Set<String>( 'item1;item2;item3;item4;'.split(';') );
Set<String> secondSetValues = new Set<String>( 'item3;item4;item5;item6;'.split(';') );

// cloning the first set because the Set.retainAll() modifies the set
// which it is called upon
Set<String> intersectionSet = firstSetValues.clone(); 
intersectionSet.retainAll(secondSetValues);

system.debug('\n\n\tFirst Set: ' + firstSetValues + '\n');
system.debug('\n\n\tSecond Set: ' + secondSetValues + '\n');
system.debug('\n\n\tIntersection of the two Sets: ' + intersectionSet + '\n');

It produces this debug output:

USER_DEBUG|[7]|DEBUG|

    First Set: {item1, item2, item3, item4}

USER_DEBUG|[8]|DEBUG|

    Second Set: {item3, item4, item5, item6}

USER_DEBUG|[9]|DEBUG|

    Intersection of the two Sets: {item3, item4}

You then have the ability to use the intersectionSet to retrieve the relevant data and build the third List<SelectOption> (possibly retrieved from a map that has been defined in the controller which uses this intersectionSet's values as keys).


Update

Here is a similar example with List<SelectOption> instead. The intersection of the two is options 1 and 3. The value of selectOptionSetIntersection could be returned from a function.

// set up our lists of options
List<SelectOption> optionsList1 = new List<SelectOption>();
List<SelectOption> optionsList2 = new List<SelectOption>();

// add some options to each one
optionsList1.add(new SelectOption('value1','label1'));
optionsList1.add(new SelectOption('value2','label2'));
optionsList1.add(new SelectOption('value3','label3'));

optionsList2.add(new SelectOption('value1','label1'));
optionsList2.add(new SelectOption('value3','label3'));
optionsList2.add(new SelectOption('value5','label5'));
optionsList2.add(new SelectOption('value7','label7'));

// build two sets from these lists
Set<SelectOption> selectOptionSet1 = new Set<SelectOption>( optionsList1 );
Set<SelectOption> selectOptionSet2 = new Set<SelectOption>( optionsList2 );

// clone the first list so that it's not modified
Set<SelectOption> selectOptionSetIntersection = selectOptionSet1.clone();

// keep only the selectoptions which are in both
selectOptionSetIntersection.retainAll(selectOptionSet2);

// output some visible proof
system.debug('\n\n\tFirst Set: ' + selectOptionSet1 + '\n');
system.debug('\n\n\tSecond Set: ' + selectOptionSet2 + '\n');
system.debug('\n\n\tIntersection of the two Sets: ' + selectOptionSetIntersection + '\n');
1
  • Thank you very much for this input Mark. I really appreciate it.
    – Zoom_v
    Commented May 9, 2013 at 12:40
1

You can add Lists of Strings directly to Sets of Strings using the addall method. So I would do that and then use the Contains feature of Sets to look for values that appear in both

So add the first List to a new Set, then loop through list 2, see if the value is contained in the new Set - if so, you have a match, and you add it to the select option

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .