How can I add a JavaScript-created element into a Primeng TurboTable component?

I am in the process of replacing a custom-made table with PrimeNG's turbotable. The issue I'm facing is that when I try to insert buttons into the table that call specific JavaScript functions, they end up displaying as [object HTMLInputElement] rather than actual buttons. This problem seems to occur because the turbotable converts the element into text instead of rendering it as HTML.

Here is an example of what is being displayed:

https://i.sstatic.net/YB50w.png

Below is the code for the turbotable:

<p-table [columns]="resultsCols" [value]="results">
  <ng-template pTemplate="caption">
    Agencies  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Count {{results?.length}}
  </ng-template>
  <ng-template pTemplate="header">
    <tr>
      <th >Options</th>
      <th [pSortableColumn]="'agency'" >Agency</th>
      <th [pSortableColumn]="'department'" class="ui-p-2">Department</th>
      <th [pSortableColumn]="'affiliateCount'" class="ui-p-4">Affiliate Count</th>
      <th [pSortableColumn]="'basigdate'" class="ui-p-6">BA Sig Date</th>
    </tr>
  </ng-template>
  <ng-template pTemplate="body" let-r>
    <tr>
      <td>  {{r.btnEdit}}</td>
      <td >{{r.agency}}</td>
      <td class="ui-p-2">{{r.department}}</td>
      <td class="ui-p-4">{{r.affiliateCount}}</td>
      <td class="ui-p-6">{{r.basigdate}}</td>
    </tr>
  </ng-template>
</p-table>

Here is how the button is generated and the results array populated:

var result = JSON.parse(xmlhttp.responseText);

for (var i = 0; i < result.length; i++) {

  var inputEdit = document.createElement("input");
  inputEdit.type = "button";
  inputEdit.value = "Edit";
  inputEdit.classList.add("btn-link");
  inputEdit.onclick = (
    function(i) {
      return function() {
        comp.setEditMode(i);
      }
    }
  )(result[i].id);


  var a = new agencySearchResult();
  a.agency = result[i].name;
  a.affiliateCount = result[i].affiliateCount;
  a.basigdate = result[i].baSigDate;
  a.department = result[i].department;
  a.btnEdit = inputEdit;

  comp.results.push(a); 
}

Finally, this is where the agencySearchResult class is defined in TypeScript:

export class agencySearchResult {
  constructor() {};

  agency: string;
  department: string;
  affiliateCount: string;
  basigdate: string;

  btnEdit: HTMLInputElement;
}

I suspect that the issue lies in the {{r.btnEdit}} line in the HTML code, but I have included all relevant information just in case. Can anyone provide guidance on how to properly insert a JavaScript-generated HTML element into a turbotable?

Answer №1

You might want to consider placing your HTML button within your component file rather than creating it in your TypeScript code.

Instead of:

<td>  {{r.btnEdit}}</td>

and

var inputEdit = document.createElement("input");
  inputEdit.type = "button";
  inputEdit.value = "Edit";
  inputEdit.classList.add("btn-link");
  inputEdit.onclick = (
    function(i) {
      return function() {
        comp.setEditMode(i);
      }
    }
  )(result[i].id);

You can replace them with something like:

<td><input type="button" value="Edit" class="btn-link" (click)="edit(r.id)"/></td>

and

edit(rowId) {
    alert('Edition of row ' + rowId);
    // do whatever you need
}

This approach is more concise and easier to read.

Check out this StackBlitz for reference.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for connecting to a property in another component

As a newcomer to Angular, I am exploring new concepts for the first time. I have a custom component called Timeselector with an Apply button whose enable/disable state is determined by validations performed in another custom component called Monthpicker. C ...

Display a fixed three levels of highchart Sunburst upon each click in Angular8

Looking to create a dynamic sunburst highchart that displays three levels at a time while allowing interactive drilling. For instance, if there are 5 levels, the chart should initially show the first three levels. When clicking on level 3, levels 2, 3, and ...

"Linking a Next.js application with Azure's Application Insights for advanced insights

Trying to include my Next.js (TypeScript) app logs in Azure Application Insights has been a bit challenging. The documentation provided poor guidance, so I decided to follow this solution: https://medium.com/@nirbhayluthra/integrating-azure-application-ins ...

Fetching data in VueJs before redirecting to a new page

