Monday, 31 August 2020

Dynamically bind variable in Lightning Web Component (LWC)

 Use case

Once we will be working with generic component we may have to bind declared variables  dynamically in code to get expected result .

Based on below example we  can display  account name for an particular 'accountId' 

import { LightningElement, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Account.Name';

export default class Example extends LightningElement {
    @wire(getRecord, { recordId: '0013xx065790ASZ', fields: [NAME_FIELD] })
    account;

     get name() {
        return getFieldValue(this.account.data, NAME_FIELD);
    }

 
    
}

 

Instead of importing the field definition in controller we can dynamically pass  fields array  within getrecord().


Lets have a look into the code.

Controller

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
 * @File Name          : dynamicbinding.js
 * @Description        : 
 * @Author             : Swarup Satpti
 * @Group              : 
 * @Last Modified By   : Swarup Satpati
 * @Last Modified On   : 8/31/2020, 5:00:00 PM
**/
import { LightningElement, api, wire, track } from 'lwc';
import { getFieldValue } from 'lightning/uiRecordApi';
import {getRecord} from 'lightning/uiRecordApi';

export default class Chevron extends LightningElement {
    @api objectName = 'Account';
    @api fieldName = 'Name';
    
    /*component with a recordId property is used on a Lightning record page, 
    the page sets the property to the ID of the current record.*/
    @api recordId='001W000000dls6ZIAQ'; 
    @track record;
    @track error;
    @track fieldArray;
    @track fieldValue;


    connectedCallback(){
        console.log("hi..");
        this.fieldArray = [`${this.objectName}.${this.fieldName}`,`${this.objectName}.RecordTypeId`];
    }
    
    /*Use this wire adapter to get a record’s data : 
       Recordtype ID and value of status field pass through API
    */
    @wire(getRecord, { recordId: '$recordId', fields:'$fieldArray'})
    wiredAccount({ error, data }) {
        if (data) {
            this.record = data;
            console.log(JSON.stringify(data));
           // this.fieldvalue=getFieldValue(data,`${this.objectName}.${this.fieldName}`);
            this.error = undefined;
        } else if (error) {
            console.log('error..');

            this.error = error;
            this.record = undefined;
        }
    }

    get name() {
        return getFieldValue(this.record,`${this.objectName}.${this.fieldName}`);
    }
}

  HTML Template

1
2
3
4
5
<template>
    <div class="slds-m-around_medium">
        <p>Account Name: {name}</p>
    </div>
</template>


Code Explanation:

within Js controller variables are dynamically bound using '$' sign as below.

  this.fieldArray = [`${this.objectName}.${this.fieldName}`,`${this.objectName}.RecordTypeId`]

 Finally  Code will return the  value of account name for given account ID .


Hope you got it useful....! cheers ..

Wednesday, 5 August 2020

Custom Chevron component using lightning web component(LWC)

Use case :

we can use sales force standard "Path" component to build chevron on record page showed as below.


                                                                                                                                                                           
But there is an problem 😟   with this approach . As you can see once stage is completed it shows the chevron with right check mark and not displaying the status  and also i don't want user to manually change the status by using "Mark Stage Completed"  button on  right which should not be available to end user.

To achieve this we have to use custom LWC component. Let's get into the code..!

Code:

Chevron.js

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
/**
 * @File Name          : chevron.js
 * @Description        : 
 * @Author             : Swarup Satpti
 * @Group              : 
 * @Last Modified By   : Swarup satpati
 * @Last Modified On   : 8/3/2020, 5:30:00 PM
**/
import { LightningElement, api, wire, track } from 'lwc';
import { getObjectInfo, getPicklistValues} from 'lightning/uiObjectInfoApi';
import { getFieldValue } from 'lightning/uiRecordApi';
import {getRecord} from 'lightning/uiRecordApi';

export default class Chevron extends LightningElement {
    @api objectName = 'Opportunity';
    @api fieldName = 'StageName';
    /*component with a recordId property is used on a Lightning record page, 
    the page sets the property to the ID of the current record.*/
    @api recordId; 

    @track picklistvalues;
    @track record;
    @track error;
    @track chevrondata=[];
    @track itemList;
    @track fieldValue;
    @track fieldArray;

    recordtypeId;
    index=0;
    isFound=false;
    isfoundindex=0;
    fieldapi;


  connectedCallback(){
    this.fieldArray = [`${this.objectName}.${this.fieldName}`,`${this.objectName}.RecordTypeId`];
    this.fieldapi=`${this.objectName}.${this.fieldName}` ;
    }
    
    /*Use this wire adapter to get a record’s data : 
       Recordtype ID and value of status field pass through API
    */
    @wire(getRecord, { recordId: '$recordId', fields:'$fieldArray'})
    wiredAccount({ error, data }) {
        if (data) {
            this.record = data;
            console.log(JSON.stringify(data));
            this.fieldvalue=getFieldValue(data,`${this.objectName}.${this.fieldName}`);
            this.recordtypeId=this.record.fields.RecordTypeId.value;
            this.error = undefined;
            console.log('selected value..'+this.fieldvalue);
        } else if (error) {
            console.log('error..');

            this.error = error;
            this.record = undefined;
        }
    }

   /*Use this wire adapter to get the picklist values for a specified field.*/

    @wire(getPicklistValues, {
        fieldApiName: '$fieldapi',
        recordTypeId: '$recordtypeId'
    })
    fetchRecordTypeInfo({ data, error }) {
        if (data) {
            console.log('data..'+JSON.stringify(data.values));

           // this.picklistvalues = data.picklistFieldValues.Status_EI__c.values;
              this.picklistvalues = data.values ;

            this.picklistvalues.forEach(item=>{
               // console.log('rec..'+item.value);
                let classType;
                if(this.fieldvalue==item.value){
                    classType = 'slds-path__item slds-is-current slds-is-active';
                    this.isFound=true;
                    this.isfoundindex=this.index;
                }
                else{ 
                   classType='slds-path__item slds-is-incomplete';
                   this.index ++; 
                }
                this.chevrondata.push({
                 stages :item,
                 classType:classType
                });


            });
            if(this.isFound){
                for(let i=0;i<this.isfoundindex;i++){
                   this.chevrondata[i].classType='slds-path__item slds-is-complete';
                }

            }
           
             console.log('chevron data..'+JSON.stringify(this.chevrondata));
           
            //console.log(JSON.stringify(this.picklistvalues));
        }
        else if (error) {
            console.log(" Error  ---> " + JSON.stringify(error));
        }
    }
    
}

chevron.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
    <div class="slds-path">
        <div class="slds-grid slds-path__track">
          <div class="slds-grid slds-path__scroller-container">
            <div class="slds-path__scroller" role="application">
              <div class="slds-path__scroller_inner">
                <ul class="slds-path__nav" role="listbox" aria-orientation="horizontal">
                  <template for:each={chevrondata} for:item="stageIs" for:index="index">
                    <li key={stageIs} class={stageIs.classType} style="margin-left: 0em !important;" role="presentation">
                        <a aria-selected="flase" class="slds-path__link" href="javascript:void(0);"  role="option" tabindex="0">
                          <span class="slds-path__stage">
                            <!--<svg class="slds-icon slds-icon_x-small" aria-hidden="true">
                              <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#check"></use>
                            </svg>
                          -->
                           {stageIs.stages.label}
                            <span class="slds-assistive-text">{stageIs.stages.label}</span>
                          </span>
                          <span class="slds-path__title">{stageIs.stages.label}</span>
                        </a>
                    </li>
                  </template>
                </ul>
            </div>
          </div>
        </div>
        </div>
    </div>
</template>

Metadata

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?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>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>


Code Explanation:

Within js controller we are using two wire adapters.

getRecord() : by using this method we are  retrieving the present stage value and record type Id for  the current record

getPicklistValues() : dynamically fetching pick list values for the given field Api 
and recordtype.

Have created custom property called 'ClassType' and 'stage' to display 
the chevron in html.

Main tricky part is to set the claastype conditionally based on the current stage.

'slds-path__item slds-is-current slds-is-active' :   for current Stage
'slds-path__item slds-is-incomplete': for all incomplete stages
'slds-path__item slds-is-complete' : for all completed stages


Hope you get it right !

Output :



Getting started with Heroku

I am familiar with the heroku for quite long time, have seen lots of people are interested with it but not sure from where its need to Start...