Blog

Multiple Selections on a Drop-Down List (Combo-Box)

MultiPickList :

Do you need to select multiple values from a dropdown list that you define?

Here we go !!!!

From a list of drop down values you can select multiple values on the MultiPickList component.

In this blog, we would like to share the idea of selecting multiple values from a combo-box.

The custom aura component shows a combo-box, the combo-box is used to select multiple values.

Multiple Selections Drop-Down List
Multiple Selections Drop-Down List

On clicking the multiple option, the list of selected options will be displayed inside and outside the combo-box.

Multiple Selections Drop-Down List
Multiple Selections Drop-Down List

You can also remove the selected options by clicking the cross mark on each option outside the combo-box or again clicking the same option will be unselected.

Multiple Selections Drop-Down List

Here we go with the code for the same !!!

MultiSelectionPickList.cmp

<aura:component controller="GetPickListValues" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<!--MultiPickList attributes-->
<aura:attribute name="pickListOptions" type="List" />
<aura:attribute name="selectedOptions" type="String" default="" />
<aura:attribute name="placeHolderName" type="String" default="Select Options"/>
<aura:attribute name="optionsList" type="list" default="" />

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

<article class="slds-card"> 
    <div class="slds-card__body slds-card__body_inner">
    <!-- Selection of the values from the drop-down list -->   
    <div class="slds-col">
        <div class="slds-form-element">
            <label class="slds-form-element__label" for="combobox-unique-id-3">Stage</label>
            <div class="slds-form-element__control">
                <div class="slds-combobox_container" aura:id="dropdown" data-id="Dropdown">
                    <div  class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click" aria-expanded="true" aria-haspopup="listbox" role="combobox">
                        
                        <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
                            <input type="text" class="slds-input slds-combobox__input slds-combobox__input-value"
                                placeholder="{!v.placeHolderName}" readonly="true" onclick="{!c.handleOpenDropdown}" value="{!v.selectedOptions}"/>
                            <span class="slds-icon_container slds-icon-utility-down slds-input__icon slds-input__icon_right" title="Down icon">
                                <lightning:icon iconName="utility:down" size="xx-small" class="slds-icon-text-default"/>
                            </span>
                        </div>
                        
                        <div id="listbox-unique-id" role="listbox">
                            <ul class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid" role="presentation">
                                <div class="slds-scrollable">
                                    <aura:iteration items="{!v.pickListOptions}" var="item" indexVar="ind">
                                        
                                        <li id="{!item.label+'-'+item.isChecked}" role="presentation" onclick="{!c.handleFilterValueChange}" class="slds-listbox__item">
                                            <div id="{!'listbox-option-unique-id-'+(ind+1)}"
                                                class="{!item.isChecked==true?'slds-media slds-listbox__option slds-listbox__option_plain slds-media_small slds-media_center slds-is-selected':'slds-media slds-listbox__option slds-listbox__option_plain slds-media_small slds-media_center'}" role="option">
                                                <span class="slds-media__figure">
                                                    <lightning:icon iconName="utility:check" size="xx-small" class="slds-listbox__icon-selected"/>
                                                </span>
                                                <span class="slds-media__body">
                                                    <span class="slds-truncate" style="color:black;" title="{!item.label}"> {!item.label}</span>
                                                </span>
                                            </div>
                                        </li>
                                        
                                    </aura:iteration>
                                </div>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
            <!-- To display the selected options -->
            <aura:iteration items="{!v.pickListOptions}" var="option">
                <aura:if isTrue="{!option.isChecked}">
                    <lightning:pill class="slds-m-around_xx-small" name="{!option.label}" label="{!option.label}" onremove="{!c.handleRemovePill}"/>
                </aura:if>
            </aura:iteration> 
        </div>
    </div>
    </div>
  </article>
</aura:component>	

MultiSelectionPickListController.js

