Toggle table row based on if condition not working - html

Need to toggle one table row based on if condition not working.
If status id none I need to open a form in popup but if status is done popup shouldn't open.
<ng-container *ngFor="let person of personList |
searchFilter:searchValue;index as i">
<tr *ngIf="person.status == 'none'"
data-toggle="modal" data-target="#personModal"
(click)="function(person.id)">
<tr *ngIf="person.status == 'done'" >
<td>Place</td>
<td>Job</td>
</tr>
</tr>
</ng-container>
When I tried this solution the row is not displaying in the table list

Probably you should do something like this:
<ng-container *ngFor="let person of personList | searchFilter:searchValue;index as i">
<tr *ngIf="person.status == 'none'" data-toggle="modal" data-target="#personModal"
(click)="someFunction(person.id)">
<td>Place</td>
<td>Job</td>
</tr>
<tr *ngIf="person.status == 'done'" >
<td>Place</td>
<td>Job</td>
</tr>
</ng-container>
But it's important to see your TypeScript code. You should make a Stackblitz example.

Related

Angular material Table with expandable rows, automaticly expanded when change tabs With stackBlitz example

I have an Angular material table with expandable rows. In every row, I have multiple tabs,
On the first tab, I have another table with expandable rows. At the start al the rows are collapsed, so far so good. When I click a row, the row is expanded, again so far, so good. When I change tabs and come back, all my rows are expanded.
How can I solve this issue? The HTML code is like Angular material describes on their page for a table with expandable rows.
I created a StackBlitz with my problem, it is a less complicated file then what I'm having, but it has the same problem.
Result:
https://angular-wat7fa.stackblitz.io
Code:
https://stackblitz.com/edit/angular-wat7fa-wzk7sh?file=app/table-expandable-rows-example.html
After I switched tabs and return to the Messages tab
Part of my HTML file
<table
mat-table
[dataSource]="messages.results"
multiTemplateDataRows
class="mat-elevation-z0 messages-table"
>
<ng-container matColumnDef="enqueuedTimeUtc">
All my columns
</ng-container>
<ng-container matColumnDef="info">
<th mat-header-cell *matHeaderCellDef>Info</th>
<td mat-cell *matCellDef="let context">
<i
[appTooltip]="customerInfo"
[appTooltipContext]="context"
class="material-icons info-icon"
>info</i
>
</td>
</ng-container>
<ng-container matColumnDef="expandedDetail">
<td
mat-cell
*matCellDef="let element"
[attr.colspan]="displayedColumns.length"
class="locations-cell"
>
<div
class="example-element-detail"
[#detailExpand]="
element == expandedElement ? 'expanded' : 'collapsed'
"
>
<td-code-editor
[style.height.px]="200"
editorStyle="border:0;"
theme="vs"
[editorOptions]="editorOptions"
[(ngModel)]="element.messageBody"
>
</td-code-editor>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr
mat-row
*matRowDef="let element; columns: displayedColumns"
class="example-element-row"
[class.example-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element"
></tr>
<tr
mat-row
class="example-detail-row"
*matRowDef="let row; columns: ['expandedDetail']"
></tr>
</table>
<app-paginator
[itemsPerPage]="20"
[numberOfEntries]="messages?.totalCount"
[currentPage]="page$ | async"
(pageChanged)="pageChange$.next($event)"
></app-paginator>
Part of the Typescript file:
expandedElement = null;
I hope somebody can help me here.
I found my answer.
Apparentely I have to add <ng-template matTabContent></ng-template> to the <mat-tab>

Display more information after clicking in row of table in angular

I have a table which contains list of informations from the database my problem how I can display the information of each line ,below this line,in other words i want more information about this line.
I have already managed to display the information but below the table .
<tbody>
<ng-container>
<tr *ngFor="let affectation of affectations">
<td>{{affectation[1]}}</td>
<td>{{affectation[2] }}</td>
<td>{{affectation[3]}}</td>
<td><button type="button" class="btaction"
(click)="getAffectationForEmploye(affectation[0])">Actionner</button></td>
--after clicking show more information about the line of table 1
</tr>
--show informations about the line of table 1
<tr [hidden]="!visionnerTableau" class="trDisplay" *ngFor="let affecter of affecters">
<td>{{affecter.fiche.nom}}</td>
<td>{{affecter.fiche.prenom}}</td>
<td>{{affecter.fiche.produit.nom_produit}}</td>
</tr>
</ng-container>
</tbody>
you should place the first for loop on the ng-container and if you just want to show information of 1 line at a time, you can use the index for this and a selectedItemIndex in your component and probably an ngIf instead of hidden to only invoke getAffectationForEmploye for the selected item. So something like this:
<tbody>
<ng-container *ngFor="let affectation of affectations; let i = index;">
<tr>
<td>{{affectation[1]}}</td>
<td>{{affectation[2] }}</td>
<td>{{affectation[3]}}</td>
<td><button type="button" class="btaction"
(click)="selectedItemIndex = index;">Actionner</button></td>
--after clicking show more information about the line of table 1
</tr>
--show informations about the line of table 1
<ng-container *ngIf="selectedItemIndex === index">
<tr class="trDisplay" *ngFor="let affecter of getAffectationForEmploye(affectation[0])">
<td>{{affecter.fiche.nom}}</td>
<td>{{affecter.fiche.prenom}}</td>
<td>{{affecter.fiche.produit.nom_produit}}</td>
</tr>
</ng-container>
</ng-container>
</tbody>

How to display table row data based on headers sequence from json objects in Angular 6?

I am facing problem in showing dynamic table from JSON objects. I have two array. One array contains headers of the table and other array contains JSON objects.The problem is that I want the data to be shown in sequence of header array value from each JSON Object(each object is treated as row).
The code I have tried to show data is:
<table id="myTable">
<tr >
<th *ngFor="let head of FilteredKeys;let i =index" (click)="sortTable(i)">{{head}}</th>
</tr>
<tr *ngFor="let object of finalContactsArray;">
<td *ngIf="hasProp('FilteredKeys', 'id')">{{object.id}}</td>
<td *ngIf="hasProp('FilteredKeys', 'firstname')" >{{object.firstname}}</td>
<td *ngIf="hasProp('FilteredKeys', 'lastname')">{{object.lastname}}</td>
<td *ngIf="hasProp('FilteredKeys', 'prefix')">{{object.prefix}}</td>
</tr>
</table>
Filtered Key array is:
["id","firstname","prefix","lastname"]
finalContactArray is:
[{"id":"1","firstname":"Vikas"},{"id":"2","firstname":"Raj","lastname":""},{"id":"3","prefix":"Mr.","lastname":"sdsdfsd"},{"id":"4","prefix":"Mrs."},{"id":"5","firstname":"Hari","prefix":"Mr."}]
For demo of the problem the stackblitz is:
https://stackblitz.com/edit/angular-8cacgk
Here you can see that prefix column values are shown in lastname.How to get rid of this problem?
My working code:
<table id="myTable">
<tr >
<th *ngFor="let head of FilteredKeys;let i =index" (click)="sortTable(i)">{{head}}</th>
</tr>
<tr *ngFor="let object of finalContactsArray;">
<ng-container *ngFor="let head of FilteredKeys">
<td *ngIf="head==='id' && hasProp('FilteredKeys', 'id')">{{object[head]}}</td>
</ng-container>
<ng-container *ngFor="let head of FilteredKeys">
<td *ngIf=" head === 'prefix' && hasProp('FilteredKeys', 'prefix')" (click)="showalert()" style="cursor:pointer" >{{object[head]}}</td>
</ng-container>
<ng-container *ngFor="let head of FilteredKeys">
<td *ngIf=" head === 'firstname' && hasProp('FilteredKeys', 'firstname')" >{{object[head]}}</td>
</ng-container>
<ng-container *ngFor="let head of FilteredKeys">
<td *ngIf=" head === 'lastname' && hasProp('FilteredKeys', 'lastname')">{{object[head]}}</td>
</ng-container>
</tr>
If your data structure is this simple and the relationships are that direct, you can accomplish this with simple nested for loops:
<table id="myTable">
<tr >
<th *ngFor="let head of FilteredKeys;let i =index" (click)="sortTable(i)">{{head}}</th>
</tr>
<tr *ngFor="let object of finalContactsArray;">
<td *ngFor="let key of FilteredKeys"
(click)="key === 'prefix' && showalert()"
[ngStyle]="{'cursor': (key === 'prefix') ? 'pointer': 'default'}">
{{object[key] || ' '}}
</td>
</tr>
</table>
Just iterate through your rows and within rows iterate over your header keys to show the correct row property in the cell, and create cells for every column regardless of what the actual object contains. My example puts in a single space as a placeholder if no value for that column, but you could put whatever you want, all depends what your requirement is, but you need to create cells for every column, regardless of if the object has the property or not, otherwise the cells will never align correctly.

how to display only selected columns and ignore empty cells in html table using ngFor

I am trying to display specific columns in table in angular 2. So my table element looks like this:
<table class="ui single line table" id="tablej">
<tbody>
<tr *ngFor="let row of data;let i=index">
<td *ngFor="let val of row;let j=index" >
<div *ngIf="j<=2 || j==9 || j==17||j==20||j==21">
{{val}}
</div>
</td>
</tr>
</tbody>
</table>
I am getting empty spaces for skipped columns and my table became uneven. Is there any way to display specific columns and ignore the rest?
You can wrap your tr within a template tag to display or not display that column:
<template *ngFor="let row of data;let i=index">
<tr *ngIf="condition to display this column">
<td *ngFor="let val of row;let j=index" >
<div *ngIf="j<=2 || j==9 || j==17||j==20||j==21">
{{val}}
</div>
</td>
</tr>
</template>
The conditional row might be:
<template *ngFor="let row of data;let i=index">
<tr *ngIf="displayRow(row)">
<td *ngFor="let val of row;let j=index" >
{{val}}
</td>
</tr>
</template>
public displayRow(row):boolean {
return row.length <= 2 || row.length == 9 || row.length == 17 || row.length == 20 || row.length == 21
}
Hope that helps

AngularJS - Updating one element in ng-if causes all elements to get updated

I am using angluar2 and TypeScript to create a table. I couldn't figure out how to make the <select> in each <td> of the same row <tr> to be independent. My codes would allow user to pick an option from any column. Once a user pick an option, all columns in the same row will be updated.
<!--
public _tableHeaders: Array of Object;
public _rosters: Array of Object;
public _dutyOptions: Array of Object;
-->
<div class="row">
<table class="table">
<thead>
<tr>
<th style="width:55px" *ngIf="_tableHeaders"></th>
<!-- col for 'name'-->
<th style="width:10px" *ngFor="let hdr of _tableHeaders">
<div>{{hdr.DayOfMonth}}</div>
<div>{{hdr.DayOfWeek}}</div>
</tr>
</thead>
<tbody>
<tr *ngFor="let rosterList of _rosters">
<template ngFor let-roster="$implicit" [ngForOf]="rosterList">
<td *ngIf="roster.Switch == 'n'" style="width:55px">{{roster.DutyOption}}</td>
<td *ngIf="roster.Switch == 'c'" style="width:55px">{{roster.DutyOption}}</td>
<td *ngIf="roster.Switch == 'p'" style="width:10px">{{roster.DutyOption}}</td>
<td *ngIf="roster.Switch == 'u' && roster.UserId != _userId" style="width:10px">{{roster.DutyOption}}</td>
<td *ngIf="roster.Switch == 'u' && roster.UserId == _userId" style="width:10px">
<select class="form-control input-sm" [ngModel]="_selDutyOption" (ngModelChange)="updateUserRequest($event, roster)">
<option></option>
<option *ngFor="let dutyOption of _dutyOptions; let j=index" (ngValue)="dutyOption" [selected]="dutyOption.Id === roster.DutyOptionId ? true : false">{{dutyOption.Description}}</option>
</select>
</td>
</template>
</tr>
</tbody>
</table>
</div>
This is because you bind all the select elements with the same value:_selDutyOption, when one select changed, all will update.
Defining distinct models for each select element will solve your problem.