Within the mounted function, I am creating an action that fetches data from a Rest API and populates my table in a Vue.js component mounted() { UserService.getProjects().then( (response) => { this.isProject = true; this.project ...

Alter the background color of a table cell in Angular HTML depending on a boolean value

Attempting to use Angular ng-class to set the background color of a table cell. I'm referencing code snippets from these resources: Angular: How to change the color of cell table if condition is true Change HTML table cell background color using ...

What is the best approach to testing the React Hook "useEffect" that is used to make an API call with Typescript?

Currently, I am working on writing Jest-enzyme tests for a basic React application using Typescript along with the new React hooks. The main issue I am facing is with properly simulating the api call made within the useEffect hook. Within the useEffect, ...

Attempting to integrate a new feature into the smart admin platform

I've been tasked with enhancing an existing website that was originally created using the Smart Admin template. My first step is to add a new component to the dashboard. Here are the specific commands and steps I followed: -Using the command line: ...

Retrieve recently appended DOM elements following the invocation of createComponent on a ViewContainerRef

I have a current function in my code that dynamically creates components and then generates a table of contents once the components are added to the DOM. This service retrieves all h3 elements from the DOM to include in the table of contents: generateDy ...

Leveraging Angular 8 for Multi-Tenancy Implementation

Currently, I am involved in a project that caters to multiple clients. Utilizing angular themes allows me to customize the background color, font, and other elements for each client. Additionally, I need to repurpose components by adjusting the text in var ...

Is there a way to retrieve the requested data in useEffect when using next.js?

As a newcomer to next.js and TypeScript, I am facing an issue with passing props from data retrieved in useEffect. Despite my attempts, including adding 'return scheduleList' in the function, nothing seems to work. useEffect((): (() => void) = ...

TS2307 error encountered in Angular 2 TypeScript due to the inability to locate a module for a private npm

I've been working on creating some components for internal company use, with the intention of sharing them through our private npm repository. However, I've hit a roadblock while trying to add these components to an app using npm and systemjs - I ...

Typescript - using optional type predicates

I'm looking to create a custom type predicate function that can accurately determine if a number is real and tighten the type as well: function isRealNumber(input: number | undefined | null): input is number { return input !== undefined && ...

Ways to conceal a component based on a specific condition?

In my Angular 8 application, I need to dynamically hide a component based on a specific condition. The condition I want to check is: "status === EcheqSubmissionStatus.EXPIRED" Initially, I attempted the following approach: EcheqProcessComponent templat ...

Angular 2 - Implementing a custom base view for all components within a specific directory

I'm currently working on an app that involves user authentication. Once users are logged in, they should have access to an admin sidebar for navigation. However, there are certain pages like Login and Register that won't require the sidebar. Furt ...

Ways to verify that the Google Analytics code is functioning properly within an Angular 2 application

I'm just getting started with Google Analytics and I'm attempting to integrate it into my Angular 2 project. Here's how I've set it up: app.component.ts import { Component } from '@angular/core'; import {Router, NavigationEn ...

Translate array into object with correct data types (type-specific method)

Welcome In our project, we have implemented attributes support where each attribute acts as a class. These attributes include information on type, optionality, and name. Instead of creating an interface for every entity, my goal is to automate this proces ...

Is there a way to automatically determine the parameters of a constructor to match the default class type in TypeScript

I need a function in a class that can utilize a type from constructor arguments, but I am unsure how to achieve this. class CustomClass<Type1, Type2=any>{ a: string = 'a' constructor(private readonly parameters: { attributes: Type ...

Guide to specifying the indexer type of a function argument as T[K] being of type X in order for t[k]=x to be a permissible expression

Currently, I am attempting to create a function that can alter a boolean property within an object based on the provided object and property name. While I have found some helpful information here, the function body is still producing errors. Is there a way ...

Vue version 3 is encountering an issue with a module that does not have an exported member in the specified path of "../../node_modules/vue/dist/vue"

After I updated my npm packages, errors started popping up in some of the imports from the 'vue' module: TS2305: Module '"../../node_modules/vue/dist/vue"' has no exported member 'X' The X instances affected inclu ...

The improper utilization or replacement of Jest mock in an Angular standalone component's unit test is causing issues

Presented here is a streamlined Ionic/Angular component with unnecessary code removed. import { IonicModule, ModalController } from '@ionic/angular'; @Component({ selector: 'my-component', templateUrl: 'my-component.html' ...