web-dev-qa-db-fra.com

Angular 4 - Copier le texte dans le presse-papier

J'ai une icône cliquable sur la page. En cliquant sur cette icône, je voudrais construire du texte et le copier dans le presse-papier

<td><img src='./assets/Copy.gif' (click)="copyToClipboard()"  /></td> 

et dans la composante

  copyToClipboard() {
     this.textToCopy = this.text1 + this.text2 + this.text3;  
     this.toastr.info('Copied to Clipboard');
  }

J'ai examiné https://www.npmjs.com/package/ngx-clipboard . Cependant, ce package nécessite de faire référence à un élément d'entrée et de copier le texte à partir de cet élément d'entrée. Dans mon cas d'utilisation, le texte doit être créé dynamiquement, puis ajouté au Presse-papiers.

Puis-je utiliser ngx-clipboard pour copier dans le presse-papiers ou existe-t-il un autre package qui me permettrait d'y parvenir? 

16
kayasa

Vous devez utiliserngxClipboarddirective avec votre image. Voici comment l'utiliser pour résoudre votre problème: 

<td>
    <img src='./assets/Copy.gif' (click)="copyToClipboard()" ngxClipboard [cbContent]="textToCopy" />
</td> 

N'oubliez pas d'ajouterClipboardModuledans votre module d'application. Exemple de code ci-dessous:

import { ClipboardModule } from 'ngx-clipboard';

@NgModule({
  imports: [
    // Other Imports
    ClipboardModule
  ],
  // Other code
})
export class AppModule { }
12
Faisal

L'interaction de l'utilisateur est obligatoire pour exécuter document.execCommand, utilisé pour copier du texte dans le Presse-papiers. 

Voir ma réponse .

Si vous ne souhaitez utiliser aucune bibliothèque tierce, vous pouvez utiliser le fragment ci-dessous pour copier du texte dans le Presse-papiers.

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

Modifiez la fonction copyToClipboard comme ci-dessous pour appeler la fonction copyTextToClipboard

copyToClipboard() {
    this.textToCopy = this.text1 + this.text2 + this.text3;
    var result = this.copyTextToClipboard(this.textToCopy);
    if (result) {
        this.toastr.info('Copied to Clipboard');
    }
}
14
Gangadhar Jannu

C'est le moyen le plus simple de copier dans le presse-papier.

Dans votre template

<button (click)="copyToClipboard(sharableLink)">Copy link</button>
<input type="text" value="This is the value to copy" #sharableLink>

En composant

copyToClipboard(element) {
    element.select();
    document.execCommand('copy');
    this.toaster('success', 'Success!', 'Link copied to clipboard.');
  }
11

Voici une autre option rapide et sale sans avoir besoin de bibliothèques ou de modules tiers. Tiré d'ici

Dans votre template

<a class="accent" (click)="copyLink(textToCopy)">{{textToCopy}}</a>

Et dans votre composant

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');
    }
5
velval

ngx-clipboard ne vous oblige maintenant plus à utiliser un élément input. Maintenant, il est plus simple et offre plusieurs façons de le faire. Une façon de faire est simplement d'utiliser ClipboardService. À partir de trois, documentation 

import { ClipboardService } from 'ngx-clipboard'

constructor(private _clipboardService: ClipboardService){
...
}
copy(text: string){
  this._clipboardService.copyFromContent(text)
}

Mais dans mon cas, cela n'a pas fonctionné. Et au moment de la compilation, j’ai reçu des avertissements angulaires que les dépendances entre pairs ne sont pas satisfaites. Depuis que j'utilisais Angular 4, ces avertissements s’attendaient. Mais il existe un moyen simple de le faire avec @ViewChild si la solution ci-dessus ne vous convient pas. 

dans votre html:

<textarea name="copyText" #copyText id="" style="opacity: 0;height: 0;"></textarea>

Et en composant: 

@ViewChild('copyText', { read: ElementRef }) copyText: ElementRef;

copyText() {
    const element = this.copyText.nativeElement;
    element.value = 'some text';
    element.focus();
    element.select();
    document.execCommand('copy');
}

Ceci est juste une approche javascript simple de Vanilla avec @ViewChild d'Angular 

0
dilantha111

Le problème (mis en évidence ultérieurement par l'OP) de la réponse approuvée à l'aide de NgxClipboard est que le contenu n'a pas pu être défini de manière dynamique.

L'utilisation d'un écouteur d'événement (clic) ne fonctionne pas, car il est déclenché après ngxClipboard.

Donc, définissez simplement [cbContent] avec un getter @Input et oubliez l’événement (click):

Dans le modèle:

<button ngxClipboard [cbContent]="foo">Click me</button>

Dans le composant:

@Input()
get foo() {
    // Dynamic generation of the text to put in the clipboard:
    return this.text1 + this.text2 + this.text3
}
0
Philo