Issue while printing in HTML - html

I am getting an array of users in response and there is one more array of roles in that respose and I want to print that role in my HTML.
Response :
User
email : "musaevt#yahoo.com"
firstName : "Timur"
fullName : "Timur Musaev"
id : "auth0|5a1ff162a916760a80b8b838"
lastName : "Musaev"
roles : Array(2)
0 : "Student"
1 : "Guest"
HTML :
<tbody>
<tr *ngFor="let user of users
| hipUsersSorter: key: direction
| paginate: { id: 'server', itemsPerPage: usersPerPage, currentPage: currentPage, total: totalUsers }">
<td>{{ user.lastName }}</td>
<td>{{ user.firstName }}</td>
<td>{{ user.email }}</td>
<td *ngFor ="let role of user.roles" >
{{ role | translate }}
</td>
<td>
<button md-icon-button color="primary" [routerLink]="[ '/users/edit-user', user.id ]">
<md-icon>edit</md-icon>
</button>
</td>
</tr>
</tbody>
I am able to print this but because of 2 values in roles array, it is creating a new column and alignment gets changed. How can i print those two roles without changing the alignment of my edit button?

What about not looping on the td, but rather create a looping span inside the td?
<td>
<span *ngFor ="let role of user.roles" >
{{ role | translate }}
</span>
</td>
Here's the full HTML code:
<tbody>
<tr *ngFor="let user of users
| hipUsersSorter: key: direction
| paginate: { id: 'server', itemsPerPage: usersPerPage, currentPage: currentPage, total: totalUsers }">
<td>{{ user.lastName }}</td>
<td>{{ user.firstName }}</td>
<td>{{ user.email }}</td>
<td>
<span *ngFor ="let role of user.roles" >
{{ role | translate }}
</span>
</td>
<td>
<button md-icon-button color="primary" [routerLink]="[ '/users/edit-user', user.id ]">
<md-icon>edit</md-icon>
</button>
</td>
</tr>

Related

Display multi arrays with rowspan in angular

Hi I am trying to create a table with rowspan based on array lengths. It works for me with 2 nested arrays but I have no idea ho to do it with more nest levels.
For data:
data = [
{ id: 1, name: 'one', groups:
[{'name': 'gr1', campaigns :
[{'name' : 'camp1'}, {'name' : 'camp2'}, {'name' : 'camp3'}]},
{'name': 'gr2', campaigns :
[{'name' : 'camp4'}, {'name' : 'camp5'}, {'name' : 'camp6'}]}
] },
{ id: 2, name: 'two', groups: [{'name': 'gr3', campaigns : [{'name' : 'camp7'}]}] },
{ id: 3, name: 'three', groups: [{'name': 'gr4', campaigns : [{'name' : 'camp8'}]}] },
{ id: 4, name: 'four', groups: [{'name': 'gr5', campaigns : [{'name' : 'camp9'}]}] }
];
I tried:
<table class="table table-bordered table-hover hidder" id="report">
<!-- Header -->
<tr>
<th >Project</th>
<th>Group</th>
<th>Camps</th>
</tr>
<ng-container *ngFor="let project of data; let i = index;">
<tr>
<td [attr.rowspanspan]="project.groups.length"> {{project.name}} </td>
<ng-container *ngFor="let group of project.groups; let j = index">
<tr>
<td>
{{ group.name }}
</td>
<!-- <ng-container *ngFor="let campaign of group.campaigns; let k = index">
<tr>
<td >
{{ campaign.name }}
</td>
</ng-container> -->
</tr>
</ng-container>
</ng-container>
</table>
My goal is to get table like this in picture:
image example
For exampleI have code here:
working code example
The nature of the table structure in HTML makes it quite difficult to split it programmatically. You could try the following, but then you'll have to style the table yourself:
<table class="table table-bordered table-hover hidder" id="report">
<!-- Header -->
<tr>
<th>Project</th>
<th>Group</th>
<th>Camps</th>
</tr>
<ng-container *ngFor="let project of data; let i = index">
<tr>
<td>{{ project.name }}</td>
<td>
<table>
<ng-container *ngFor="let group of project.groups; let j = index">
<tr click="test(group);">
<td>{{ group.name }}</td>
</tr>
</ng-container>
</table>
</td>
<td>
<table>
<ng-container *ngFor="let group of project.groups; let j = index">
<ng-container *ngFor="let campaign of group.campaigns; let k = index">
<tr click="test(group);">
<td>{{ campaign.name }}</td>
</tr>
</ng-container>
</ng-container>
</table>
</td>
</tr>
</ng-container>
</table>
Check out the StackBlitz example.
Should be [attr.rowspan], but I think you should remove it, see your forked stackblitz.
NOTE: I added in the .css to override the bootstrap padding of a table
.table > :not(caption) > * > *
{
padding:0 .5rem;
}
NOTE2: we use [attr.rowspan] if we have a "flat" array, like this another SO. not when we have an array with "groups"

