Tuesday, March 19, 2019

How to import third party libraries in Lightning Web Components(lwc)

This post explains how to import third-party libraries in lightning web components(lwc).

We can not directly import the third party scripts in Lightning web components because Security purpose Salesforce restrict the importing scripts from third-party content delivery sites like cdnjs, jsdelivr, etc

1.  First, you need to download the scripts from third-party sites.
2.  Then upload the scripts in static resources.

check below link how to import static resources in Lightning web components
https://www.salesforcecodecrack.com/2019/01/how-to-access-static-resources-in.html

Import methods from platformResourceLoader module.
Syntax
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';

platformResourceLoader have two methods loadStyle, and loadScript. For both methods return type is Promise.

To know more about Javascript promises to check below link.
Javascript Promise

loadScript(self, fileUrl): Promise
self—A reference to the component. The value must be this.
fileUrl—A string that contains the path to the JavaScript file. To build the string, concatenate the resourceName and the path to the file within the static resource archive.

loadStyle(self, fileUrl): Promise
self—A reference to the component. The value must be this.
fileUrl—A string that contains the path to the CSS file. To build the string, concatenate the resourceName and the path to the file within the static resource archive.

Note:
Promise.all() method combine all promises into a single promise.
To invoke the platformResourceLoader methods we use renderedCallback() or connectedCallback() Methods based on the Requirement.

Examples:
if you are importing single script or CSS Files use below code
For script
loadScript(this, resourceName + '/lib.js')
    .then(() => { /* callback */ });

for CSS Files
loadStyle(this, resourceName + '/lib.css')
    .then(() => { /* callback */ });

If you are importing multiple scripts use below code.
Promise.all([
    loadScript(this, resourceName + '/lib1.js'),
    loadScript(this, resourceName + '/lib2.js'),
    loadScript(this, resourceName + '/lib3.js')
]).then(() => { /* callback */ });


Demo

In this Demo, I am importing two different third-party scripts, Jquery script, and CSS File.
thirdPartyLibraryDemo.html
<template>
    <lightning-card title="Third Party Library Demo" icon-name="custom:custom19">
        <p><b style="color:blue;">{successMessage}</b></p>
    </lightning-card>
</template>

thirdPartyLibraryDemo.js
import { LightningElement, track } from 'lwc';
// importing leaflet library from static resource
import leafletResource from '@salesforce/resourceUrl/leaflet';
// importing chartJS Library from static resource
import chartJSResource from '@salesforce/resourceUrl/chartJS';
// importing jquery library  from static resource
import jqueryResource from '@salesforce/resourceUrl/Jquery331';
// importing resource loader
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
// imported for to show toast messages
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class ThirdPartyLibraryDemo extends LightningElement {
    @track error;
    @track successMessage = '';

    renderedCallback() { // invoke the method when component rendered or loaded
        Promise.all([
            loadStyle(this, leafletResource +'/leaflet.css'), // CSS File
            loadScript(this, leafletResource + '/leaflet.js'),  // leaflet js file
            loadScript(this, chartJSResource + '/Chart.min.js'), // chart js file
            loadScript(this, jqueryResource), // jquery script
        ])
        .then(() => { 
            this.error = undefined;
            // Call back function if scripts loaded successfully
            this.showSuccessMessage();
        })
        .catch(error => {
            this.error = error;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error!!',
                    message: error.message,
                    variant: 'error',
                }),
            );
        });
       
    }
    showSuccessMessage() { // call back method 
       this.successMessage = 'Scripts are loaded successfully!!';
       alert('Scripts are loaded successfully!!!');
    }
}

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

Result

Saturday, March 16, 2019

Accordion component Lightning web components(lwc)

This post explains how to create the accordion component in Lightning web components(lwc)

Demo
accordinLWCDemo.html
<template>
    <lightning-card title="Accordin Example">
        <template if:true={accounts}>
            <!-- accordion component with muliple sectio open -->
        <lightning-accordion allow-multiple-sections-open>
            <template for:each={accounts} for:item="acc" for:index="indexVar">
                <lightning-accordion-section key={acc.Id} name={acc.Name} label={acc.Name}>
                    <p><b>Id</b> : {acc.Id}</p>
                    <p><b>AccountNumber</b> : {acc.AccountNumber}</p>
                    <p><b>Phone</b> : {acc.Phone}</p>
                    <p><b>Industry</b> : {acc.Industry}</p>
                    <p><b>CreatedDate</b> : {acc.CreateDate}</p>
                    <p><b>Type</b> : {acc.Type}</p>
                    <p><b>Rating</b> : {acc.Rating}</p>
                </lightning-accordion-section>
            </template>
        </lightning-accordion>
        </template>
    </lightning-card>
