web-dev-qa-db-fra.com

Angular 5 - Copier dans le presse-papier

J'essaie d'implémenter une icône qui, une fois cliquée, enregistrera une variable dans le presse-papier de l'utilisateur. J'ai actuellement essayé plusieurs bibliothèques et aucune d'entre elles n'a été capable de le faire.

Comment copier correctement une variable dans le presse-papier de l'utilisateur dans Angular 5?

66
Sam Mallabone

Solution 1: Copiez n'importe quel texte

HTML

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

. ts fichier

copyMessage(val: string){
    let 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: Copier à partir d'une zone de texte

HTML

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

. ts fichier

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

démonstration ici


Solution 3: Importer une directive tierce partie ngx-clipboard

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

Solution 4: Directive personnalisée

Si vous préférez utiliser une directive personnalisée, vérifiez la réponse answer de Dan Dohotaru, une solution élégante mise en œuvre avec ClipboardEvent.

132

Je sais que cela a déjà été très voté ici, mais je préférerais une approche de directive personnalisée et compter sur ClipboardEvent comme le suggère @jockeisorby, tout en veillant à ce que l'auditeur soit correctement supprimé (la même fonction doit être fournie pour les écouteurs d'ajout et de suppression d'événement)

stackblitz démo

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

et ensuite l'utiliser comme tel

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

Remarque: notez que le window["clipboardData"] est nécessaire pour IE car il ne comprend pas e.clipboardData.

38
Dan Dohotaru

Je pense que c'est une solution beaucoup plus propre lors de la copie de texte:

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

Et ensuite, il suffit d'appeler copyToClipboard on click event en html. (click) = "copyToClipboard ('texttocopy')"

36
jockeisorby

Version modifiée de la réponse de jockeisorby qui corrige que le gestionnaire d'événements ne soit pas correctement supprimé.

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