({
    doInit : function(component, event, helper) {
        console.log('Inside do init');
        var caplist=[];
        var action = component.get("c.getPickListValuesT");
        action.setCallback(this, function(data) {
            var state = data.getState();
            if(state == "SUCCESS"){
                var returnValue = data.getReturnValue();
                console.log('returnValue'+returnValue);
                component.set("v.optionsList",returnValue.stagePickListValues); 
            }
            else {
                alert("Error occured while fetching data");
            }
        });
        $A.enqueueAction(action);          
        
        window.setTimeout(
            $A.getCallback(function() {
                let capabilities = component.get("v.optionsList");
                for(let i = 0; i < capabilities.length; i++){
                    
                    caplist.push({ label: capabilities[i],isChecked:false});
                } 
                component.set("v.pickListOptions", caplist);  
                console.log('pickListOptions' + JSON.stringify(component.get("v.pickListOptions")));
            }), 1000
        );
    },
    
    handleOpenDropdown:function(component,event,helper){
        
        var index = component.get('v.valuesDropDownIndex');

        // Get the index of the Values dropdown for the selected/opened Filter pill and apply Open style for the pill
        let addDropDowm = document.querySelector(`[data-id="Dropdown"]`);
        addDropDowm.classList.add('slds-is-open');

        
    },
    
    handleFilterValueChange : function(component,event,helper) {
        
        var label = event.currentTarget.id.split("-")[0];
        var isCheck = event.currentTarget.id.split("-")[1];
        
        helper.selectFilterValue(component, label, isCheck);
        
        
    },
    
    handleRemovePill : function(component,event,helper){
        
        var value = event.getSource().get("v.label");
        var removedOptions = component.get("v.pickListOptions");
        var count = 0;
        var selectedListData=[];
        
        for(let i=0; i < removedOptions.length; i++) {
            
            if(removedOptions[i].label == value){
                removedOptions[i].isChecked = false;
            }
            if(removedOptions[i].isChecked){
                selectedListData.push(removedOptions[i].label); 
                count++;
            }
        }
        
        if(selectedListData.length > 0) {
            component.set("v.selectedOptions", JSON.stringify(selectedListData));
        } else {
            component.set("v.selectedOptions", component.get("v.placeHolderName"));
        }
        
        component.set("v.pickListOptions", removedOptions);
    },
});

MultiSelectionPickListHelper.js

({
    selectFilterValue : function(component, label, isCheck) {
        var selectedPickListValues = [];
        var availablePickListValues = component.get('v.pickListOptions');

        for(var i=0; i<availablePickListValues.length; i++) { 
            if(availablePickListValues[i].label == label && isCheck=='true') { 
                availablePickListValues[i].isChecked = false;
            } else if(availablePickListValues[i].label == label && isCheck=='false') { 
                availablePickListValues[i].isChecked = true; 
            }
            if(availablePickListValues[i].isChecked) { 
                selectedPickListValues.push(availablePickListValues[i].label);
            } 
        }
        if(selectedPickListValues.length > 0) {
            component.set("v.selectedOptions", selectedPickListValues);
        } else {
            component.set("v.selectedOptions", component.get("v.placeHolderName"));
        }
        
        component.set("v.pickListOptions", availablePickListValues);
        
    },
});

Apex class:

GetPickListValues.cls

public with sharing class GetPickListValues {

    @AuraEnabled(cacheable=true)    
    public static pickListWrapper getPickListValuesT(){
        
        pickListWrapper wrapperPickList = new pickListWrapper();
        List<String> options = new List<String>();
        
        Schema.DescribeFieldResult fieldResult = Opportunity.StageName.getDescribe();
        List<Schema.PicklistEntry> pickListValues = fieldResult.getPicklistValues();
        
        for( Schema.PicklistEntry pickListValue : pickListValues)
        {
            options.add(pickListValue.getLabel());
        }  
        
        wrapperPickList.stagePickListValues = options;
        return wrapperPickList;
         
    } 

    public class pickListWrapper {
        @AuraEnabled
        public List<String> stagePickListValues;
    } 
    
}