How To Add Event Listener For Button Click In SPFX Webpart

Scenario
 
Suppose you are developing an SPFx web part. A part of the requirement is to get data from the user through a basic input form and a button. On the click of the button, you want to call and run your custom code, maybe saving data to SP via REST API or anything.
 
In this article, we will see how to add HTML input controls like textarea and a button. On click of the button, we want to read data from input controls and use this user inputted data as per our requirement.
 
This article assumes you have already created an SPFx web part without any JavaScript framework selected. You would see render method in your WebPart.ts file. Replace it with the below code in the render method.
  1. public render(): void {  
  2.   
  3. // HERE WE ARE ADDING TEXT AREA CONTROL.  
  4.   this.domElement.innerHTML += '<textarea id ="headerText" rows = "5" cols = "50" name = "description">Enter Header HTML</textarea>'
  5.   this.domElement.innerHTML += '<button type="button" id="btnRegister">Click Me!</button>';  
  6.   this._setButtonEventHandlers();  
  7.  }  
  8.   // METHOD TO BIND EVENT HANDLER TO BUTTON CLICK
  9.  private _setButtonEventHandlers(): void {  
  10.    const webPart: WpConfigureApplicationCustomizerWebPart = this;  
  11.    this.domElement.querySelector('#btnRegister').addEventListener('click', () => {  
  12.   
  13.               var headtext =  document.getElementById("headerText")["value"] ;  
  14.               alert(headtext);  
  15.   
  16.     }); 
  17. }  
Some notes in the above code.
  • If you use an onclick event in button HTML control and try to call your custom JavaScript function, it will not execute because the browser will block it with the below error. That is the reason we have to use another approach to add an event listener to the button.

    Refused to execute inline event handler because it violates the following Content Security Policy directive: "default-src 'self' blob: filesystem: chrome-extension-resource:". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

  • To get an instance of input control, you have to go with traditional JavaScript but to read the value, it has to be accessed by properties array like below. We cannot access it with the ‘.value’ way.

    var headtext = document.getElementById("headerText")["value"] ;

This solution is using no JavaScript framework. With React and KnockoutJS, it would be different.
This might be one of the solutions; however, there may be some other ways. Please comment if you find any other way.
I hope this helps...Happy coding!