Showing posts with label Salesforce. Show all posts
Showing posts with label Salesforce. Show all posts

Friday, January 12, 2024

Lightning Record Picker in Salesforce

The lightning-record-picker component allows you to search for a list of Salesforce Records that match search input. It uses the GraphQL wire adapter to search for records, displays the records, and allows the user to select a record.

 Ex:

HTML

<template>
	<lightning-card title="Lightning Record Picker" icon-name="standard:account">
	<lightning-record-picker label="Select Account" 
							 onchange={handleRecordChange} 
							 placeholder="Search Accounts..." 
							 object-api-name="Account"
							 display-info={displayInfo}>
		</lightning-record-picker>
		<template lwc:if={selectedRecordId}>Selected Record Id: {selectedRecordId}</template>
	</lightning-card>
</template>
JS

import { LightningElement } from 'lwc';

export default class RecordPicker extends LightningElement {
    selectedRecordId;

    displayInfo = {
        additionalFields: ['Phone', 'Industry']
    }
    handleRecordChange(event) {
        this.selectedRecordId = event.detail.recordId;
    }
}



Thursday, January 11, 2024

Dynamically detect the running context in salesforce using Apex

In the salesforce, the Request class provides a few methods among them we do have a getQuiddity () method that returns an enum(System.Quiddity) specifying the context of the origin of this request. 

Ex:

Quiddity contextInfo = Request.getCurrent().getQuiddity();
switch on contextInfo {
    when VF {
        system.debug('Visualforce');         
    } when AURA {
        system.debug('AURA');       
    } when FUTURE, SCHEDULED, QUEUEABLE, BATCH_APEX {
        system.debug('async context');        
    } when INVOCABLE_ACTION {
        system.debug('FLOW'); 
    } when ANONYMOUS {
        system.debug('ANONYMOUS');
    } when REST {
        system.debug('REST');        
    }
}
For Reference 

Wednesday, August 9, 2023

How to convert timestamp to datetime using apex in salesforce

 Sample Code:

String timestamp = '2023-08-07T14:53:49Z';
timestamp = timestamp.replace('T', ' ');
System.debug('Datetime ==> '+DateTime.valueOf(timestamp));

Screenshot:




Tuesday, January 3, 2023

Dynamic popup/modal using Lightning-modal in Lightning Web Components(LWC)

This post explains how to open the popup using Lightning web components (LWC).

  • Created the lwcmodal component this component has the lighting modal base components to open the popup/modal.
  • import LightningModal from lightning/modal. The component has access to the normal LWC resources as well as the special container, helper components, methods, and events of the lightning/modal module.

LWCModal Component

lwcmodal.html

<template>
	<lightning-modal-header label={label}></lightning-modal-header>
	<lightning-modal-body>
		<lightning-datatable key-field="id" data={conData} columns={columns}>
		</lightning-datatable>
	</lightning-modal-body>
	<lightning-modal-footer>
		<lightning-button variant="brand" label="OK" onclick={handleOkay}></lightning-button>
	</lightning-modal-footer>
</template>

lwcmodal.js

import { api } from 'lwc';
import LightningModal from 'lightning/modal';

export default class Lwcmodal extends LightningModal {
    @api conData;
    @api columns;
    @api label;

    handleOkay(event) {
        this.close('okay');
    }
}

  • LightningModal provides a .open() method which opens a modal and returns a promise that asynchronously resolves with the result of the user’s interaction with the modal.
  • Use this.close(result) to close the modal, where the result is anything you want to return from the modal. The .close() operation is asynchronous to display a brief fade-out animation before the modal is destroyed. The result data can’t be modified after the close operation begins.
The .open() method lets you assign values to the modal's properties. LightningModal provides these properties.

label - Required. Sets the modal's title and assistive device label. If the modal has a header, set the label in the lightning-modal-header component. If the modal doesn't have a header, set the label property when opening the modal.

size - Determines how much of the viewport width the modal uses. Supported values are small, medium, and large, which you can set when you open the modal. The default value is medium. The length of the modal is determined by the amount of content.

