Angular 5 - Copy to clipboard
Solution 1: Copy any text
HTML
<button (click)="copyMessage('This goes to Clipboard')" value="click to copy" >Copy this</button>
.ts file
copyMessage(val: string){ const selBox = document.createElement('textarea'); selBox.style.position = 'fixed'; selBox.style.left = '0'; selBox.style.top = '0'; selBox.style.opacity = '0'; selBox.value = val; document.body.appendChild(selBox); selBox.focus(); selBox.select(); document.execCommand('copy'); document.body.removeChild(selBox); }
Solution 2: Copy from a TextBox
HTML
<input type="text" value="User input Text to copy" #userinput> <button (click)="copyInputMessage(userinput)" value="click to copy" >Copy from Textbox</button>
.ts file
/* To copy Text from Textbox */ copyInputMessage(inputElement){ inputElement.select(); document.execCommand('copy'); inputElement.setSelectionRange(0, 0); }
Solution 3: Import a 3rd party directive ngx-clipboard
<button class="btn btn-default" type="button" ngxClipboard [cbContent]="Text to be copied">copy</button>
Solution 4: Custom Directive
If you prefer using a custom directive, Check Dan Dohotaru's answer which is an elegant solution implemented using ClipboardEvent
.
Solution 5: Angular Material
Angular material 9 + users can utilize the built-in clipboard feature to copy text. There are a few more customization available such as limiting the number of attempts to copy data.
I know this has already been highly voted in here by now, but I'd rather go for a custom directive approach and rely on the ClipboardEvent as @jockeisorby suggested, while also making sure the listener is correctly removed (same function needs to be provided for both the add and remove event listeners)
stackblitz demo
import { Directive, Input, Output, EventEmitter, HostListener } from "@angular/core";@Directive({ selector: '[copy-clipboard]' })export class CopyClipboardDirective { @Input("copy-clipboard") public payload: string; @Output("copied") public copied: EventEmitter<string> = new EventEmitter<string>(); @HostListener("click", ["$event"]) public onClick(event: MouseEvent): void { event.preventDefault(); if (!this.payload) return; let listener = (e: ClipboardEvent) => { let clipboard = e.clipboardData || window["clipboardData"]; clipboard.setData("text", this.payload.toString()); e.preventDefault(); this.copied.emit(this.payload); }; document.addEventListener("copy", listener, false) document.execCommand("copy"); document.removeEventListener("copy", listener, false); }}
and then use it as such
<a role="button" [copy-clipboard]="'some stuff'" (copied)="notify($event)"> <i class="fa fa-clipboard"></i> Copy</a>public notify(payload: string) { // Might want to notify the user that something has been pushed to the clipboard console.info(`'${payload}' has been copied to clipboard`);}
Note: notice the window["clipboardData"]
is needed for IE as it does not understand e.clipboardData
I think this is a much more cleaner solution when copying text:
copyToClipboard(item) { document.addEventListener('copy', (e: ClipboardEvent) => { e.clipboardData.setData('text/plain', (item)); e.preventDefault(); document.removeEventListener('copy', null); }); document.execCommand('copy'); }
And then just call copyToClipboard
on click event in html. (click)="copyToClipboard('texttocopy')"
.