Prevent Users from Copying/Pasting DataTable Information in Lightning Web Components
Hey readers! Wow, it's been a busy year. My first post from Austin, Texas! For those of you who are still around and interested in this content, thank you. Recently, my role as an architect has taken my focus away from being hands on keyboard and coding, however when I am able to work on something small and it happens to be kind of cool, I want to post about it!
Recently, we build an entire partner portal for a client using Salesforce Communities and I have to say that I wish I could talk about it more because its been on the most incredible projects I have ever been on. I have learned so much and worked with so many incredible people over the last year. I am very grateful. As part of our second phase of work, there was a need to expose sensitive data to partners when they logged in to use the portal, however we needed to prevent them from copying the information and storing it somewhere on their local machine.
I am still really happy with the direction that Salesforce is taking Lightning Web Components and wanted to share a pretty easy solution around how we can go about preventing users from copying your information within your components and even leaving them a nice message for when they actually do paste letting them know that we do not support copying from that particular component.
Below I have a pretty simple Lightning Datatable showing Account information from my personal org:
// JavaScript file
import { LightningElement } from 'lwc';
import getAccounts from '@salesforce/apex/AccountSelector.getAccounts';
const columns = [
{ label: 'Label', fieldName: 'Name' },
{ label: 'Site', fieldName: 'Site', type: 'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Type', fieldName: 'amount', type: 'currency' }
];
export default class AccountDataTable extends LightningElement {
data;
columns = columns;
connectedCallback() {
getAccounts()
.then(result => {
this.data = result;
})
}
}
<!-- html file -->
<template>
<div style="height: 300px;">
<lightning-datatable
key-field="id"
data={data}
columns={columns}>
</lightning-datatable>
</div>
</template>
Pretty simple, right? However, what happens if this information should be viewed but not copied and distributed elsewhere without the knowledge of the business? JavaScript Event Listeners has entered the chat!
We know from previous blogs that Lightning Web Components have certain webhooks that you can incorporate in different stages within the lifecycle of the application. In this specific case, we want to add our even listener when the page is loaded using connectedCallback(). Here is the updated JavaScript with the event listener:
// JavaScript file
import { LightningElement } from 'lwc';
import getAccounts from '@salesforce/apex/AccountSelector.getAccounts';
const columns = [
{ label: 'Label', fieldName: 'Name' },
{ label: 'Site', fieldName: 'Site', type: 'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Type', fieldName: 'amount', type: 'currency' }
];
export default class AccountDataTable extends LightningElement {
data;
columns = columns;
connectedCallback() {
// once we are inside of the connected callback , we can begin setting up our even listener for the copy event
document.addEventListener("copy", function(evt){
// When the copy occurs, you can actually change the copy text if you want to paste in as a substitute to what the user thinks they are copying
evt.clipboardData.setData("text/plain", "Copying is not allowed from this component!");
// Prevent the normal default copy from occuring
evt.preventDefault();
}, false);
getAccounts()
.then(result => {
this.data = result;
})
}
}
https://videopress.com/v/lo2uNBVl?preloadContent=metadata
As you can see above, we are calling and setting up the event listener within the connected callback so that anything within the document, including the datatable, cannot be copied by a user. When I try to paste the value into my VS Code editor, I get the message that we added above in the event listener! I couldn't pass up the opportunity to show you this small but useful nugget of information that might help someone down the line when trying to do the same thing. If you have any questions, please feel free to reach out or comment below. Thanks so much for taking the time to read today. Happy coding!