While expanding a table row, it changes the expand/collapse icons of all the rows altogether

On click of a table row icon of expand and collapse, it expands/collapses that particular row but it changes expand/collapse icon of all the rows. Kindly provide a solution so that it changes only one icon that is clicked.
Here is the sample code:
component.ts:
collapse:boolean =true;
==================
Html:
<tr *ngFor="let user of users | listFilterCommon: searchTerm | tableFilterCommon: loantype| slice: (page-1) * pageSize : page * pageSize; index as i">
<!--<th scope="row">{{ (page -1) * pageSize + i + 1 }}</th>-->
<td>
{{ user.borrowerName }}
<tr>
<div class="collapse" id="collapse{{user.id}}">
<p style="font-size:10px;">
ABC......
</p>
</div>
</tr>
</td>
<td>{{ user.reviewName }}</td>
<td>{{ user.exposure | number }}</td>
<td>{{ user.loantype }}</td>
<td><a (click)="collapse=!collapse" class="btn" data-bs-toggle="collapse" href="#collapse{{user.id}}"
role="button" aria-expanded="false" aria-controls="collapse">
<i class="bi" [ngClass]="{'bi-plus': collapse, 'bi-dash': !collapse}"></i>
</a>

How to design a html table as like this image with angular?

I am trying a to create a html table in angular. I have a json which included below. In json first have asset head and asset head sub list. Under asset head sub list have account head list.
I want to design a html table by this json.
json
[
{
assetHead: 'Fixed Asset',
assetSubHeadList: [
{
subHead: 'Property, Plant & Equipment',
accountHeadList : [
{
accId: 101234,
accName: 'Office Equipment',
obDebit: 72045,
obCredit: 0,
cpDebit: 0,
cpCredit: 0,
cbDebit: 75845,
cbCredit: 0
},
{
accId: 101234,
accName: 'Motor Vehicle',
obDebit: 72045,
obCredit: 0,
cpDebit: 0,
cpCredit: 0,
cbDebit: 75845,
cbCredit: 0
},
]
},
],
}
];
Table design will be like this image
Firtly, for perfomance optimization I would create a pure pipe for sum calculation:
sum.pipe.ts
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'sum'
})
export class SumPipe<T> implements PipeTransform {
transform(arr: Array<{ [k in keyof T]: number }>, prop: keyof T): any {
return arr.reduce((sum, cur) => sum + cur[prop], 0);
}
}
then if you're aware of colspan and rowspan attributes it should be easy to implement your design:
<table>
<thead>
<tr>
<td rowspan="2">Acc Ca</td>
<td rowspan="2">Accounts Head</td>
<td colspan="2">Opening Balance Period</td>
<td colspan="2">Current Period</td>
<td colspan="2">Closing Balance</td>
</tr>
<tr>
<td>Debit</td>
<td>Credit</td>
<td>Debit</td>
<td>Credit</td>
<td>Debit</td>
<td>Credit</td>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let asset of json">
<tr>
<td colspan="8">{{ asset.assetHead }}</td>
</tr>
<ng-container *ngFor="let subHeadItem of asset.assetSubHeadList">
<tr>
<td colspan="8">{{ subHeadItem.subHead }}</td>
</tr>
<tr *ngFor="let headItem of subHeadItem.accountHeadList">
<td>{{ headItem.accId }}</td>
<td>{{ headItem.accName }}</td>
<td>{{ headItem.obDebit }}</td>
<td>{{ headItem.obCredit }}</td>
<td>{{ headItem.cpDebit }}</td>
<td>{{ headItem.cpCredit }}</td>
<td>{{ headItem.cbDebit }}</td>
<td>{{ headItem.cbCredit }}</td>
</tr>
<tr>
<td colspan="2"><b>Sub total</b></td>
<td>{{ subHeadItem.accountHeadList | sum: 'obDebit' }}</td>
<td>{{ subHeadItem.accountHeadList | sum: 'obCredit' }}</td>
<td>{{ subHeadItem.accountHeadList | sum: 'cpDebit' }}</td>
<td>{{ subHeadItem.accountHeadList | sum: 'cpCredit' }}</td>
<td>{{ subHeadItem.accountHeadList | sum: 'cbDebit' }}</td>
<td>{{ subHeadItem.accountHeadList | sum: 'cbCredit' }}</td>
</tr>
</ng-container>
</ng-container>
</tbody>
</table>
Ng-run Example

