Tuesday, August 20, 2019

Custom search functionality in Lightning Web Component(lwc)

This post explains how to implement custom search functionality in Lightning web components(lwc).



Example

Apex Class
public inherited sharing class LWCExampleController {

    @AuraEnabled(Cacheable = true)
    public static list<Account> retriveAccs(String strAccName) {
        strAccName = '%' + strAccName + '%';
        list<Account> lstAccs = [SELECT  Id, Name, Industry, Phone, Type From Account WHERE Name LIKE :strAccName];

        if(lstAccs.isEmpty()) {
            throw new AuraHandledException('No Record Found..');
        }
        return lstAccs; 
    }
} 

CustomSearchInLWC.html
<template>
    <lightning-card title="Custom Search Functionality in LWC" icon-name="standard:account">
        <div if:true={errorMsg} style="margin-left: 3%;">
            <p style="color: red;">{errorMsg}</p>
        </div>

        <lightning-layout multiple-rows="true" vertical-align="end">
            <lightning-layout-item size="12" small-device-size="10" medium-device-size="8" large-device-size="6" padding="around-small">
                    <div class="slds-form-element">
                            <div class="slds-form-element__control">
                                    <lightning-input type="text" 
                                                     label="Enter Account Name" 
                                                     onchange={handleAccountName} ></lightning-input>
                            </div>
                        </div> 
            </lightning-layout-item>
            <lightning-layout-item size="12" small-device-size="2" medium-device-size="2" large-device-size="2" padding="around-small">
                    <lightning-button label="Search" 
                                      variant="brand" 
                                      onclick={handleSearch}></lightning-button>
                </lightning-layout-item>
            </lightning-layout><br/>

        <div if:true={searchData}>
            <lightning-datatable data={searchData} 
                                 columns={columns} 
                                 key-field="id"
                                 hide-checkbox-column="true"></lightning-datatable>
        </div>
    </lightning-card>

</template>

CustomSearchInLWC.js
import { LightningElement, track } from 'lwc';
import serachAccs from '@salesforce/apex/LWCExampleController.retriveAccs';

// datatable columns
const columns = [
    {
        label: 'Name',
        fieldName: 'AccName',
        type: 'url',
        typeAttributes: {label: { fieldName: 'Name' }, target: '_blank'}
    }, {
        label: 'Industry',
        fieldName: 'Industry',
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone',
    }, {
        label: 'Type',
        fieldName: 'Type',
        type: 'text'
    },
];
export default class CustomSearchInLWC extends LightningElement {
    @track searchData;
    @track columns = columns;
    @track errorMsg = '';
    strSearchAccName = '';
    

    handleAccountName(event) {
        this.strSearchAccName = event.detail.value;
    }

    handleSearch() {
        if(!this.strSearchAccName) {
            this.errorMsg = 'Please enter account name to search.';
            this.searchData = undefined;
            return;
        }

        serachAccs({strAccName : this.strSearchAccName})
        .then(result => {
            result.forEach((record) => {
                record.AccName = '/' + record.Id;
            });

            this.searchData = result;
            
        })
        .catch(error => {
            this.searchData = undefined;
            window.console.log('error =====> '+JSON.stringify(error));
            if(error) {
                this.errorMsg = error.body.message;
            }
        }) 
    }

}

CustomSearchInLEC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="CustomSearchInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Output

11 comments:

  1. Its nicely explained, thanks a lot. But while excuting the code i am getting below error

    error1 =====> TypeError: Cannot add property AccName, object is not extensible
    at eval (meetingHome.js:4)
    at Array.forEach ()
    at eval (meetingHome.js:4)

    Please let me know if u have faced it before.

    ReplyDelete
    Replies
    1. Yes , remove this result.forEach((record) => {
      record.AccName = '/' + record.Id;
      });
      and proceed .

      Delete
    2. Thanks Manish, with your suggestion the above code worked!
      serachAccs({strAccName : this.strSearchAccName})
      .then(result => {
      this.searchData = result;

      })
      .catch(error => {
      this.searchData = undefined;
      window.console.log('error =====> '+JSON.stringify(error));
      if(error) {
      this.errorMsg = error.body.message;
      }
      })

      Delete
    3. While executing this code, Name column values aren't visible. Remaining all working fine. Do you know why that happens?

      Delete
    4. I haven't changed the fieldName before(AccName to Name). Now name column is working fine.
      Thanks

      Delete
  2. Results are not being displayed even though log shows correct result being fetched...HELP!

    ReplyDelete
  3. Hi...I want to creat default opportunity Datatable I mean it's is showing default fields with out using wire method

    ReplyDelete
  4. not at all helpful, the code is not even working, giving error on "message"

    ReplyDelete
  5. how can we search a contact (firstname, lastname, email) in search bar. And using the same email to send an email to anyone.
    Can we add multiple email to send the email.

    ReplyDelete
  6. this code worked for me ! thank you so much!

    ReplyDelete