Sudut 5 - Salin ke clipboard

124

Saya mencoba untuk menerapkan ikon yang ketika diklik akan menyimpan variabel ke papan klip pengguna. Saat ini saya telah mencoba beberapa perpustakaan dan tidak satupun yang mampu melakukannya.

Bagaimana cara menyalin variabel dengan benar ke papan klip pengguna di Angular 5?

anonim-dev
sumber
Anda dapat menggunakan ngxyz-c2c , ada beberapa cara untuk melakukannya.
Ankit Singh
Jika Anda menggunakan Angular Material, maka versi 9.0.0 (dirilis 6 Februari 2020) memperkenalkan paket papan klip yang sangat mudah digunakan . Lihat dokumentasi Angular dan jawaban @ Nabel .
George Hawkins

Jawaban:

236

Solusi 1: Salin teks apa pun

HTML

<button (click)="copyMessage('This goes to Clipboard')" value="click to copy" >Copy this</button>

file .ts

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);
  }

Solusi 2: Salin dari TextBox

HTML

 <input type="text" value="User input Text to copy" #userinput>
      <button (click)="copyInputMessage(userinput)" value="click to copy" >Copy from Textbox</button>

file .ts

    /* To copy Text from Textbox */
  copyInputMessage(inputElement){
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }

Demo Disini


Solusi 3: Impor arahan ngx-clipboard pihak ketiga

<button class="btn btn-default" type="button" ngxClipboard [cbContent]="Text to be copied">copy</button>

Solusi 4: Petunjuk Kustom

Jika Anda lebih suka menggunakan arahan khusus, Periksa jawaban Dan Dohotaru yang merupakan solusi elegan yang diterapkan menggunakan ClipboardEvent.

Sangram Nandkhile
sumber
1
Ide bagus, tapi saya menyalin solusi kedua Anda dan saya terus mendapatkan Cannot read property 'select' of undefinedsudut 6. Apakah ini kompatibel dengan angular6?
slevin
1
@slevin Saya rasa ini tidak terkait dengan versi sudut dengan cara apa pun. Apakah Anda menambahkan `# userinput` ke masukan Anda?
Sangram Nandkhile
1
@SangramNandkhile Saya memeriksa lagi dan lagi, tetapi masih kesalahan yang sama. Ini adalah kode saya <input *ngIf="invitation_code" type="text" readonly value="{{invitation_code}}" #userinput > <button *ngIf="code_success" (click)="copyInputMessage(userinput)" value="click to copy" > Copy code </button>Terima kasih
slevin
Anda bahkan dapat menghapus position, left, top, dan opacity. dan menggantinya denganselBox.style.height = '0';
Mendy
masalah kecil, harus menggunakan const tidak membiarkan
Stephen DuMont
70

Saya tahu ini sudah banyak dipilih di sini sekarang, tetapi saya lebih suka menggunakan pendekatan direktif kustom dan mengandalkan ClipboardEvent seperti yang disarankan @jockeisorby, sambil juga memastikan pendengar dihapus dengan benar (fungsi yang sama perlu disediakan untuk event listener add dan remove)

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);
  }
}

dan kemudian menggunakannya seperti itu

