I am going to show to create custom multiselect component using salesforce lightning design system static HTML.

Here I am retrieving data from custom object in list and populate in options and making options multiselect.

Follow the below process step by step then you will be able to create multiselect picklist: –

Step 1: Create lightning component “MultiSelectComponent.cmp” and use below code.

<aura:component controller="ExpenseOptionsCtr">
<aura:attribute name="lstExpenseData" type="Expense__c[]" />
<aura:handler name="init" action="{!c.doInit}" value="{!this}"></aura:handler>
<c:QFMultiSelectUIComp options_="{!v.lstExpenseData}" />
</aura:component>

When you will save this code then it will fail to save because we didn’t create “QFMultiSelectUIComp” till now. Before we create this component let we should create MultiSelectComponentController and MultiSelectComponentHelper . Now follow next step.

Step 2: Create lightning component controller “MultiSelectComponentController.js” and use below code.

({
    doInit : function(component, event, helper) {
        helper.expenseDetails(component, event, helper);
    }
})

Step 3: Create lightning component helper “MultiSelectComponentHelper.js” and use below code.

({
expenseDetails : function(component, event, helper) {

var action = component.get("c.getExpenseDetails"); //Calling Apex class controller 'getTemplateRecrod' method

action.setCallback(this, function(res) {

var state = res.getState();

if (state === "SUCCESS") {

component.set("v.lstExpenseData", res.getReturnValue());

} else {

var toastEvent = $A.get("e.force:showToast");

toastEvent.setParams({

"title": "Error :",

"mode": "sticky",

"message": res.getError()[0].message

});

toastEvent.fire();

}

});

$A.enqueueAction(action);

}

})

We defined the controller “ExpenseOptionsCtr” in component so now create controller .

Step 4: Create apex controller “ExpenseOptionsCtr.apxc” , in this getting data from custom object Expense__c but you can use any object.

public class ExpenseOptionsCtr {

          @AuraEnabled

    public static List<Expense__c> getExpenseDetails(){

        List<Expense__c> lstExpense=[Select Id,Name From Expense__c];

        return lstExpense;

    }

}

Step 5: Create lightning component “QFMultiSelectUIComp.cmp” and use below code.

<aura:component >

    <aura:attribute name="MultipleoptnId" type="object" />

    <aura:attribute name="options_" type="String[]" />

    <aura:attribute name="selectedItems" type="String[]" />

    <aura:attribute name="infoText" type="String" default="Select an option..." />

    <aura:attribute name="width" type="String" default="245px;" />

    <aura:attribute name="dropdownLength" type="Integer" default="4" />

    <aura:registerEvent name="selectChange" type="c:SelectChange" />

    <aura:method name="reInit" action="{!c.init}" description="Allows the lookup to be reinitalized">

    </aura:method>

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

    <aura:attribute name="dropdownOver" type="Boolean" default="false" />

    <div aura:id="main-div" class=" slds-picklist slds-dropdown-trigger slds-dropdown-trigger--click ">

        <button class="slds-button slds-button--neutral slds-picklist__label" style="{!'width:' + v.width }" aria-haspopup="true" onclick="{!c.handleClick}" onmouseleave="{!c.handleMouseOutButton}">

            <span class="slds-truncate" title="{!v.infoText}">{!v.infoText}</span>

            <lightning:icon iconName="utility:down" size="small" class="slds-icon" />

        </button>

        <div class="slds-dropdown slds-dropdown--left" onmouseenter="{!c.handleMouseEnter}" onmouseleave="{!c.handleMouseLeave}">

            <ul class="{!'slds-dropdown__list slds-dropdown--length-' + v.dropdownLength}" role="menu">

                <aura:iteration items="{!v.options_}" var="option">

                    <li class="{!'slds-dropdown__item ' + (option.selected ? 'slds-is-selected' : '')}" role="presentation" onclick="{!c.handleSelection}" data-value="{!option.Name}" data-selected="{!option.selected}">

                        <a href="javascript:void(0);" role="menuitemcheckbox" aria-checked="true" tabindex="0">

                            <span class="slds-truncate">

                                <lightning:icon iconName="utility:check" size="x-small" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small" />

                                {!option.Name}

                            </span>

                        </a>

                    </li>

                </aura:iteration>

            </ul>
        </div>

    </div>

