1

Angular (7) dynamic template (ng-template) rendering like ui grid cell template (template declared in colDefs of parent); I tried in so many ways since more than 30 days, watched ng-template rendering videos, articles, but could'not find any solution, kindly help me here.

Thanks in advance :)

app.component.ts

export class AppComponent implements OnInit {
name = 'Angular';
gridOptions:any;

constructor(private http: HttpClient){}


ngOnInit(){

  this.gridOptions = {
    colDefs:[
     {name:'id', displayName:'ID',width:80},
     {name:'name', displayName:'Name'},
     {name:'username', displayName:'Username', cellTemplate:'Static text from template'},
     {name:'email', displayName:'Email', cellTemplate:'{{row[col.name]}}'},  // i tried like this
     {name:'phone', displayName:'phone', cellTemplate:"<strong style='color:blue'> + row[col.name] + </strong>"}, // I need to achive this kind of template like ui grid for angularjs
     {name:'website', displayName:'website', cellTemplate:'row[col.name]'}, // i tried like this also
    ]
   }

   this.http.get("https://jsonplaceholder.typicode.com/users").subscribe((res) =>{
    this.gridOptions.data = res;
  });

 }

}

data-table.component.ts

export class DataTableComponent implements OnInit {
@Input() gridOptions: any = [];
  constructor() { } 
 
  ngOnInit() {}
}

data-table.component.html

<table>
    <tr>
        <th *ngFor="let col of gridOptions.colDefs">{{col.name}}</th>
    </tr>

    <tr *ngFor="let row of gridOptions.data ;let i = index">
        <td *ngFor="let col of gridOptions.colDefs">
            <ng-container *ngIf="!col.cellTemplate else myTemplate" [ngTemplateOutlet]="myTemplate">
                {{row[col.name]}}
            </ng-container>
            <ng-template #myTemplate row="row" col="col">
                {{col.cellTemplate}}
            </ng-template>

            <!-- <ng-template #myTemplate row="row" col="col" innerHTML="col.cellTemplate}"></ng-template> -->
        </td>
    </tr>
</table>

app.component.html

<app-data-table [gridOptions]="gridOptions"></app-data-table>

a busy cat

StackBlitz DEMO

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Gopala Raja Naika
  • 2,321
  • 23
  • 18
  • why didn't you add the cellTemplate to the template and add condition, instead of defining them in the ts file? – Nguyen Phong Thien Feb 14 '19 at 08:45
  • It should work for any time of cellTemplate for any kind of json like ui grid, I have to keep adding conditions for diff json service, here the **data-table** component should be common – Gopala Raja Naika Feb 14 '19 at 08:59

2 Answers2

4

Check out StackBlitz demo that I created for you. It's leverage the render function cellFn in which you can customize template as you please. Also notice the usage of safeHtml pipe to render html inside template.

EDIT: As the OP stated in comments, he also wants to use Angular directives etc. in template. So here is the StackBlitz demo for this purpose.

Bardr
  • 2,319
  • 2
  • 12
  • 21
  • wooww... thanks lot @**Bardr**, excellent answer, you have saved me time n mind from this big problem in angular project. just thanks is not enough to you.. god bless you.. – Gopala Raja Naika Feb 14 '19 at 10:18
  • @RajGopal No problem. I'm glad I helped. – Bardr Feb 14 '19 at 10:20
  • Hi @Bardr, I need one more help from you, ngClass is not working, could you pls check --------- `{ name: 'name', displayName: 'Name', cellFn: rowData => '${rowData.name}' }` – Gopala Raja Naika Feb 14 '19 at 11:53
  • I am not able to use any angular attributes in this case – Gopala Raja Naika Feb 14 '19 at 13:30
  • @RajGopal Yes, and this is obvious. They will be just rendered as a plain HTML. No magic here. Do you only need `[ngClass]` or more eloquent directives? `[ngClass]` equivalent can be simply made inside `cellFn` function. – Bardr Feb 14 '19 at 13:47
  • I need all ng directives, do we have any other method to achieve this kind of template definitions. Especially i need u use ngif, ngclass and ngmodel.. – Gopala Raja Naika Feb 14 '19 at 17:14
  • Thanks @Bardr, works perfectly as i expected, thank you so much for your help – Gopala Raja Naika Feb 21 '19 at 14:15
  • Hi @Bardr, this is not working in production, I am facing issue like "**Runtime compiler is not loaded**" after build --prod, Do you have any idea about this. – Gopala Raja Naika Mar 07 '19 at 09:32
  • @RajGopal Because you are compiling components dynamically, you need compiler. But in AOT (which is enabled by default by `--prod` flag), compiler is not included. Take a look here: https://stackoverflow.com/questions/42706113/angular-cli-build-prod-runtime-compiler-is-not-loaded/42843683 – Bardr Mar 07 '19 at 09:52
1

AS far as I know DataTables doesn't support any Angular magic. I handled similar problems with the render-functions which DataTables offers you: https://datatables.net/reference/option/columns.render#function

For example you would need to change the row:

{name:'email', displayName:'Email', cellTemplate:'{{row[col.name]}}'},

to:

{name:'email', displayName:'Email', render:(data, type, row, meta) => 'contact ' + row.name + ' via E-Mail'},

I hope this helps.

bb1
  • 141
  • 1
  • 10