> For the complete documentation index, see [llms.txt](https://docs.gapvelocity.ai/webmap/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gapvelocity.ai/webmap/winforms/extend-or-modify-the-converted-application/adding-frontend-element-properties-and-js-listeners.md).

# Adding FrontEnd element properties and JS listeners

In some scenarios, the migrated application has client-side Javascript logic and you will need to update the implementation manually, this way you can use the migrated application components or use the "Angular way" to accomplish the legacy behavior and take full advantage of the new technology.

### Renderer

You can use Angular's [<mark style="color:red;">renderer</mark> ](https://angular.io/api/core/Renderer2)to add attributes, classes, styles or properties easily to an element.

For example, if you want to add a style or update a value you can use the renderer's `setStyle` and `setProperty` methods.

**Legacy JavaScript function:**

```javascript
function myFunction() {
    var tb = document.getElementById('textbox1');
    var inpName = document.getElementById('input1');

    tb.value = inpName.value;
    tb.style.fontWeight = 'bold';
    tb.style.color = 'green';
 }
```

**Legacy html:**

```html
<asp:TextBox ID="textbox1" runat="server">
</asp:TextBox>

<INPUT id="input1" type="hidden" value="0" runat="server" name="input1"/>
```

**Manually converted TypeScript method:**

```typescript
myFunction(): void {
    const tb = document.querySelector<HTMLInputElement>(
      "#textbox1 input" //textbox1 is a component, we need to access the root html element
    );
    const inpName = document.querySelector<HTMLInputElement>("#input1");

    this.render.setProperty(tb, "value", inpName.value);
    this.render.setStyle(tb, "fontWeight", "bold");
    this.render.setStyle(tb, "color", "green");
}
```

**Migrated html:**

```html
 <wm-asp-textbox #textbox1 id="textbox1" [model]="model.textbox1" class="textbox1">
 </wm-asp-textbox>
 
 <INPUT wmHtmlControl [model]="model.input1" id="input1" type="hidden" value="0" name="input1">
```

Remember that the "**renderer**" reference is usually in the migrated component constuctor or you can add it youself if needed.

```typescript
constructor (render: Renderer2, wmService: WebMapService, cdr: ChangeDetectorRef ,elem: ElementRef, webComponents: WebComponentsService) {
      super(wmservice,changeDetector,render2,elem,webComponents);
}
```

### JS Listeners

If you have custom listeners and they cannot be converted using the WebMAP infrastructure, you can select the specific element and use the [<mark style="color:red;">addEventListener</mark>](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)<mark style="color:red;">.</mark>

For example:

**Legacy click listener (jQuery):**

```javascript
$("#btn1").click(function (e) {
  // custom logic to be executed every time the button's click is triggered            
 });
```

**Legacy html:**

```html
<asp:LinkButton ID="btn1" runat="server"/>
```

**Manually converted TypeScript:**

```typescript
addBtnListener(): void {
    document.querySelector("#btn1 a").addEventListener("click", (event) => {
        // custom logic to be executed every time the button's click is triggered
    });
}
```

We added the click listener to the anchor element, but you can add any available event for a specific element.

**.html file:**

```html
<wm-link-button id="btn1" [model]="model.btn1" class="btn1">
</wm-link-button>
```

The addBtnListener should be called after the page's components are fully initialized. For this, we can use Angular's lifecycle hook **AfterViewInit.**

**.ts file:**

```typescript
ngAfterViewInit(): void {
    this.addBtnListener();
}
```