description - Sets the modal's accessible description. It uses the aria-description attribute where supported, or falls back to aria-describedby. If you set a custom description value, include the label name at the beginning of your description, because some screen readers only read the description and not the label.

disableClose - Prevents closing the modal by normal means like the ESC key, the close button, or .close(). For example, you could briefly set disableClose to true while a completed form is saving, so the user doesn't dismiss the modal early.

dynamicmodal.html
<template>
    <lightning-card  variant="Narrow">
        <p class="slds-p-horizontal_small">When clicking the button it opens the dynamic modal.<br/>
            <lightning-button variant="brand" onclick={handleContactData} label="Show Contact Data"></lightning-button>
        </p>
    </lightning-card>
</template>
dynamicmodal.js
import { LightningElement } from 'lwc';
import MyModal from "c/lwcmodal";
import getContacts from '@salesforce/apex/LWCExampleController.getContacts';

export default class Dynamicmodal extends LightningElement {
    consData;

    columns = [
        { label: 'First Name', fieldName: 'FirstName', type:'text' },
        { label: 'Last Name', fieldName: 'LastName', type: 'text' },
        { label: 'Name', fieldName: 'Name', type: 'text' },
        { label: 'Email', fieldName: 'Email', type: 'email' },
    ];
    connectedCallback() {
        getContacts().then(res => {
            console.log('res => ', res);
            this.consData = res;
        })
            .catch(error => {
                console.log('error => ', error);
            });
    }

    async handleContactData() {
        const result = await MyModal.open({
            label: 'Contact Data',
            size: 'large',
            columns: [...this.columns],
            conData : [...this.consData]
        });
        // if modal closed with X button, promise returns result = 'undefined'
        // if modal closed with OK button, promise returns result = 'okay'
        console.log('result ==> ',result);
    }
}
Apex class
public inherited sharing class LWCExampleController {

    @AuraEnabled(Cacheable = true)
    public static List<Contact> getContacts() {
        return [SELECT Id, Name, FirstName, LastName, Email 
                FROM Contact 
                WHERE Email != null 
                ORDER BY CreatedDate DESC NULLS LAST limit 10];
    }
}
Example




Wednesday, November 3, 2021

Dynamically Add/Remove rows using Lightning Web Components(LWC)

 This post explains how to add/remove the rows using the Lighting web component(LWC).

HTML Code:

<template>
   <lightning-card>
      <lightning-spinner if:true={isSpinner} variant="brand" size="large"> </lightning-spinner>
      <lightning-layout>
         <lightning-layout-item size="12">
            <lightning-button class="slds-float--right slds-m-around_small" variant="brand" label="Save"
               onclick={saveRows}>
            </lightning-button>
            <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-border_left slds-border_right"
               aria-labelledby="element-with-table-label other-element-with-table-label">
               <thead>
                  <tr>
                     <th>Name</th>
                     <th>Industry</th>
                     <th>Phone</th>
                     <th>Email</th>
                     <th></th>
                  </tr>
               </thead>
               <tbody>
                  <template for:each={filterList} for:item="filterData" for:index="index">
                     <tr key={filterData}>
                        <td>
                           <lightning-input type="text" name="accName" data-index={index}
                              variant="label-hidden" placeholder="" onchange={handleChange}
                              value={filterData.Name}>
                           </lightning-input>
                        </td>
                        <td>
                           <lightning-combobox name="industry" data-index={index} variant="label-hidden"
                              placeholder="" onchange={handleChange} value={filterData.Industry}
                              options={industryOptions}>
                           </lightning-combobox>
                        </td>
                        <td>
                           <lightning-input type="text" name="accEmail" data-index={index}
                              variant="label-hidden" placeholder="" onchange={handleChange}
                              value={filterData.Email}>
                           </lightning-input>
                        </td>
                        <td>
                           <lightning-input type="text" name="accPhone" data-index={index}
                              value={filterData.Phone} variant="label-hidden" onchange={handleChange}>
                           </lightning-input>
                        </td>
                        <td>
                           <lightning-button-icon data-index={filterData.id} class="slds-float--right"
                              icon-name="action:new" onclick={handleAddRow}></lightning-button-icon>
                           <lightning-button-icon data-index={filterData.id} class="slds-float--right"
                              icon-name="action:delete" onclick={handleRemoveRow}></lightning-button-icon>
                        </td>
                     </tr>
                  </template>
               </tbody>
            </table>
         </lightning-layout-item>
      </lightning-layout>
   </lightning-card>
