Tuesday 28 April 2020

Drag and Drop functionality in Lightning Web Component

Hi,

Here we are going to learn how to achieve drag and drop functionality in Lightning Web Component.

Its very simple if we understand the following things.


draggable:

It is an attribute to make an element draggable by setting the value as "true".

Drag and Drop Events:

ondragstart:
It fires when the user starts dragging of the object.

ondrop:
The drop event is fired on the element where the drop occurred at the end of the drag operation.

ondragover:
This event is fired as the mouse is moved over an element when a drag is occurring. Much of the time, the operation that occurs during a listener will be the same as the dragenter event.

How to set the data on drag:

dataTransfer.setData(format,value Of the dragged Data)

How to get the data on drop:
event.dataTransfer.getData(“format");

preventDefault()

it is a method of "event" object to prevent browser default handling of the data(default is open as a link on the drop)

Eg;

Let's have 2 LWC components
1)dragger_component - from where we drag the element

,2)drop_component  - the location which we want to drop

3)Accountcls - apex class which returns account records

Please follow links for source code (GitHub(Salesforce Techbook)) and video demo from my channel (Salesforce Techbook)

Source Code:
dragger_component:
drop_component:
Accountcls:
Video Link:

Output:


Note: It doesn't support Salesforce 1 mobile application.
References:




Tuesday 21 April 2020

How to create a record using apex class from Lightning Web Component

Hi ,

Here we are going to learn how to create a record with apex class from Lightning Web Component.

We have a simple method "createAccount"  which expects "Account" record as parameter.

For video demo . You can watch on my channel  Salesforce Techbook :
https://www.youtube.com/watch?v=31jSRKMaUGQ&list=PL-JzyFWuCbkKcFSOCRlCUk79YbET5QvZC&index=14

Apex Class:

public with sharing class AccountCreationController {
    @AuraEnabled
    public static Account createAccount(Account accountRecObj){
        try{
            insert accountRecObj;
            return accountRecObj;
        }
        catch(Exception ex){
            throw new AuraHandledException(ex.getMessage());

        }
    }
}


Lightning Web Component:

HTML file:
<template>
    <lightning-card>
        <h3 slot="title">
            <lightning-icon icon-name="standard:account" size="small"></lightning-icon>
            Account Creation using Apex Controller
        </h3>
        <div slot="footer">
                <lightning-button label="Create Account" onclick={handleSaveAccount} variant="brand"></lightning-button>                
                <lightning-badge label={accountid}></lightning-badge>
                <lightning-badge label={error}></lightning-badge>

                
        </div>
        <p class="slds-p-horizontal_small">
            <lightning-input type="text" label="Account Name" value={accountRecord.Name} onchange={handleNameChange}></lightning-input>     
            <lightning-input type="text" label="Type" value={accountRecord.Type} onchange={handleTypeChange}></lightning-input>     
            <lightning-input type="text" label="Phone" value={accountRecord.Phone} onchange={handlePhoneChange}></lightning-input>     
        </p>
    </lightning-card>
</template>



Javascript file:

Here we are importing Account Fields and ShowToastEvent through import statement.

Here the track variable "accountRecord" represents the format of the account record and we are assigning values to each key or attribute in accountRecord based  on "onchange" event from HTML file which is on every input element.

createAccount is an identifier for your apex method which is imported via '@salesforce/apex/AccountCreationController.createAccount'

here AccountCreationContoller is an apex class

and createAccount is a method of apex class

