Having Tables inside NgFor with same height - javascript

I have an ngFor which will iterate number of tables for me,In my case 3(not static) tables will be generated with the ngFor i am using, and inside the table I have rows that are to be generated, using another ngFor, but now, the problem, if my first is having less amount of data, say 2 rows of data, and my third table is having 6 rows of data, then the height of tables isn't constant.
Expected Solution: All tables should be of equal height, if table 3 has 6 rows, then table 1 and table 2 should also have 6 rows, Lets keep the rows the static, i mean irrespective of data, each table should be able to show 6 rows. if table 2 has data for 2 rows then remaining 4 rows should be empty.
<div
class="shift-table"
[ngClass]="{ disablePreviousRecord: isPreviousWeekRecord }"
[attr.disabled]="isPreviousWeekRecord"
>
<div class="shift-name " *ngFor="let roster of rosterInfo">
<span>Shift - {{ roster.shiftName }}</span>
<table
class="table scrollbar"
id="customScrollDiv"
style="background-color: white; color:#EBF4FF"
>
<thead style="background-color: #9AA7C7;">
<tr class="header">
<th>
Copy
</th>
<th>
Person Name
</th>
<th>
Role
</th>
</tr>
</thead>
<tbody class="text-black-50">
<tr class="dataRow" *ngFor="let user of roster.userDetails">
<td>
<input type="checkbox" [disabled]="isPreviousWeekRecord" />
</td>
<td>
{{ user.userId }}
</td>
<td>
<span *ngFor="let role of user.roles; let i = index">
{{ role }} {{ i === user.roles.length - 1 ? '' : ',' }}
</span>
</td>
</tr>
</tbody>
</table>

Related

How could I use ngFor to design this (maybe nested) table

I have an Object Array that has a key and then has an array for it's value. Something like this:
[
{key: 'example#example.com', value: ['message1', 'message2']}
]
I previously had this working using an object like this
[
{key: 'example#example.com', value: 'message'}
]
but I would like to change the functionality some so I switched to the value being an array instead.
I want to create a table that looks something like this
| User Email | Result |
| example#example.com | message1 |
| | message2 |
| example1#example.com | message1 |
| | message2 |
It can be a nested table or it can just show the two messages in the table cell. I am not too picky.
I tried nesting the table, but that did not work. I am not sure how I can use a second ngFor to do something like this.
This is my html that works with the Object Array that does not have an array for its value
<div class="container" style="text-align:center">
<br />
<h1>Results</h1>
<head>
<style>
table,
th,
td {
border: 1px solid black;
align: center;
}
</style>
</head>
<body>
<table style="width:50%" align="center">
<tr>
<th *ngFor="let col of displayedColumns">
{{ col }}
</th>
</tr>
<tr *ngFor="let item of userResults | keyvalue">
<td>{{ item.key }}</td>
<td>{{ item.value }}</td>
</tr>
<tr></tr>
</table>
</body>
I tried changing the item.value line with another table and another ngFor, but nothing printed.
any ideas would be appreciated
You're very close; you should just need another *ngFor directive inside your second tag, like this...
<td>
<span *ngFor="let val of item.value" style="display:inline-block">
{{ item.value }}
<span>
</td>
So your final table looks like...
<div class="container" style="text-align:center">
<br />
<h1>Results</h1>
<head>
<style>
table,
th,
td {
border: 1px solid black;
align: center;
}
</style>
</head>
<body>
<table style="width:50%" align="center">
<tr>
<th *ngFor="let col of displayedColumns">
{{ col }}
</th>
</tr>
<tr *ngFor="let item of userResults | keyvalue">
<td>{{ item.key }}</td>
<td>
<span *ngFor="let val of item.value" style="display:inline-block">
{{ item.value }}
<span>
</td>
</tr>
<tr></tr>
</table>
</body>
You do not need to use the keyvalue pipe. The keyvalue pipe is used to transform an object into an array of key value pairs so using this will give you incorrect values in your table. On the other hand, you have a normal array of objects with one property that contains an array. This format is perfect for a nested ngFor.
Change your table to the code below
<table style="width:50%" align="center">
<tr>
<th *ngFor="let col of displayedColumns">
{{ col }}
</th>
</tr>
<tr *ngFor="let item of userResults">
<td>{{ item.key }}</td>
<td>
<div *ngFor="let value of item.value">
{{ value }}
</div>
</td>
</tr>
<tr>
</table>
In your css add a vertical-align to keep the data in the cell on top.
table,
th,
td {
border: 1px solid black;
align: center;
vertical-align: top;
}
Here is a working example on stackblitz
Edit: As requested in the comments, to add html content, use innerHTML on the div like below
<div *ngFor="let value of item.value" [innerHTML]="value">
</div>

How to create table as generic component in Angular 2?