</aura:component>

Do not panic if your code is not getting save. Just follow the complete process and save code in the last. It will save successfully.

Step 6: Create lightning component controller “QFMultiSelectUICompController.js” and use below code.

({

    init: function(component, event, helper) {

        var values = helper.getSelectedValues(component);

        helper.setInfoText(component, values);

    },

 

    handleClick: function(component, event, helper) {

        var mainDiv = component.find('main-div');

        $A.util.addClass(mainDiv, 'slds-is-open');

    },

 

    handleSelection: function(component, event, helper) {

        var item = event.currentTarget;

        if (item && item.dataset) {

            var value = item.dataset.value;

            var selected = item.dataset.selected;

            var options = component.get("v.options_");

 

 

            //contro(ctrl) key ADDS to the list (unless clicking on a previously selected item)

            //also, ctrl key does not close the dropdown (uses mouse out to do that)

            if (event.ctrlKey) {

                options.forEach(function(element) {

 

                    if (element.Name === value) {

                        element.selected = selected === "true" ? false : true;

                    }

                });

            } else {

                options.forEach(function(element) {

                    if (element.Name === value) {

                        element.selected = selected === "true" ? false : true;

                    } else {

                        element.selected = false;

                    }

                });

                var mainDiv = component.find('main-div');

                $A.util.removeClass(mainDiv, 'slds-is-open');

            }

            component.set("v.options_", options);

 

            var values = helper.getSelectedValues(component);

            var labels = helper.getSelectedLabels(component);

 

            helper.setInfoText(component, labels);

            helper.despatchSelectChangeEvent(component, values);

 

        }

    },

 

    handleMouseLeave: function(component, event, helper) {

        component.set("v.dropdownOver", false);

        var mainDiv = component.find('main-div');

        $A.util.removeClass(mainDiv, 'slds-is-open');

    },

 

    handleMouseEnter: function(component, event, helper) {

        component.set("v.dropdownOver", true);

    },

 

    handleMouseOutButton: function(component, event, helper) {

        window.setTimeout(

            $A.getCallback(function() {

                if (component.isValid()) {

                    //if dropdown over, user has hovered over the dropdown, so don't close.

                    if (component.get("v.dropdownOver")) {

                        return;

                    }

                    var mainDiv = component.find('main-div');

                    $A.util.removeClass(mainDiv, 'slds-is-open');

                }

            }), 200

        );

    }

})

Step 7: Create lightning component helper “MultiSelectComponentHelper.js” and use below code.


({

    setInfoText: function(component, labels) {

        if (labels.length === 0) {

            component.set("v.infoText", "Select an option...");

        }

        if (labels.length === 1) {

            component.set("v.infoText", labels[0]);

        }

        else if (labels.length > 1) {

            component.set("v.infoText", labels.length + " options selected");

        }

    },

    

    getSelectedValues: function(component){

        var options = component.get("v.options_");

        console.log('options:='+options);

        var values = [];

        if(options!==undefined){

            options.forEach(function(element) {

                if (element.selected) {

                    values.push(element.Name);

                }

            });

        }

   return values;

    },

    

    getSelectedLabels: function(component){

        var options = component.get("v.options_");

        var labels = [];

        if(options!==undefined){

            options.forEach(function(element) {

                if (element.selected) {

                    labels.push(element.Name);

                }

            });  

        }

        

        return labels;

    },

    

    despatchSelectChangeEvent: function(component,values){

        var compEvent = component.getEvent("selectChange");

        compEvent.setParams({ "values": values });

        compEvent.fire();

    }

})

Now you will save the code but it will not save because we didn’t create event right now.

Let’s create event “SelectChange.evt”

Step 8: Create lightning event “SelectChange.evt” and use below code.


<aura:event type="COMPONENT" description="Despatched when a select has changed value" >

  <aura:attribute name="values" type="String[]" description="Selected values" access="global" />

</aura:event>

You can check – Salesforce consulting company
Salesforce implementation partner

About Author
Arun Garg
Arun Garg
Share this post on: