Handling the Paste Event in Angular
After using a framework for a significant amount of time, you gain confidence that you understand it well. But you might still have incorrect assumptions which don't affect your work most of the time. I learned that about Angular recently when I wanted to handle the paste
event for an input
element.
For some reason I was convinced that the event binding syntax in templates works only for a predefined subset of standard DOM events for a specific HTML element. Since I couldn't find any examples of it being used for the paste
event, I was convinced that this wasn't supported.
In the search of an alternative approach, I learned about the listen
event on the Renderer2
class. Although a bit complicated to use, it was a working solution for my problem:
@ViewChild('input')
inputElement: ElementRef;
constructor(private renderer: Renderer2) { }
ngAfterViewInit(): void {
if (this.inputElement != null) {
this.renderer.listen(this.inputElement.nativeElement, 'paste', (event) => {
// handle the event
});
}
}
For the ViewChild
decorator to work, I had to create a variable for the referenced element in the HTML template:
<input #input>
After doing some more research, a finally learned that in the case of DOM elements, the event name in the event binding syntax will simply map to the name of the event for which a listener will be created. Hence, I could replace the above code with standard event binding syntax:
<input (paste)="onPaste($event)">
The event object passed to the function invoked will match the documented DOM event type, i.e. ClipboardEvent
in this case. Knowing that, you can make your code strongly typed:
onPaste(event: ClipboardEvent) {
this.pasteCount++;
this.pastedText = event.clipboardData.getData('text');
}
I still think that the documentation for the event binding syntax could make it more clear that any DOM event is supported. Well, at least I learned about Renderer2.listen
in the process. However, I'm still not sure what would be a good use case for it.