Showing posts with label LWC. Show all posts
Showing posts with label LWC. Show all posts

Saturday, April 27, 2024

How to Share JavaScript Code in LWC

 In Lightning Web Components (LWC), there are two primary patterns for code sharing:

  1. Module Pattern:

    • Usage: This pattern involves creating reusable JavaScript modules that can be imported into LWC components.
    • Implementation: You create separate JavaScript files containing reusable code, then import these modules into your LWC components using the ES6 import statement.
    • Benefits: Encourages modularity, reusability, and separation of concerns. It allows you to organize your codebase effectively and promotes maintainability.
    • Example: As described in the previous response, creating a JavaScript module (sharedUtils.js) and importing it into components.

  2. Base Components Pattern:

    • Usage: This pattern involves creating base components that encapsulate common functionality and can be extended or customized by other components.
    • Implementation: You create base components that contain common logic or UI elements. Other components can then extend these base components to inherit their functionality.
    • Benefits: Promotes code reuse and consistency across the application. It simplifies development by providing a standardized way to implement common features.
    • Example: You might create a base component for a custom modal dialog that includes methods for showing and hiding the modal. Other components can extend this base component to create specific modal instances with customized content.

The first pattern is used in this instance. Only myComponent.js has the ability to import code from myFunction.js and utils.js.


lwc

└───myWgComponent

├──myWgComponent.html

├──myWgComponent.js

├──myWgComponent.js-meta.xml

├──myWgFunction.js

└──wgutils.js

 Utilize relative paths when importing the code.

// myComponent.js

import { getMonthlyAmount, calculateMonth} from ‘./myWgfunction;

import WgCalender from ‘./wgutils; 

Another illustration is a service component (library). The name of the folder and one JavaScript file must match. The name in this instance is wgUtils. 

lwc

├──wgUtils

├──wgUtils.js

└──wgUtils.js-meta.xml

└───wgComponent

├──wgComponent.html

├──wgComponent.js

└──wgComponent.js-meta.xml

 

For importing the code into other components, use c/componentName syntax.

// wgComponent.js

import { getOptions, calculatePayment } from ‘c/wgUtils’;


Both patterns have their strengths and are suitable for different scenarios. The choice between them depends on factors such as the complexity of the shared functionality, the level of customization required, and the architecture of your application. Using a combination of both patterns can often provide a flexible and scalable approach to code sharing in LWC.


Thursday, January 4, 2024

Issue in Lightning-progress-indicator in lwc

 Hello all today i will share one inserting issue, when we used conditional rendering within  

Lightning-progress-indicator


ProgressIndicatorBasic.html

<template>

    <p>

        A progress indicator displays the steps in a process. All steps preceding the step specified by currentStep are marked completed.

    </p>

    <lightning-progress-indicator current-step="3" type="base" has-error="true" variant="base">

        <lightning-progress-step label="Step 1" value="1"></lightning-progress-step>

     <template if:true={areDetailsVisible}>

            <lightning-progress-step label="Step 2" value="2"></lightning-progress-step>

        </template>

        <lightning-progress-step label="Step 3" value="3"></lightning-progress-step>

        <lightning-progress-step label="Step 4" value="4"></lightning-progress-step>

    </lightning-progress-indicator>

</template>

ProgressIndicatorBasic.js

import { LightningElement } from 'lwc';


export default class ProgressIndicatorBasic extends LightningElement {}


Issue: As per the above code if  <template if:true={areDetailsVisible}> is true then Lightning-progress-indicator step will

correctly otherwise current steps selection will display correctly.

Updated code:-

<template>

    <p>

        A progress indicator displays the steps in a process. All steps preceding the step specified by currentStep are marked completed.

    </p>

   <template if:true={areDetailsVisible}>

<lightning-progress-indicator current-step="3" type="base" has-error="true" variant="base">

        <lightning-progress-step label="Step 1" value="1"></lightning-progress-step>

        <lightning-progress-step label="Step 2" value="2"></lightning-progress-step>

        <lightning-progress-step label="Step 3" value="3"></lightning-progress-step>

        <lightning-progress-step label="Step 4" value="4"></lightning-progress-step>

    </lightning-progress-indicator>

<template>

<template if:false={areDetailsVisible}>

<lightning-progress-indicator current-step="3" type="base" has-error="true" variant="base">

        <lightning-progress-step label="Step 1" value="1"></lightning-progress-step>

       <lightning-progress-step label="Step 3" value="3"></lightning-progress-step>

        <lightning-progress-step label="Step 4" value="4"></lightning-progress-step>

    </lightning-progress-indicator>

<template>


</template>



Lightning-progress-indicator in lwc

 A lightning-progress-indicator component displays steps horizontally. It indicates the number of steps in a given process, the current step, as well as prior steps which is completed.

Steps are created using lightning-progress-step component along with label and value attributes. The current step is specified using the current-step attribute, The current step must match one of the value attributes on a lightning-progress-step component as shown below.

  • Set type="base" to create a component that implements the progress indicator blueprint in the Lightning Design System. 

          A progress indicator component communicates to the user the progress of a particular process.
     

  • Set type="path" to create a component that implements the path blueprint in the Lightning Design System. 
          The Path communicates to the user the progress of a particular process.

  • If the type is not specified, the default type base is used. 

lightningprogressindicator.html

<template>
    <p>
        A progress indicator displays the steps in a process. All steps preceding the step specified by currentStep are marked completed.
    </p>
    <lightning-progress-indicator current-step="3" type="base" has-error="true" variant="base">
        <lightning-progress-step label="Step 1" value="1"></lightning-progress-step>
        <lightning-progress-step label="Step 2" value="2"></lightning-progress-step>
        <lightning-progress-step label="Step 3" value="3"></lightning-progress-step>
        <lightning-progress-step label="Step 4" value="4"></lightning-progress-step>
    </lightning-progress-indicator>
