Reputation: 2085
I have a clickable icon on the page. On click on this icon, I would like to construct some text and copy that in the clipboard
<td><img src='./assets/Copy.gif' (click)="copyToClipboard()" /></td>
and in the Component
copyToClipboard() {
this.textToCopy = this.text1 + this.text2 + this.text3;
this.toastr.info('Copied to Clipboard');
}
I have looked at https://www.npmjs.com/package/ngx-clipboard. However, this package requires to refer to an input element and copy the text from that input element. In my use case, the text needs to be dynamically created and then added to clipboard.
Can I use ngx-clipboard to copy to clipboard or is there be another package that would enable me to achieve this?
Upvotes: 19
Views: 36579
Reputation: 4414
User interaction is mandatory for executing document.execCommand
, which is used for copying text to the clipboard.
See my other answer.
If you don't want to use any third party library, you could use below snippet for copying text to the clipboard.
function copyTextToClipboard(text) {
var txtArea = document.createElement("textarea");
txtArea.id = 'txt';
txtArea.style.position = 'fixed';
txtArea.style.top = '0';
txtArea.style.left = '0';
txtArea.style.opacity = '0';
txtArea.value = text;
document.body.appendChild(txtArea);
txtArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
if (successful) {
return true;
}
} catch (err) {
console.log('Oops, unable to copy');
} finally {
document.body.removeChild(txtArea);
}
return false;
}
Change copyToClipboard
function as below to call the copyTextToClipboard function
copyToClipboard() {
this.textToCopy = this.text1 + this.text2 + this.text3;
var result = this.copyTextToClipboard(this.textToCopy);
if (result) {
this.toastr.info('Copied to Clipboard');
}
}
Upvotes: 20
Reputation: 1498
ngx-clipboard now doesn't require you to use input element. Now it's more straight forward and provide several ways of doing this. One way to do is simply use ClipboardService. From three, documentation
import { ClipboardService } from 'ngx-clipboard'
constructor(private _clipboardService: ClipboardService){
...
}
copy(text: string){
this._clipboardService.copyFromContent(text)
}
But in my case this didn't work. And I got some warnings at the compile time in angular that peer dependencies are not met. Since I was using Angular 4 these warning I expected. But there's a simple way to do this with @ViewChild if the above solution doesn't work for you.
in your html :
<textarea name="copyText" #copyText id="" style="opacity: 0;height: 0;"></textarea>
And in Component :
@ViewChild('copyText', { read: ElementRef }) copyText: ElementRef;
copyText() {
const element = this.copyText.nativeElement;
element.value = 'some text';
element.focus();
element.select();
document.execCommand('copy');
}
This is just simple vanilla javascript approach with Angular's @ViewChild
Upvotes: 3
Reputation: 176
The problem (later highlighted by the OP) of the approved answer, using NgxClipboard, is that the content could not be set dynamically.
Using a (click) event listener doesn't work, because it is triggered after ngxClipboard execution.
So, simply define [cbContent] with an @Input getter, and forget about the (click) event:
In the template:
<button ngxClipboard [cbContent]="foo">Click me</button>
In the component:
@Input()
get foo() {
// Dynamic generation of the text to put in the clipboard:
return this.text1 + this.text2 + this.text3
}
Upvotes: 0
Reputation: 3312
Here another quick and dirty option without the need of third-party libraries or modules. Taken from here
In your template
<a class="accent" (click)="copyLink(textToCopy)">{{textToCopy}}</a>
And in your component
copyLink(text:string) {
const event = (e: ClipboardEvent) => {
e.clipboardData.setData('text/plain', text);
e.preventDefault();
// ...('copy', e), as event is outside scope
document.removeEventListener('copy', e);
}
document.addEventListener('copy', event);
document.execCommand('copy');
}
Upvotes: 9
Reputation: 34673
You need to use ngxClipboard
directive with your image. This is how you need to use it to solve your issue:
<td>
<img src='./assets/Copy.gif' (click)="copyToClipboard()" ngxClipboard [cbContent]="textToCopy" />
</td>
Remember to add ClipboardModule
in your app module. Example code below:
import { ClipboardModule } from 'ngx-clipboard';
@NgModule({
imports: [
// Other Imports
ClipboardModule
],
// Other code
})
export class AppModule { }
Upvotes: 17
Reputation: 1134
This is the easiest way to copy to clipboard.
In your template
<button (click)="copyToClipboard(sharableLink)">Copy link</button>
<input type="text" value="This is the value to copy" #sharableLink>
In component
copyToClipboard(element) {
element.select();
document.execCommand('copy');
this.toaster('success', 'Success!', 'Link copied to clipboard.');
}
Upvotes: 15