I have this table below. This kind of table can be found anywhere in my project, with different number of columns, with-or-without header column. That's why I would like to create a generic component, more simple, and have his own CSS.
<table class="table">
<thead>
<tr>
<th style="width: 100px"></th>
<th> {{ 'nameColumn_result_name' | translate }} </th>
<th> {{ 'nameColumn_result_date' | translate }}
</tr>
</thead>
<tbody #lines>
<tr #lineSelected *ngFor="let result of results"
(click)="appendLine($event, lineSelected, result)"
(contextmenu)="multipleSelection($event)">
<td (click)="selectUnitaryLine($event, result)" class="arrowDown"></td>
<td>{{result.name}}</td>
<td>{{result.date}}</td>
</tr>
<tr *ngIf="result && result .length == 0" >
<td colspan="10" class="text-center">{{ 'no_result _found' | translate }}</td>
</tr>
</tbody>
</table>
I would like something like this :
<CustomTable [data]="results" (click)="appendLine($event, lineSelected, result)" (contextmenu)="multipleSelection($event)">
<CustomTableColumn style="width: 100px" (click)="selectUnitaryLine($event, result)"></CustomTableColumn>
<CustomTableColumn [data]="name"> {{ 'nameColumn_result_name' | translate }} </CustomTableColumn>
<CustomTableColumn [data]="date"> {{ 'nameColumn_result_date' | translate }}</CustomTableColumn>
</CustomTable>
The idea is that CustomTable generate table, thead, tbody and tr and CustomTableColumn generate td. The events (click) are not generic. It can be add by the page which use this table.
So I create my component:
customtable.component.ts
#Component({
selector: 'CustomTable',
templateUrl: './customtable.component.html',
styleUrls: ['./customtable.component.css']
})
(...)
I don't know how to do that?
Can you help me please?
Thanks

Angularjs push table row to another table

I have 2 tables i want to push the row of the first table to the second.
table 1 :
<table>
<tr ng-repeat="row in items">
<td>{{row.PRODUCTDESCRIPTION}}</td>
<td><input type="text" ng-model="quantity[$index]"></td>
</tr>
</table>
<button ng-click="pushRows(row)"> </button>
table 2 :
<table>
<tr ng-repeat="row in products">
<td>{{row.PRODUCTDESCRIPTION}}</td>
<td><input type="text" ng-model="quantity[$index]"></td>
</tr>
i need to push the row in table 1 to the table 2 (my problem is how to push the input type text with its value)
You can use ng-model and create a new property on all the items.
plunker Example

How Do I Render Table With Meteor Spacebars Template and Row Number For Each Row?

How can I render a table with a meteor spacebars {{#each}} in a template and for each row add row number in first column like below:
| | title header | content header |
| 1 | first title | first content |
| 2 | second title | second content |
| 3 | third title | third content |
This is my each code now:
<table class="table table-bordered table-hover">
<thead>
<tr>
<th></th>
<th>title</th>
<th>content</th>
</tr>
</thead>
<tbody>
{{#each posts}}
<tr>
<td>
*** need index for each row in this column ***
</td>
<td>
{{ title }}
</td>
<td>
{{ content }}
</td>
</tr>
{{/each}}
</tbody>
</table>
Is there a way to get the array index within the {{#each}} or define extra property named index myself and index++ in each iteration?
In your helper that returns the cursor of values, instead of just doing a collection.find() do a collection.find().fetch() This will give you you an array of objects instead of a cursor. Then simply .forEach() through that an add an index key! Or you could just use collection.map() and add the key directly to each element as you map the cursor into an array. Docs

Angular - Multiple column filters for table

I have a table where I want to have an input box below each table header to filter its corresponding column. So I have 2 questions: 1. Between thead tag, how would use the "header" variable as a value for the enclosed ng-model? 2. Between tbody tag, what would be the best approach to specify the column name in the ng-repeat for the filter (filter:{ column_name: model_name })?
<table class="table table-striped table-bordered">
<thead>
<th ng-repeat="header in tableHeaders">{{header}}<a ng-click="sort_by(header);"></a>
<div>
<input type="text" ng-model="search" ng-change="filter()" class="form-control"/> <!-- value for ng-model should match header variable in enclosing ng-repeat -->
</div>
</th>
</thead>
<tbody>
<tr ng-repeat="data in filtered = (list | filter:{ Status: search} | orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit"> <!-- "Status" should be corresponding column header -->
<td ng-repeat="header in tableHeaders">{{data[header]}}</td>
</tr>
</tbody>
</table>
tableheaders is an array declared in the controller:
$scope.tableHeaders = ['Environment', 'Server', 'Name', 'Status'];
Assuming your tableHeader values match the variable names they're associated with, make search an object having ng-model="search[header]" and your filter to just filter: search. Keep in mind these are "ands" not "ors", so it matches on all properties of your search object, which may affect how you want to use that search object. Maybe reset it to null in your header ng-click.
<table class="table table-striped table-bordered">
<thead>
<th ng-repeat="header in tableHeaders">{{header}}<a ng-click="sort_by(header);"></a>
<div>
<input type="text" ng-model="search[header]" ng-change="filter()" class="form-control"/> <!-- value for ng-model should match header variable in enclosing ng-repeat -->
</div>
</th>
</thead>
<tbody>
<tr ng-repeat="data in filtered = (list | filter: search | orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit"> <!-- "Status" should be corresponding column header -->
<td ng-repeat="header in tableHeaders">{{data[header]}}</td>
</tr>
</tbody>
</table>

Categories

Resources