</template>

lightningprogressindicator.js

import { LightningElement } from 'lwc';

export default class lightningprogressindicator extends LightningElement {}

Monday, November 27, 2023

How to use Google reCAPTCHA v3 in Lightning Web Component

We have many applications that do require some authentication to prevent the attack vectors. To stop flooding the application with unnecessary attacks(eg. Robots running the scripts), we have to adopt some sort of authentication mechanism to regularize the application access. Google reCAPTCHA can help in identifying if the requests are coming from human or not


Google Configuration

  1. Go to https://www.google.com/recaptcha
  2. Click on the ‘Admin console’ button
  3. Click the ‘+’ create icon if you already have sites configured
  4. Enter a Label and select reCAPTCHA v3, v2 Checkbox or v2 Invisible.
  5. Add your custom or force.com community domain. (You can also add additional domains so that it will function in Experience Builder)
  6. Accept the terms of service and click the Submit button

Screen Shot 2020-04-19 at 3.24.06 PM.png
You will need to use your resulting keys in the code examples below. The keys are only valid for the type of reCAPTCHA selected during creation. If you want to test all 3 examples below, you must create each type in the admin console.
Screen Shot 2020-04-18 at 12.47.50 PM.png Site Key - This public key is intended to be exposed on your site and should be pasted directly in the JavaScript Head Markup examples (replace text ‘reCAPTCHA_site_key’).

Secret Key - This private key should live on the server-side only and be stored in a Custom Setting, Custom Metadata Type or Apex class (replace text ‘reCAPTCHA_secret_key’).

 

Experience Builder Settings

You will see Content Security Policy (CSP) errors as you implement the reCAPTCHA code examples. In Experience Builder → Settings → Security, add the trusted sites shown below and click the ‘Whitelist’ button as items show in the ‘CSP Errors’ list.
Screen Shot 2020-04-18 at 2.16.33 PM.png
 

There are 4 steps to integrate reCAPTCHA v3 to a Lightning Web Component

1. Create html static resource with reCAPTCHA

reCAPTCHAv3.html

<html>
    <head>
        <title></title>reCAPTCHA html resource</title>
        <script src="https://www.google.com/recaptcha/api.js?render=reCAPTCHA_site_key"></script>
    </head>
    <body>
        <input type="hidden" name="recaptcha_response" id="recaptchaResponse"/>
        <script type="text/javascript">
            grecaptcha.ready(function() {
                var reCAPTCHA_site_key = "reCAPTCHA_site_key";
                grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'}).then(function(token) {
                    recaptchaResponse.value = token;
                    if (token == "") {
                        parent.postMessage({ action: "getCAPCAH", callCAPTCHAResponse : "NOK"}, "*");
                    } else {
                        parent.postMessage({ action: "getCAPCAH", callCAPTCHAResponse : token}, "*");
                    }
                });
            }
        </script>
    </body>
</html>

reCAPTCHAv3.resource-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Public</cacheControl>
    <contentType>text/html</contentType>
</StaticResource>

2. Create Lightning Web Component with an iframe to load the static resource

myLWC.html

<template>
    <iframe src={navigateTo} name="captchaFrame" onload={captchaLoaded}></iframe>
</template>

3. Create the Javascript controller for the Lightning Web Component

myLWC.js

import { LightningElement, track, api } from 'lwc';
import pageUrl from '@salesforce/resourceUrl/reCAPTCHAv3';
import isReCAPTCHAValid from '@salesforce/apex/reCAPTCHAv3ServerController.isReCAPTCHAValid';

export default class GoogleCapatcha extends LightningElement {
    @api formToken;
    @api validReCAPTCHA = false;

    @track navigateTo;
    captchaWindow = null;

    constructor(){
        super();
        this.navigateTo = pageUrl;
    }

    captchaLoaded(evt){
        var e = evt;
        console.log(e.target.getAttribute('src') + ' loaded');
        if(e.target.getAttribute('src') == pageUrl){

            window.addEventListener("message", function(e) {
                if (e.data.action == "getCAPCAH" && e.data.callCAPTCHAResponse == "NOK"){
                    console.log("Token not obtained!")
                } else if (e.data.action == "getCAPCAH" ) {
                    this.formToken = e.data.callCAPTCHAResponse;
                    isReCAPTCHAValid({tokenFromClient: formToken}).then(data => {
                        this.validReCAPTCHA = data;
                    });
                }
            }, false);
        } 
    }

}

4. Create Apex class to handle the server-side verification

reCAPTCHAv3ServerController.cls

public with sharing class reCAPTCHAv3ServerController {
    public reCAPTCHAv3ServerController(){

    }


    @AuraEnabled
    public static Boolean isReCAPTCHAValid(String tokenFromClient) {
        String SECRET_KEY = 'reCAPTCHA_secret_key';
        String RECAPTCHA_SERVICE_URL = 'https://www.google.com/recaptcha/api/siteverify';
        Http http = new Http();

        HttpRequest request = new HttpRequest();

        request.setEndpoint(RECAPTCHA_SERVICE_URL + '?secret=' + SECRET_KEY + '&response' + tokenFromClient);
        request.setMethod('POST');
        request.setHeader('Content-Length', '0');
        HttpResponse response = http.send(request);

        Map<String, Object> mapOfBody = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());

        Boolean success = (Boolean) mapOfBody.get('success');

        return success;
    }
}