Angular 1.4: Render HTML in variable

I have the following Angular code:
<tr dir-paginate="item in file.messages | orderBy: orderByField: orderByReversed | itemsPerPage: 10: 'fileMessages'" pagination-id="fileMessages">
<td>{{ item.id }}</td>
<td>{{ item.created_at }}</td>
<td><span data-ng-class="['label', 'label-' + item.type]">{{ item.type }}</span></td>
<td>{{ item.message }}</td>
</tr>
Now the item.message contains some html which is coming from back end of the application which is in Laravel. How to render the html in Angular? I have tried ng-bind-html but to no avail. Any solutions or alternate to this approach?
Depending on your version of angular, you can use :
<td [innerHTML]="item.message"></td>
Angular will sanitize your content (remove for example) for security purposes.

Is there a way I can incorporate mailto links with ngFor?

I create an Object and use ngFor to loop through it and create a table. I would like to somehow incorporate mailto links if possible.
I have this finalResults object that looks something like this:
[
{key: 'example#example.com', value: 'message'}
]
Where message is something like
"Please contact the Login Team for help."
I would like to make Login Team a mailto link.
I have already tried making the message like this
Please contact the Login Team for help.
But on the webpage it just displayed that exactly. There was no link.
I use ngFor to loop through my object and make a table.
< <tr>
<th *ngFor="let col of displayedColumns">
{{ col }}
</th>
</tr>
<tr *ngFor="let item of finalResults">
<td>{{ item.key }}</td>
<td>{{ item.value }}</td>
</tr>
<tr></tr>
</table>
Is there some way to do this?
If you want to keep your text as html text then consider using innerHTML binding:
ts
finalResults = [
{
key: 'example#example.com',
value: 'Please contact the Login Team for help.'
}
];
html
<td [innerHTML]="item.value"></td>
Ng-run Example
In component declare
email: string = 'mailto:misesasd#gmail.com'
in template:
<a [href]="email">misesasd#gmail.com</a>
array:
<tr *ngFor="let item of finalResults">
<td><a [href]="item.key">{{item.key}}</a></td>
<td>{{ item.value }}</td>
</tr>
or:
<tr *ngFor="let item of finalResults">
<td>{{item.key}}</td>
<td>{{ item.value }}</td>
</tr>
<tr *ngFor="let item of finalResults">
<td>{{ item.value }}</td>
</tr>