We are using Salesforce's 'lightning/modal' component to build modals as it has all standard functionalitites with the additional functionalities which will always make is scalable.
The modal component file:
js file:
import { api } from 'lwc';
import LightningModal from 'lightning/modal';
export default class LwcModal extends LightningModal {
@api content;
@api header;
@api navigateToLead=false;
@api leadId;
handleClose() {
this.close('okay');
console.log("myModal onnavigatetoLead is called");
this.navigateToLead=false;
}
//navigation cannot be done from here it needs to be done through an event and a child component
}
html file:
<template>
<lightning-modal-header label={header}></lightning-modal-header>
<lightning-modal-body> {content}
</lightning-modal-body>
<lightning-modal-footer>
<lightning-button variant="destructive-text" label="Close" class="slds-var-m-around_medium" onclick={handleClose}></lightning-button>
<template lwc:if={navigateToLead}>
<c-nav-to-lead-modal onnavigatetolead={handleClose} lead-id={leadId}></c-nav-to-lead-modal>
</template>
</lightning-modal-footer>
</template>
As per my use case I required a button which when clicked will the modal should close and the page should navigate to the supplied lead detail page.
The navigation works differntly on a modal when compared to a normal lwc page, the navigation requires an event to be fired and also requires a child component which makes the navigation work, you can find more on it here:
Below is the child compoenent which contains the navigation settings:
js file:
import { LightningElement, api } from 'lwc';
export default class NavToLeadModal extends LightningElement {
@api leadId;
navigateToLead()
{
const pageRef = {
type: "standard__recordPage",
attributes: {
recordId: this.leadId,
objectApiName: "Lead",
actionName: "view",
},
};
const evt = new CustomEvent("navigatetolead", {
bubbles: true,
composed: true,
detail: pageRef
});
this.dispatchEvent(evt);
}
}
html file:
<template>
<lightning-button
variant="brand"
label="Go To Lead"
class="slds-var-m-around_medium"
onclick={navigateToLead}
></lightning-button>
</template>
I had to use a Platform event which when received, triggerred the modal as it was part of a notification system. So the following code is of the parent component which subscribes to the empApi when the matching Platform event is received. Attaching the parent component's code below:
js file:
import { LightningElement, wire, track } from 'lwc';
import LwcModal from 'c/lwcModal';
import USER_ID from '@salesforce/user/Id';
import { subscribe as empSubscribe, unsubscribe as empUnsubscribe, onError } from 'lightning/empApi';
import { NavigationMixin } from "lightning/navigation";
export default class LeadNotifier extends NavigationMixin(LightningElement) {
result;
showModal = false;
message = '';
leadId;
currentUserId = USER_ID;
subscription = {};
channelName = '/event/LeadAssignment_PlatformEvent__e';
connectedCallback()
{
console.log('LeadNotifier component connected');
this.registerErrorListener();
this.subscribeToEvent();
}
subscribeToEvent() {
empSubscribe(this.channelName, -1, (response) => {
const payload = response.data.payload;
console.log('Received PE:', JSON.stringify(payload));
const userId = payload.User__c;
const leadId = payload.Lead__c;
const msg = payload.Message__c;
if (userId === this.currentUserId) {
this.message = msg;
this.leadId = leadId;
this.showModal = true;
this.handleClick(this.message, this.leadId);
}
}).then((response) => {
console.log('Subscribed to channel ', response.channel);
this.subscription = response;
});
}
registerErrorListener() {
onError((error) => {
console.error('EMP API error:', JSON.stringify(error));
});
}
async handleClick(mssg, leadId) {
console.log('In handleClick method, mssg: ', mssg);
const result = await LwcModal.open({
// `label` is not included here in this example.
// it is set on lightning-modal-header instead
size: 'small',
description: 'Accessible description of modal\'s purpose',
content: mssg,
header: 'Lead Notification - Round Robin',
navigateToLead: true,
leadId: leadId,
onnavigatetolead : (e) => {
this[NavigationMixin.Navigate](e.detail);
},
});
//onnavigatetolead event needs to be called to make the navigation to lead detail page happen
// if modal closed with X button, promise returns result = 'undefined'
// if modal closed with OK button, promise returns result = 'okay'
console.log(result);
this.result = result;
}
}
html file:
<template>
<template lwc:if={showModal}>
<p>RR notif showed up!</p>
</template>
</template>
meta file:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>64.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__UtilityBar</target>
<target>lightning__RecordPage</target>
<target>lightning__RecordAction</target>
</targets>
</LightningComponentBundle>
Below is the image of the component:
Top comments (0)