</template>

accordinLWCDemo.js
import { LightningElement, track, wire } from 'lwc';
// importing apex class method to get the accounts
import retriveAccounts  from '@salesforce/apex/LWCExampleController.getAccounts';
// imported to show toast messages
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

export default class AccordinLWCDemo extends LightningElement {
    @track accounts;

    // wire service to fetch the slesforce data
    @wire(retriveAccounts)
    wiredAccount({ error, data }) {
        if(data) {
            this.accounts = data;
            this.error = undefined;
        }
        else if(error) {
            this.error = error;
            this.accounts = undefined;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error!!',
                    message: error.message,
                    variant: 'error',
                }),
            );
        }
    }
}

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

Result

Wednesday, March 13, 2019

dual list box component in Lightning Web Components(lwc)

This post explains how to create a dual list box in lightning web components(lwc)

Demo
dualListBoxLWCDemo.html
<template>
    <lightning-card title="Dual List Box Example" icon-name="custom:custom43">
        <template if:true={IndustryValues.data}>
            <lightning-dual-listbox name="Industries"
                                    label="Select Industries"
                                    source-label="Available"
                                    selected-label="Selected"
                                    field-level-help="This is a dual listbox"
                                    options={IndustryValues.data.values}
                                    onchange={handleChange}></lightning-dual-listbox>
        </template><br/>
    <div class="slds-box" >
        <p>Selected values are: <b style="color:blue;">{selected}</b></p>
    </div>
</lightning-card>
</template>

dualListBoxLWCDemo.js
import {LightningElement, track, 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';

export default class DualListBoxLWCDemo extends LightningElement {
    @track _selected = []; // this array tracks the seleted values

    // Getting Account Object info using wire service
    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    objectInfo;

    // Getting Pickvalues based on default recordtype using wire service
    @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: INDUSTRY_FIELD})
    IndustryValues;

    // assigning none if you are not seleted any values
    get selected() {
        return this._selected.length ? this._selected : 'none';
    }

    // Handling the change event
    handleChange(event) {
        this._selected = event.detail.value;
    }
}

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

Result

File upload component in lightning web components(lwc)

This post explains how to use file upload in lighting web component(lwc)

lightning-file-upload component provides an easy and integrated way for users to upload multiple files. The file uploader includes drag-and-drop functionality and filtering by file types.

Demo
fileUploadLWCdemo.html
<template>
    <lightning-card title='File Uploadr' icon-name="custom:custom19">
        <lightning-file-upload
                label="Attach receipt"
                name="fileUploader"
                accept={acceptedFormats}
                record-id={recordId}
                onuploadfinished={handleUploadFinished}
                multiple>
            </lightning-file-upload>
    </lightning-card>
</template>

fileUploadLWCdemo.js
import { LightningElement, api } from 'lwc';
// imported to show toast messages
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

export default class FileUploadLWCdemo extends LightningElement {
    @api
    recordId;
    // accepted parameters
    get acceptedFormats() {
        return ['.pdf', '.png','.jpg','.jpeg'];
    }
    handleUploadFinished(event) {
        let strFileNames = '';
        // Get the list of uploaded files
        const uploadedFiles = event.detail.files;

        for(let i = 0; i < uploadedFiles.length; i++) {
            strFileNames += uploadedFiles[i].name + ', ';
        }
        this.dispatchEvent(
            new ShowToastEvent({
                title: 'Success!!',
                message: strFileNames + ' Files uploaded Successfully!!!',
                variant: 'success',
            }),
        );
    }
}

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

Result

Sunday, March 10, 2019

How to fetch Picklist values in Lightning Web Components(lwc)

This post explains how to fetch picklist values in Lightning web components(lwc)

use getPicklistValues wire adapter to fetch picklist values for a specified field.

Parameters:

