Reputation: 1899
I'm trying to create dinamically the elements of a table and I have a doubt.
How can I create new <tr>
for example each 4 <td>
and then continue creating new <td>
<table>
<tr>
<td class="category-card" *ngFor= "let category of categories">
<img class="product-card-image" src="{{category.icon}}">
<span class="barImage">{{category.title}}</span>
</td>
</table>
EDIT:
<table>
<ng-template *ngFor="let category of categories; let i = index">
<tr *ngIf="(i % 4) == 0">
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/{{category.icon}}.png">
<span class="barImage">{{category.titulo}}</span>
</td>
</tr>
</ng-template>
</table>
EDIT2: I've added
<table [outerHTML]="categorias | dynamicTablePipe"></table> on my html
This is a external class (I've declared on NGModule)
@Pipe({
name: 'dynamicTablePipe'
})
export class DynamicTablePipe implements PipeTransform{
transform(contents) {
let template = ``;
let index = 0;
for (let content of contents) {
let currentTemplate = ``;
if (index === 0) {
// check if first record
currentTemplate = `
<tr>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/${content.icono}.png">
<span class="barImage">${content.titulo}</span>
</td>`;
} else if ((index % 4) === 0) {
// check if multiple of 4
currentTemplate = `
</tr>
<tr>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/${content.icono}.png">
<span class="barImage">${content.titulo}</span>
</td>`;
} else {
// normal row
currentTemplate = `
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/${content.icono}.png">
<span class="barImage">${content.titulo}</span>
</td>`;
}
index++;
template += currentTemplate;
}
return template;
}
}
The code inside of the pipe works fine, this is the template string formed at the end:
<tr>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/smartphone.png">
<span class="barImage">Telefonia</span>
</td>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/gamepad.png">
<span class="barImage">Videojuegos</span>
</td>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/laptop.png">
<span class="barImage">Portatiles</span>
</td>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/speaker.png">
<span class="barImage">Reproductores</span>
</td>
</tr>
<tr>
<td class="product-card">
<img class="product-card-image" src="/app/assets/img/link.png">
<span class="barImage">Redes</span>
</td></tr>
The problem is in the moment to return
thanks
Upvotes: 1
Views: 4548
Reputation: 482
This is how i resolved, it is not optimized solution but I got resolved. Hope helps you.
<table class="table table-bordered">
<ng-container *ngFor="let item of categories; let i = index">
<tr *ngIf="((i % 4) == 0)">
<ng-container *ngFor="let item of categories; let j = index">
<td *ngIf="j >= i && j < i+4">
<label>
<input type="checkbox" [value]="item.id">{{item.name}}
</label>
</td>
</ng-container>
</tr>
</ng-container>
</table>
Upvotes: 0
Reputation: 20005
Instead of using the *ngFor
in the <tr>
or <td>
, use it in <template>
and depending on the index
or amount of records found you could chose to render <td>
or <tr>
.
Follow this tutorial/guide that explains this exact thing: https://toddmotto.com/angular-ngfor-template-element
Rememeber to use <ng-template>
for Angular v4 or <template>
for Angular v2.
At the end, you could have something like:
<ng-template ngFor let-i="index" let-c="count" let-contact [ngForOf]="contacts | async">
<tr *ngIf="if((i % 4) == 0)">
// Check if index is multiple of 4
</tr>
</ng-template>
This final example is the final code of the tutorial/guide I linked you. I used it so when you get to this point you have a friendly code.
Option 2:
Using <template>
you could build a directive to render the data.
So you would have something like:
<template [myDirective]="myData"></template>
And in your myDirective
logic you chose how to render data using an index within the data loop.
Option 3 - @Pipe:
The @Pipe
could be the right one! You could try something like this:
@Pipe({
name: 'renderTable'
})
class RenderTable {
transform(content) {
let template = ``;
let index = 0;
for (let row in content) {
let currentTemplate = ``;
if (index === 0) {
// check if first record
currentTemplate = `
<tr>
<td>${row}</td>`;
} else if ((index % 4) === 0) {
// check if multiple of 4
currentTemplate = `
</tr>
<tr>
<td>${row}</td>`;
} else {
// normal row
currentTemplate = `
<td>${row}</td>`;
}
index++;
template += currentTemplate;
}
return template;
}
}
In your table, something like:
<table [outerHTML]="categories | renderTable"></table>
Update:
Try with innerHTML
:
<table [innerHTML]="categories | renderTable"></table>
Update 2:
For the style losing issue, here is the solution! Found it!
In RC.1 some styles can't be added using binding syntax
Upvotes: 1