40

I have an angular component that allows a user to enter data into a textarea. There are two events tied to this keydown and paste. Both of these events trigger the same method which will try and determine the data entered.

The issue I am having is when the data is pasted paste, I am getting the value of the formControl but its the value BEFORE the data is pasted and doesn't include what I actually just entered into the field.

HTML

<textarea 
  formControlName="multiSearch" 
  class="form-control" 
  placeholder="Enter one or more values. One per line." 
  rows="6" 
  (keydown)="keyDownFunction($event)"
  (paste)="onPaste()">
</textarea>

Component

  /**
   * If we hit enter in our text area, determine the data type
   */
  keyDownFunction(event) {

    // Enter Key?
    if (event.keyCode == 13) {
      this.determineDataType();
    }
  }

  /**
   * If we paste data in our text area, determine the data type
   */
  onPaste() {
    this.determineDataType();
  }

  /**
   * Using regex, determine the datatype of the data and confirm with the user.
   */
  determineDataType() {
    console.log(this.searchForm.value.multiSearch)
  }

Question How can I get access to the data that is pasted into the form as soon as the paste event is fired and not what the value was before pasting?

SBB
  • 8,560
  • 30
  • 108
  • 223
  • Did you try using `[(ngModel)]` as attribute in text area element? [ngModel doc](https://angular.io/api/forms/NgModel). – Abel Valdez May 02 '18 at 16:05

2 Answers2

76

You can get the pasted content from the paste event and the updated content of the textarea by handling the input event:

<textarea #myText (paste)="onPaste($event)" (input)="onInput(myText.value)"></textarea>

with this code:

onPaste(event: ClipboardEvent) {
  let clipboardData = event.clipboardData || window.clipboardData;
  let pastedText = clipboardData.getData('text');
  ...
}

onInput(content: string) {
  ...
}

See this stackblitz for a demo.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
11

This is from an example with angular2 typescript that works for my project. Hope it helps someone. Logic is same for other cases as-well.

  1. angular-clipboard-event.html
<textarea placeholder="Type a message" (paste)="onPaste($event)"></textarea>
<!-- Place to render the image -->
<img #imgRenderer />
  1. angular-clipboard-event.ts
// Reference to the dom element
@ViewChild('imgRenderer') imgRenderer: ElementRef;

onPaste(event: any) {
    const items = (event.clipboardData || event.originalEvent.clipboardData).items;
    let blob = null;

    for (const item of items) {
      if (item.type.indexOf('image') === 0) {
        blob = item.getAsFile();
      }
    }

    // load image if there is a pasted image
    if (blob !== null) {
      const reader = new FileReader();
      reader.onload = (evt: any) => {
        console.log(evt.target.result); // data url!
        this.imgRenderer.nativeElement.src = evt.target.result;
      };
      reader.readAsDataURL(blob);
    }
  }
Sandeep K Nair
  • 2,512
  • 26
  • 26
  • Thanks @Sandeep, instead of Ctrl + V for pasting, have any method or code to handle from UI? – Alam Aug 07 '20 at 13:08