recordTypeId—(Required) The ID of the record type. Use the Object Info defaultRecordTypeId property, which is returned from getObjectInfo or getRecordUi.
fieldApiName—(Required) The API name of the picklist field on a supported object.
propertyOrFunction—A private property or function that receives the stream of data from the wire service. If a property is decorated with @wire, the results are returned to the property’s data property or error property. If a function is decorated with  @wire, the results are returned in an object with a data property and an error property.

Demo:
PicklistValuesDemo.html
<template>
    <lightning-card title="Account PicklistValues">
        <template if:true={IndustryPicklistValues.data}>
            <lightning-combobox name="progress"
                                label="Industry"
                                value={value}
                                placeholder="-Select-"
                                options={IndustryPicklistValues.data.values}
                                onchange={handleChange} >
            </lightning-combobox>
      </template><br/>
      you selected industry: <b>{value}</b><br/><br/>
      <template if:true={IndustryPicklistValues.data}>
        Account Type: <br/>
        <template for:each={TypePicklistValues.data.values} for:item="item">
            <lightning-input
                placeholder="Account Type"
                key={item.value}
                label={item.label}
                data-value={item.value}
                type="checkbox"></lightning-input>
        </template>
    </template>
    </lightning-card>
</template>

PicklistValuesDemo.js
import { LightningElement, track, 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 Type_FIELD from '@salesforce/schema/Account.Type';

export default class PicklistValuesDemo extends LightningElement {
    @track value;

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

    @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: Type_FIELD})
    TypePicklistValues;

    @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: INDUSTRY_FIELD})
    IndustryPicklistValues;

    handleChange(event) {
        this.value = event.detail.value;
    }
}

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

Result


Resource
getPicklistvalues

Saturday, March 9, 2019

How to access apex class properties in lightning components

This post explains how to access apex class properties in the lightning component.

Example:
Lightning Component
<aura:component controller="LightningDemoController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global" >
    <aura:attribute name="objClass" type="LightningDemoController" />
    
    <aura:handler name="init" value="{!this}" action="{!c.getAccRecors}" />
    
     <!-- Notification Library to show notices and toast messages-->
    <lightning:notificationsLibrary aura:id="notifLib"/>
    
    <lightning:card title="Account Records">
        <p>
         User Name: <b>{!v.objClass.strUserName}</b>
        </p><br/>
        <table class="slds-table slds-table--bordered slds-table--cell-buffer">
            <thead>
                <tr class="slds-text-title--caps">
                    <th scope="col">
                        <div class="slds-truncate" title="Id">Id</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Name">Name</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Industry">Industry</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Phone">Phone</div>
                    </th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.objClass.lstAccs}" var="ac">
                    <tr>
                        <th scope="row">
                            <div class="slds-truncate" title="{#ac.Id}">{!ac.Id}</div>
                        </th>
                        <th scope="row">
                            <div class="slds-truncate" title="{#ac.Name}">{!ac.Name}</div>
                        </th>
                        <th scope="row">
                            <div class="slds-truncate" title="{#ac.Industry}">{!ac.Industry}</div>
                        </th>
                        <th scope="row">
                            <div class="slds-truncate" title="{#ac.Phone}">{!ac.Phone}</div>
                        </th>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>
    </lightning:card>
</aura:component>

Lightning Component Controller
({
    getAccRecors : function(component, event, helper) {
        var action = component.get('c.retriveAccInfo');
        action.setCallback(this, function(response) {
            if(response.getState() === 'SUCCESS') {
                var result = response.getReturnValue();
                component.set('v.objClass', result); 
                if(result.lstAccs) {
                    component.find('notifLib').showToast({
                        "variant": "success",
                        "title": "Success!",
                        "message": "Account Retrived successfully."
                    });
                }
            }
        });
        $A.enqueueAction(action);
    }
})

Apex Class
public inherited sharing class LightningDemoController {
    @AuraEnabled public String strUserName {get;set;}
    @AuraEnabled public list<Account> lstAccs {get;set;}

    @AuraEnabled
    public static LightningDemoController retriveAccInfo() {
        LightningDemoController obj = new LightningDemoController();
        obj.strUserName = UserInfo.getName();
        obj.lstAccs = [SELECT Id, Name, Industry, Phone FROM Account limit 10];
        return obj;
    }
}

Result