web-dev-qa-db-fra.com

Comment copier dans le presse-papiers dans Angular 2 Typescript?

Existe-t-il un moyen de copier du texte dans le Presse-papiers (multi-navigateur) dans le framework Angular2 TypeScript?

Je ne trouve que des sources d'utilisation de Javascript, par exemple.

document.execCommand('copy')
19
Andris Krauze

Vous pouvez implémenter une directive Angular2 autour de clipboard.js library.

Commencez par configurer la bibliothèque dans SystemJS:

<script>
  System.config({
    map: {
      clipboard: 'https://cdn.rawgit.com/zenorocha/clipboard.js/master/dist/clipboard.js'
    },
    packages: {
      'app': {
        defaultExtension: 'js'
      }
    } 
  });
  (...)
</script>

Nous voulons pouvoir attacher le Presse-papiers à un élément par le biais d'une directive et fournir en paramètre l'élément DOM avec lequel nous voulons créer un lien. La valeur spécifiée dans l'élément cible spécifié sera utilisée pour copier son texte. Voici un exemple d'utilisation:

<div>
  <input #foo/>
  <button [clipboard]="foo">Copy</button>
</div>

La mise en œuvre de la directive est la suivante:

import {Directive,ElementRef,Input,Output,EventEmitter} from 'angular2/core';
import Clipboard from 'clipboard';

@Directive({
  selector: '[clipboard]'
})
export class ClipboardDirective {
  clipboard: Clipboard;

  @Input('clipboard')
  elt:ElementRef;

  @Output()
  clipboardSuccess:EventEmitter<any> = new EventEmitter();

  @Output()
  clipboardError:EventEmitter<any> = new EventEmitter();

  constructor(private eltRef:ElementRef) {
  }

  ngOnInit() {
    this.clipboard = new Clipboard(this.eltRef.nativeElement, {
      target: () => {
        return this.elt;
      }
    });

    this.clipboard.on('success', (e) => {
      this.clipboardSuccess.emit();
    });

    this.clipboard.on('error', (e) => {
      this.clipboardError.emit();
    });
  }

  ngOnDestroy() {
    if (this.clipboard) {
      this.clipboard.destroy();
    }
  }
}

Voir cet exemple pour un exemple: https://plnkr.co/edit/elyMcP5PX3UP4RkRQUG8?p=preview .

34
Thierry Templier

Félicitations à @ThierryTemplier,

Sur la base de sa réponse, j'ai mis en place une directive et un partage sur github & npm.

Voici le projet sur github

MISE À JOUR: 30/04/2017

Cette bibliothèque ne dépend plus de clipboard.js. 

Juste angulaire!

23
maxisam

j'ai juste une méthode de https://github.com/pehu71/copy-component/blob/master/src/simple/copy.component.ts fonctionne même sur Android 4.1.2

copy(val) {

    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);
}
18
dimson d

Ceci est une simple solution pure Angular2 and javascript qui ne nécessite aucune bibliothèque et qui peut être utilisée dans un composant angulaire. Vous pouvez le transformer en un service ou le rendre plus générique si nécessaire, mais cela établira l'idée de base.

Actuellement, les navigateurs autorisent uniquement la copie de texte dans le presse-papiers à partir de Sélection dans un <input> ou <textarea>.

Dans le composant, faites quelque chose comme ça:

import {Inject} from "@angular/core";
import {DOCUMENT} from "@angular/platform-browser";

export class SomeComponent {
    private dom: Document;

    constructor(@Inject(DOCUMENT) dom: Document) {        
       this.dom = dom;
    }

    copyElementText(id) {
        var element = null; // Should be <textarea> or <input>
        try {
            element = this.dom.getElementById(id);
            element.select();
            this.dom.execCommand("copy");
        }
        finally {
           this.dom.getSelection().removeAllRanges;
        }
    }
}

Ensuite, dans le bloc html associé au composant, procédez comme suit:

<div>
   <button (click)="copyElementText('elem1')">Copy</button>
</div>
<textarea id="elem1">Some text</textarea>

C'est tout! Le bouton appelle la fonction copyElementText () de son composant et lui transmet l'identifiant de l'élément html pour extraire le texte et le copier dans le Presse-papiers.

La fonction utilise javascript standard pour obtenir l'élément par son ID, le sélectionner, exécuter la commande "Copier" sur la sélection, puis la désélectionner.

2
Cliff Ribaudo

Voici un code simple au cas où votre texte ne serait pas à l'intérieur d'une entrée ou d'une zone de texte, mais d'un div, ou de tout autre objet HTMLElement:

window.getSelection().selectAllChildren(document.getElementById('yourID');
document.execCommand("Copy");

Je n'ai pas pu utiliser la commande select() car elle n'était pas reconnue par Angular. J'espère que cela aide quelqu'un!

2
Pablo Quemé

Actuellement, seules les API les plus courantes sont implémentées, principalement pour pouvoir passer différentes implémentations lorsqu’elles sont exécutées sur le serveur (rendu côté serveur ( https://github.com/angular/universal ) dans un travail Web l'API n'est pas disponible. 

Je suis à peu près sûr qu'il n'y a encore rien pour l'API presse-papiers. Il est toutefois prévu d'implémenter plus de wrappers.

1
Günter Zöchbauer

Le code que vous avez mentionné est la bonne façon de le faire et cela peut aussi être fait dans Angular 2+.

Je ne sais pas ce que vous devez faire, mais si vous avez, par exemple, une entrée et un bouton:

(.html file)

<input id='inputId'></input>
<button (click)="copyToClipboard()'>click me</button>

alors tout ce que vous devez faire est:

(.ts file)

public copyToClipboard(): void {
  const inputElement = document.getElementById('inputId');
  (<any>inputElement).select();
  document.execCommand('copy');
  inputElement.blur();
}
0
pbialy

Voici un moyen d'y parvenir sans aucune dépendance externe ni création de faux éléments, uniquement en utilisant API Clipboard :

import { DOCUMENT } from '@angular/common';
import { Directive, EventEmitter, HostListener, Inject, Input, Output } from '@angular/core';

@Directive({
  selector: '[myClipboard]'
})
export class ClipboardDirective {

  @Input() myClipboard: string;
  @Output() myClipboardSuccess = new EventEmitter<ClipboardEvent>();

  constructor(@Inject(DOCUMENT) private document: Document) {}

  @HostListener('click')
  onClick() {
    this.document.addEventListener('copy', this.handler);
    this.document.execCommand('copy');
  }

  private handler = (e: ClipboardEvent) => {
    e.clipboardData.setData('text/plain', this.myClipboard);
    e.preventDefault();
    this.myClipboardSuccess.emit(e);
    this.document.removeEventListener('copy', this.handler);
  }

}

Puis-je utiliser l'API Presse-papiers?

0
s.alem

Il s’agit d’une simple solution purement Angular2 et javascript ne nécessitant aucune bibliothèque et pouvant être utilisée dans un composant angulaire. Vous pouvez le transformer en un service ou le rendre plus générique si nécessaire, mais cela établira l'idée de base.

Actuellement, les navigateurs autorisent uniquement la copie de texte dans le presse-papiers à partir de la sélection dans un fichier ou. Cela peut implémenté dans div 

(.html file)
<div id="inputId">Some texts</div>
<button (click)="copyToClipboard()'>click me</button>

//(.ts file)

public copyToClipboard(){
  var el = document.getElementById('inputId');
  el.setAttribute('contenteditable','true');
  el.focus();
  document.execCommand('selectAll');
  document.execCommand('copy');
  el.setAttribute('contenteditable','false');
  el.blur();
}
0
Shiju Augustine