</template>

JS Code:
import { LightningElement, wire } from 'lwc';
import { getPicklistValues } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import saveAccounts from '@salesforce/apex/LWCExampleController.saveAccounts';

export default class DynamicallyAddRow extends LightningElement {
    industryOptions = [{ value: '-None-', label: '' }];
    filterList = [];
    keyIndex = 0;
    isSpinner = false;

    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    accountinfo;

    @wire(getPicklistValues, { recordTypeId: '$accountinfo.data.defaultRecordTypeId', fieldApiName: INDUSTRY_FIELD })
    industryValues({ data, error }) {
        if (data) {
            data.values.forEach(val => {
                this.industryOptions = [...this.industryOptions, { value: val.value, label: val.label }];
            });
        }
        else if (error) {
            this.processErrorMessage(error);
        }
    }

    connectedCallback() {
        this.handleAddRow();
    }

    handleChange(event) {
        if (event.target.name == 'accName') {
            this.filterList[event.currentTarget.dataset.index].Name = event.target.value;
        }
        else if (event.target.name == 'industry') {
            this.filterList[event.currentTarget.dataset.index].Industry = event.target.value;
        }
        else if (event.target.name == 'accEmail') {
            this.filterList[event.currentTarget.dataset.index].Email = event.target.value;
        }
        else if (event.target.name == 'accPhone') {
            this.filterList[event.currentTarget.dataset.index].Phone = event.target.value;
        }
    }

    handleAddRow() {
        let objRow = {
            Name: '',
            Industry: '',
            Phone: '',
            Email: '',
            id: ++this.keyIndex
        }

        this.filterList = [...this.filterList, Object.create(objRow)];
    }

    handleRemoveRow(event) {
        this.filterList = this.filterList.filter((ele) => {
            return parseInt(ele.id) !== parseInt(event.currentTarget.dataset.index);
        });

        if (this.filterList.length == 0) {
            this.handleAddRow();
        }
    }

    saveRows() {
        console.log('this.filterList => ', this.filterList);
        this.isSpinner = true;
        saveAccounts({ lstAccs: this.filterList }).then(result => {
            this.isSpinner = false;
            this.showToastMessage('success', 'Accounts Saved Successfully!!', 'Success');
            this.filterList = [];
            if (this.filterList.length == 0) {
                this.handleAddRow();
            }
            console.log('result ==> ', result);
        }).catch(error => {
            this.processErrorMessage(error);
            this.isSpinner = false;
        })
    }

    processErrorMessage(message) {
        let errorMsg = '';
        if (message) {
            if (message.body) {
                if (Array.isArray(message.body)) {
                    errorMsg = message.body.map(e => e.message).join(', ');
                } else if (typeof message.body.message === 'string') {
                    errorMsg = message.body.message;
                }
            }
            else {
                errorMsg = message;
            }
        }
        this.showToastMessage('error', errorMsg, 'Error!');
    }

    showToastMessage(variant, message, title) {
        this.dispatchEvent(
            new ShowToastEvent({
                title: title,
                message: message,
                variant: variant
            })
        );
    }
}

Apex Class:
public inherited sharing class LWCExampleController {

    @AuraEnabled
    public static List<Account> saveAccounts(List<Account> lstAccs) {
        try {
            insert lstAccs;
            return lstAccs;
        }
        catch(Exception ex) {
            throw new AuraHandledException(ex.getMessage());
        }
    }
}
Output:


Saturday, June 19, 2021