import { LightningElement,track } from 'lwc';
import createAccount from '@salesforce/apex/AccountCreationController.createAccount';
import ACCOUNT_NAME from '@salesforce/schema/Account.Name';
import ACCOUNT_TYPE from '@salesforce/schema/Account.Type';
import ACCOUNT_PHONE from '@salesforce/schema/Account.Phone';
import {ShowToastEventfrom 'lightning/platformShowToastEvent';

export default class AccountCreation_Apex extends LightningElement {
 @track accountid;
 @track error;
//Preparation of empty record
 @track accountRecord = {
    Name:ACCOUNT_NAME,
    Type:ACCOUNT_TYPE,
    Phone:ACCOUNT_PHONE
 };
 handleNameChange(event){
     this.accountRecord.Name = event.target.value;
 }
 handleTypeChange(event){
    this.accountRecord.Type = event.target.value;
 }
 handlePhoneChange(event){
    this.accountRecord.Phone = event.target.value;
 }
 handleSaveAccount(){  
//Passigng parameter to method
//Processing the result in then function if it is succcessful
//otherwise process errors in catch block  
    createAccount({accountRecObj:this.accountRecord})
    .then(result=>{    
        this.accountRecord = {};
        this.accountid = result.Id;
        window.console.log(this.accountid);
        const toastEvent = new ShowToastEvent({
            title:'Success!',
            message:'Account Record is created successfullu!',
            variant:'success'
        });
        this.dispatchEvent(toastEvent);
    })
    .catch(error=>{
        this.error = error.message;
    });
 }

}



Meta File:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>
            lightning__AppPage
        </target>
    </targets>
</LightningComponentBundle>




Output:



Reference:
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex

https://www.youtube.com/watch?v=31jSRKMaUGQ&list=PL-JzyFWuCbkKcFSOCRlCUk79YbET5QvZC&index=14





Tuesday 14 April 2020

Display Aggregate Result on Visualforce page

Hi ,

Here we are going to learn how to display aggregate result on visualforce page.

Here let's see how can we  display Opportunity count,sum of amount on Opportunities for each Stage (Propect,Closed Won,Closed Lost etc.,)

Let's have example:

Apex Class:

public with sharing class AggregateResultController {
    public List<AggregateResult> aggregateResultList{get;set;}
    public List<AggregateResult> campaignResultList{get;set;}
    public AggregateResultController() {
        aggregateResultList = new List<AggregateResult>();
        aggregateResultList = [select count(id) oppCount,sum(Amount) oppSum,StageName oppStage 
                            from Opportunity group by StageName];        
    }
}

VFPage:

If you want to set headerValue for column while you are trying to display aggregate result you have to use "<apex:facet/> tag for setting headerValue.

Here you go for VF page example:

<apex:page controller="AggregateResultController">
    
    <h1>Aggregate Resul Example</h1>
    <apex:pageBlock title="Opportunity Count with Stage Name">
        <apex:pageBlockTable value="{!aggregateResultList}" var="agResultObj">
            <apex:column value="{!agResultObj['oppCount']}">
                <apex:facet name="header">Count</apex:facet>
            </apex:column>
            <apex:column value="{!agResultObj['oppSum']}">
                <apex:facet name="header">Sum</apex:facet>
            </apex:column>
            <apex:column value="{!agResultObj['oppStage']}">
                <apex:facet name="header">Stage Name</apex:facet>
            </apex:column>
        </apex:pageBlockTable>       
    </apex:pageBlock>    
</apex:page>


I gave demo on my channel "Salesforce Techbook" on the same here you can find out the link.


Reference:

Sunday 5 April 2020

Firing Platform Events from Batch Apex

Hi ,

Here we are going to learn how to fire platform events when there is any unhandled exception occurred in start or execute or finish methods in batch apex.

Batch Apex classes can fire platform events when encountering an error or exception. Clients listening on an event can obtain actionable information, such as how often the event failed and which records were in scope at the time of failure. Events are also fired for Salesforce Platform internal errors and other uncatchable Apex exceptions such as LimitExceptions, which are caused by reaching governor limits.

An event message provides more granular error tracking than the Apex Jobs UI. It includes the record IDs being processed, exception type, exception message, and stack trace. We can also incorporate custom handling and retry logic for failures.

 We can invoke custom Apex logic from any trigger on this type of event, so Apex developers can build functionality like custom logging or automated retry handling.

Here "BatchApexErrorEvent" object  represents a platform event associated with a batch Apex class.

To fire a platform event, a batch Apex class declaration must implement the Database.RaisesPlatformEvents interface.

Eg:

public with sharing class AccountProcessing implements Database.Batchable<SObject>, 
   Database.RaisesPlatformEvents{ 
   // class implementation 
} 

We can listen the platform events through apex trigger or process builder or external system.

Apex Trigger on Platform event supports "after insert" event only.

Here we are going to the example with a trigger on platform event object "BatchApexErrorEvent"

Eg:

This example creates a trigger to determine which accounts failed in the batch transaction.

Custom field Dirty__c indicates that the account was one of a failing batch and ExceptionType__c indicates the exception that was encountered.

JobScope and ExceptionType are fields in the BatchApexErrorEvent object.



trigger UpdateAccountsonfailure on BatchApexErrorEvent (after insert) {
    Set<Id> asyncApexJobIdSet = new Set<Id>();
    for(BatchApexErrorEvent evt:Trigger.new){
        asyncApexJobIdSet.add(evt.AsyncApexJobId);
    }
    
    Map<Id,AsyncApexJob> jobs = new Map<Id,AsyncApexJob>(
        [SELECT id, ApexClass.Name FROM AsyncApexJob WHERE Id IN :asyncApexJobIdSet]
    );
    
    List<Account> accountList = new List<Account>();
    for(BatchApexErrorEvent evt:Trigger.new){
        //only handle events for the job(s) we care about
        if(jobs.get(evt.AsyncApexJobId).ApexClass.Name == 'AccountUpdaterJob'){
            for (String item : evt.JobScope.split(',')) {
                Account a = new Account(
                    Id = (Id)item,
                    ExceptionType__c = evt.ExceptionType,
                    Dirty__c = true
                );
                accountList.add(a);
            }
        }
    }
    update records;
}

Reference:

https://developer.salesforce.com/docs/atlas.en-us.224.0.platform_events.meta/platform_events/sforce_api_objects_batchapexerrorevent.htm

https://developer.salesforce.com/docs/atlas.en-us.224.0.apexcode.meta/apexcode/apex_batch_platformevents.htm?search_text=Database.RaisesPlatformEvents




How to include a screen flow in a Lightning Web Component

 Hi, Assume  you have a flow called "Quick Contact Creation" and API Name for the same is "Quick_Contact_Creation". To i...