<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`);
}

Catatan: perhatikan yang window["clipboardData"]diperlukan untuk IE karena tidak mengertie.clipboardData

Dan Dohotaru
sumber
3
Kudos karena menjadikan ini arahan yang dapat digunakan kembali. Ide yang hebat!
Batang
1
memang, dimulai dengan versi 12.x sesuatu, Safari kembali bermasalah :)
Dan Dohotaru
2
solusi minimal adalah membuat rentang dan menambahkan rentang tersebut ke pilihan, solusi yang berfungsi akan terlihat seperti ini stackblitz.com/edit/angular-labs-copy-clipboard-r1
Dan Dohotaru
window ["clipboardData"] tidak ditentukan untuk saya di IE? Ada ide ?
Victor Jozwicki
tidak berfungsi di perangkat seluler, saya menggunakan plugin ngx-clipboard
the-catalin
50

Saya pikir ini adalah solusi yang jauh lebih bersih saat menyalin teks:

copyToClipboard(item) {
    document.addEventListener('copy', (e: ClipboardEvent) => {
      e.clipboardData.setData('text/plain', (item));
      e.preventDefault();
      document.removeEventListener('copy', null);
    });
    document.execCommand('copy');
  }

Dan kemudian panggil copyToClipboard pada acara klik di html. (klik) = "copyToClipboard ('texttocopy')"

jockeisorby
sumber
2
tidak berfungsi di IE karena fakta bahwa e.clipboardData tidak ditentukan.
Dan Dohotaru
9
Selain itu, pendengar ulang juga tidak berfungsi karena pendengar asli perlu diteruskan sebagai argumen
Dan Dohotaru
2
Lihat di sini untuk cara membuat listener acara hapus berfungsi: stackoverflow.com/a/51843984/3849445
pengguna123959
Bekerja dengan baik di Angular 6! Diuji di Chrome. Terima kasih.
moreirapontocom
16

Pada Angular Material v9, sekarang memiliki CDK clipboard

Papan klip | Bahan Sudut

Ini dapat digunakan sesederhana

<button [cdkCopyToClipboard]="This goes to Clipboard">Copy this</button>
Nabel
sumber
Ini bekerja seperti pesona. Tidak pernah tahu ada solusi yang tepat!
Abdullah Feroz
1
tersedia dari Angular Material v9.
andreivictor
14

Versi modifikasi dari jawaban jockeisorby yang memperbaiki pengendali kejadian tidak dihapus dengan benar.

copyToClipboard(item): void {
    let listener = (e: ClipboardEvent) => {
        e.clipboardData.setData('text/plain', (item));
        e.preventDefault();
    };

    document.addEventListener('copy', listener);
    document.execCommand('copy');
    document.removeEventListener('copy', listener);
}
John
sumber
1
Tidak berfungsi di Firefox. Kesalahan -document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler
OPTIMUS
3

Anda dapat mencapai ini menggunakan modul Angular:

navigator.clipboard.writeText('your text').then().catch(e => console.error(e));
Anantharaman Krishnamoorthy
sumber
1

Metode di bawah ini dapat digunakan untuk menyalin pesan: -

export function copyTextAreaToClipBoard(message: string) {
  const cleanText = message.replace(/<\/?[^>]+(>|$)/g, '');
  const x = document.createElement('TEXTAREA') as HTMLTextAreaElement;
  x.value = cleanText;
  document.body.appendChild(x);
  x.select();
  document.execCommand('copy');
  document.body.removeChild(x);
}
Durgesh Pal
sumber
Ini memang solusi yang bagus. Saya mencobanya untuk aplikasi saya dan berhasil. Terima kasih.
jaihind
1

Cara terbaik untuk melakukan ini di Angular dan menjaga kodenya tetap sederhana adalah dengan menggunakan proyek ini.

https://www.npmjs.com/package/ngx-clipboard

    <fa-icon icon="copy" ngbTooltip="Copy to Clipboard" aria-hidden="true" 
    ngxClipboard [cbContent]="target value here" 
    (cbOnSuccess)="copied($event)"></fa-icon>
Rahul Basu
sumber
1

Salin menggunakan cdk sudut,

Module.ts

import {ClipboardModule} from '@angular/cdk/clipboard';

Salin string secara terprogram: MyComponent.ts,

class MyComponent {
  constructor(private clipboard: Clipboard) {}

  copyHeroName() {
    this.clipboard.copy('Alphonso');
  }
}

Klik salah satu elemen untuk disalin melalui HTML:

<button [cdkCopyToClipboard]="longText" [cdkCopyToClipboardAttempts]="2">Copy text</button>

Referensi: https://material.angular.io/cdk/clipboard/overview

Chandrahasan
sumber
0

Solusi yang disarankan pertama kali berhasil, kita hanya perlu mengubahnya

selBox.value = val;

Untuk

selBox.innerText = val;

yaitu,

HTML:

<button (click)="copyMessage('This goes to Clipboard')" value="click to copy" >Copy this</button>

file .ts:

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.innerText = val;
    document.body.appendChild(selBox);
    selBox.focus();
    selBox.select();
    document.execCommand('copy');
    document.body.removeChild(selBox);
  }
Shreeketh K
sumber