How to get Community Id and base path in lighting web components(lwc)

This post explains how to get community Id and base path in lightning web components(lwc)

HTML Code

<template>
    <lightning-card>
        <div class="slds-text-heading_medium slds-text-align_center">
            <b>Community Id:</b> {currentcommunityId}
        </div>
        <div class="slds-text-heading_medium slds-text-align_center">
            <b>Community Basepath:</b> {currentcommunityBasePath}
        </div>
    </lightning-card>
</template>

Javascript Code

import {LightningElement, api, track, wire} from 'lwc';
 
// We can get the community Id for use in the callout
import communityId from '@salesforce/community/Id';
 
// Get the base path for navigating to non-named pages
import communityBasePath from '@salesforce/community/basePath';

export default class CommunityName extends LightningElement {

    currentcommunityId;
    currentcommunityBasePath;

    connectedCallback() {
        this.currentcommunityId = communityId;
        this.currentcommunityBasePath = communityBasePath;
    }

}
Configuration File

<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
	<apiVersion>52.0</apiVersion>
	<isExposed>true</isExposed>
	<targets>
		<target>lightning__RecordPage</target>
		<target>lightningCommunity__Page</target>
		<target>lightningCommunity__Default</target>
	</targets>
</LightningComponentBundle>
Output



Saturday, May 1, 2021

LeadStaus Object in Salesforce

 LeadStatus object Represents the status of a Lead, such as Open, Qualified, or Converted.

SOQL Query

select id, MasterLabel, IsConverted, IsDefault from Leadstatus

Result



Dynamic Search/Custom Search functionality in Lightning Web Components(lwc)

 HTML Code

<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>

JS Code

import { LightningElement } from 'lwc';
import serachAccs from '@salesforce/apex/LWCExamples.retriveAccs';

const columns = [
    {
        label: 'Name',
        fieldName: 'Name'
    }, {
        label: 'Industry',
        fieldName: 'Industry',
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone',
    }, {
        label: 'Type',
        fieldName: 'Type',
        type: 'text'
    },
];

export default class DynamicSearchInLWC extends LightningElement {

    searchData;
    columns = columns;
    errorMsg = '';
    strSearchAccName = '';
    

    handleAccountName(event) {
        this.errorMsg = '';
        this.strSearchAccName = event.currentTarget.value;
    }

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

        serachAccs({strAccName : this.strSearchAccName})
        .then(result => {
            this.searchData = result;
        })
        .catch(error => {
            this.searchData = undefined;
            if(error) {
                if (Array.isArray(error.body)) {
                    this.errorMsg = error.body.map(e => e.message).join(', ');
                } else if (typeof error.body.message === 'string') {
                    this.errorMsg = error.body.message;
                }
            }
        }) 
    }
}

Apex Class

public inherited sharing class LWCExamples {
 
    @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; 
    }
}

Result



Thursday, February 4, 2021

jQuery Datatable in Lightning Web Component(lwc)

This post explains how to use jquery data tables in the lightning web component(lwc).


Prerequisites:

Step 1 : Download Required Resources 

1. Download jQuery DataTables Plugin

Click on the following link to download the DataTables library. [version 1.10.18]


This zip file includes CSS, javascript, and other files related to the plugin.

2. Download jQuery library [version 3.3.1 Recommended]

Click on the following link to download JQuery 3.3.1 minified version. [3.3.1 Recommended]


Step 2: Upload Files to static resource

upload files to static resourecs



Demo:

HTML Code:
<template>
   <lightning-card title="JQuery Datatable Demo">
      <div class="slds-m-around_medium">
         <table lwc:dom="manual"
            class="tableClass slds-table slds-table_cell-buffer slds-table_bordered" 
            style="width:100%">
         </table>
      </div>
   </lightning-card>
</template>
JS Code:
import {
    LightningElement
} from 'lwc';
import dataTableResource from '@salesforce/resourceUrl/DataTableDemo';
import JqueryResource from '@salesforce/resourceUrl/Jquery331';
import {
    loadScript,
    loadStyle
} from 'lightning/platformResourceLoader';
import {
    ShowToastEvent
} from 'lightning/platformShowToastEvent';
// import toast message event .

