How to Create a Multi-Select with Lightning-Record-Picker in Salesforce LWC

Nagendra SinghNagendra Singh
4 min read

Are you tired of the limitations of the standard Salesforce lightning-record-picker component, and you want more flexibility to select multiple records at once? Well, you're in luck! In this blog, I am going to show you how to extend the lightning-record-picker component to create a multi-select record picker that allows you to pick multiple Salesforce records efficiently. We'll also use a lightning-pill-container to display the selected records in a user-friendly manner.

Why Extend the lightning-record-picker?

The default lightning-record-picker component is great for single-record selection, but there are times when you need to select multiple records, such as selecting multiple accounts or contacts for an action. Instead of creating an entirely new component from scratch, enhancing the lightning-record-picker with multi-select capabilities saves time and offers a consistent user experience.

Overview of What We'll Build

In this tutorial, we will:

  • Enhance lightning-record-picker to allow multiple selections.

  • Use lightning-pill-container to display selected records, making it easy for users to visualize their choices.

  • Use GraphQL to fetch record data and handle the process efficiently.

Let's Get Started

We'll start with a simple HTML structure that combines the lightning-record-picker and lightning-pill-container components. Then, we will implement the logic to allow the user to select multiple records and display them as pills. Let's dive in!

HTML Code

Here is the HTML file for the component (multiLightningRecordPicker.html). We will use lightning-record-picker for searching and selecting accounts and lightning-pill-container to display the selected records.

<!--
 - Created by Nagendra on 19-11-2024.
 -->

<!-- Multi Lightning Record Picker -->
<template>
    <lightning-record-picker
            label="Accounts"
            placeholder="Search Accounts..."
            object-api-name="Account"
            onchange={handleRecordSelection}
    >
    </lightning-record-picker>

    <lightning-pill-container items={items} onitemremove={handleItemRemove}></lightning-pill-container>

</template>

Explanation:

  • The lightning-record-picker is configured to search for Account records.

  • The lightning-pill-container will show the selected accounts, and users will be able to remove selected accounts.

JavaScript Code

Now let's move on to the JavaScript part (MultiLightningRecordPicker.js). This is where the logic for adding selected records and clearing selections is implemented.

/**
 * Created by Nagendra on 19-11-2024.
 */

import {LightningElement, track, wire} from 'lwc';
import { gql, graphql } from 'lightning/uiGraphQLApi';

export default class MultiLightningRecordPicker extends LightningElement {

    @track items = [];
    selectedRecordId = '';

    get variables() {
        return {
            selectedRecordId: this.selectedRecordId
        };
    }

    handleRecordSelection(event) {
        this.selectedRecordId = event.detail.recordId;
    }

    @wire(graphql, {
        query: gql`
            query searchAccount($selectedRecordId: ID) {
                uiapi {
                    query {
                        Account(
                            where: { Id: { eq: $selectedRecordId } }
                            first: 1
                        ) {
                            edges {
                                node {
                                    Id
                                    Name {
                                        value
                                    }
                                }
                            }
                        }
                    }
                }
            }
        `,
        variables: '$variables'
    })
    wiredGraphQL({ data, errors }) {
        this.selectedRecordId = null;
        if (errors || !data || (data && data?.uiapi?.query?.Account?.edges?.length < 1)) {
            return;
        }
        const graphqlResults = data.uiapi.query.Account.edges.map((edge) => ({
            Id: edge.node.Id,
            Name: edge.node.Name.value
        }));

        const accountData = graphqlResults?.[0];
        // Check if the account is already in the list
        if (!this.items.some(item => item.name === accountData.Id)) {
            this.items = [
                ...this.items,
                {
                    label: accountData.Name,
                    name: accountData.Id
                }
            ];
        }

        const recordPicker = this.template.querySelector('lightning-record-picker');

        if (recordPicker) {
            recordPicker.clearSelection();
        }
    }

    handleItemRemove(event) {
        const itemName = event.detail.item.name;

        // Remove the item using filter to create a new array and trigger reactivity
        this.items = this.items.filter(item => item.name !== itemName);
    }
}

Explanation:

  1. State Management (@track items): The items array is used to track the list of selected records. The @track decorator allows the UI to react to changes in this array.

  2. Handling Record Selection:

    • handleRecordSelection() is called when a record is selected in the record picker. The selected record's ID is saved in selectedRecordId.
  3. GraphQL Query:

    • The graphql function is used to query the selected account's details, such as Id and Name. This is then added to the items array.

    • After adding the selected item, the clearSelection() method is used to reset the picker.

  4. Removing Items:

    • handleItemRemove() removes a selected record from the pill container when the user clicks the remove icon on the pill.

Summary

By enhancing the lightning-record-picker, you get all the benefits of the standard picker plus multi-select capabilities, which is especially useful in scenarios requiring users to select multiple records quickly. The lightning-pill-container makes the UI clean and intuitive for users, providing a seamless experience.

The code shared above should be enough to create your own multi-select record picker for Salesforce. Feel free to modify it for different objects or add additional features to suit your use case.

Demo

0
Subscribe to my newsletter

Read articles from Nagendra Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nagendra Singh
Nagendra Singh

Allow me to introduce myself, the Salesforce Technical Architect who's got more game than a seasoned poker player! With a decade of experience under my belt, I've been designing tailor-made solutions that drive business growth like a rocket launching into space. ๐Ÿš€ When it comes to programming languages like JavaScript and Python, I wield them like a skilled chef with a set of knives, slicing and dicing my way to seamless integrations and robust applications. ๐Ÿฝ๏ธ As a fervent advocate for automation, I've whipped up efficient DevOps pipelines with Jenkins, and even crafted a deployment app using AngularJS that's as sleek as a luxury sports car. ๐ŸŽ๏ธ Not one to rest on my laurels, I keep my finger on the pulse of industry trends, share my wisdom on technical blogs, and actively participate in the Salesforce Stackexchange community. In fact, this year I've climbed my way to the top 3% of the rankings! ๐Ÿง—โ€โ™‚๏ธ So, here's to me โ€“ your humor-loving, ultra-professional Salesforce Technical Architect! ๐Ÿฅณ