// import apex class and it's methods.
import getAccounts from '@salesforce/apex/LWCExampleController.getAccounts';

export default class JqueryDataTableLWCDemo extends LightningElement {
    accounts = [];
    error;

    async connectedCallback() {
        await this.fetchAccoutns();

        Promise.all([
            loadScript(this, JqueryResource),
            loadScript(this, dataTableResource + '/DataTables-1.10.18/js/jquery.dataTables.min.js'),
            loadStyle(this, dataTableResource + '/DataTables-1.10.18/css/jquery.dataTables.min.css'),
        ]).then(() => {
            console.log('script loaded sucessfully');

            const table = this.template.querySelector('.tableClass');
            const columnNames = ['Name', 'Industry', 'Type', 'Phone', 'Rating'];
            let tableHeaders = '<thead> <tr>';
            columnNames.forEach(header => {
                tableHeaders += '<th>' + header + '</th>';
            });
            tableHeaders += '</tr></thead>';
            table.innerHTML = tableHeaders;

            let jqTable = $(table).DataTable();
            $('div.dataTables_filter input').addClass('slds-input');
            $('div.dataTables_filter input').css("marginBottom", "10px");

            this.accounts.forEach(rec => {
                let tableRows = [];
                tableRows.push('<a href="/lightning/r/Account/' + rec.Id + '/view">' + rec.Name + '</a>');
                tableRows.push(rec.Industry != undefined ? rec.Industry : '');
                tableRows.push(rec.Type != undefined ? rec.Type : '');
                tableRows.push(rec.Phone != undefined ? rec.Phone : '');
                tableRows.push(rec.Rating != undefined ? rec.Rating : '');
                jqTable.row.add(tableRows);
            });
            jqTable.draw();

        }).catch(error => {
            this.error = error;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error!!',
                    message: JSON.stringify(error),
                    variant: 'error',
                }),
            );
        });
    }

    async fetchAccoutns() {
        await getAccounts()
            .then(data => {
                if (data) {
                    this.accounts = data;
                }
            })
            .catch(error => {
                this.error = error;
                this.accounts = undefined;
                this.error = 'Unknown error';
                if (Array.isArray(error.body)) {
                    this.error = error.body.map(e => e.message).join(', ');
                } else if (typeof error.body.message === 'string') {
                    this.error = error.body.message;
                }
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error!!',
                        message: error,
                        variant: 'error',
                    }),
                );
            });
    }
}
Apex Class
public inherited sharing class LWCExampleController {
	@AuraEnabled(Cacheable = true)
	public static List<Account> getAccounts(){
	  return [SELECT Id, Name,Industry, Type, Phone, Rating, AccountNumber FROM Account ORDER BY Name];
	}
}

Tuesday, February 2, 2021

Custom Spinner in Lightning Web Component(lwc)

 This post explains how to create a custom spinner in lightning web components(lwc)

HTML Code

<template>
   <lightning-card>
      <div align="center"  if:true={isSpinner}>
         <div class="loader"></div>
         Please wait...
      </div>
      <div align="center" if:true={showButon}>
         <lightning-button label="Enable Spinner" variant="brand" onclick={enableSpinner}>
         </lightning-button>
      </div>
   </lightning-card>
</template>

JS Code

import {
    LightningElement
} from 'lwc';
export default class Customspinner extends LightningElement {
    isSpinner = false;
    showButon = true;

    enableSpinner() {
        if (!this.isSpinner) {
            this.isSpinner = true;
            this.showButon = false;
        }
    }
}
CSS Code
.loader {
  border: 5px solid #f3f3f3;
  border-radius: 50%;
  border-top: 5px solid #3498db;
  width: 60px;
  height: 60px;
  -webkit-animation: spin 2s linear infinite; /* Safari */
  animation: spin 2s linear infinite;
}

/* Safari */
@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
Output