*ngFor to print only the first element of an array - html

i'm using this code:
<div *ngIf="gamedata.notOver" class="columns">
<div class="column has-text-centered" *ngFor="let board of boards; let i = index">
<table class="is-bordered" [style.opacity]="i == player ? 0.5 : 1">
<tr *ngFor="let row of board.tiles; let j = index">
<td *ngFor="let col of row; let k = index" (click)="boardListener($event)" [style.background-color]="col.used ? '' : 'transparent'" [class.win]="col.status == 'win'" [class.fail]="col.status !== 'win'" class="battleship-tile" id="t{{i}}{{j}}{{k}}">
{{ col.value == "1" ? (col.status == "hit" ? "💀" : "X") : (col.status == "miss" ? "⛶" : (col.status == "hit" ? "💀" : "🌊")) }}
</td>
</tr>
</table>
<hr>
</div>
</div>
to print the first element of an array of arrays that contains 2 elements, how can i choose to print the first or the second element without printing both of them? i need to do this since i have to put both of them in separate divs.

I assume the line that refers to the array of arrays is the board of boards one.
Try wrapping each array in an ng-content that has an ngIf directive as follows:
<div class="column has-text-centered" *ngFor="let board of boards; let i = index">
<ng-content *ngIf="i%2 == 0">
INSERT WHAT YOU WANT TO DISPLAY FOR FIRST ARRAY ITEM HERE
</ng-content>
<ng-content *ngIf="i%2 != 0">
INSERT WHAT YOU WANT TO DISPLAY FOR SECOND ARRAY ITEM HERE
</ng-content>
</div>
You may have to repeat some code, but it should work.

Related

Nested ngFor using outer index in inner loop

Given a list of elements:
const l = ["one", "two", "three", "four", "five", "six", "seven"]
We want to create 1 row for every 3 elements in the list, and (up to) 3 columns per row.
In this case, the resulting html would look like:
<div class="row">
<div class="col"><p>one</p></div>
<div class="col"><p>two</p></div>
<div class="col"><p>three</p></div>
</div>
<div class="row">
<div class="col"><p>four</p></div>
<div class="col"><p>five</p></div>
<div class="col"><p>six</p></div>
</div>
<div class="row">
<div class="col"><p>seven</p></div>
</div>
How can I dynamically do this? The only way I can see to accomplish this is a nested ngFor loop, but there doesn't seem to be a way to use the outer index value in the inner for loop. How can one do this?
Something like:
<div *ngFor="let content of l; index as i">
<div class="row" *ngIf="i % 3 === 0">
<div class="col" *ngFor="<!--HOW TO ACCOMPLISH THIS FOR LOOP? j = i; j < i + 3; j++ -->">
<p [innerHTML]="l[j]"></p>
</div>
</div>
</div>
You can do it like this:
<ng-container *ngFor="let content of [].constructor(l.length); let item_index = index">
<div class="row" *ngIf="item_index % 3 === 0">
<ng-container *ngFor="let item of [0, 1, 2]; let column_index = index">
<ng-container *ngIf="item+item_index < l.length">
<div class="col">
<p [innerHTML]="l[item + item_index]"></p>
</div>
</ng-container>
</ng-container>
</div>
</ng-container>
Working example

PrimeNG Table [rowHovered] not working on cells where the cell-background is set

I have a scrollable TreeTable with the rowHover-attribute defined like this:
<p-treeTable [value]="items" [columns]="scrollableCols" [resizableColumns]="true" [frozenColumns]="frozenCols" [scrollable]="true" scrollHeight="550px" frozenWidth="600px" [rowHover]="true" *ngIf="submitFinished">
So I set the background of the second and third columns - I do this like this:
<td style="text-align: center; height: 40px" [ngStyle]="{'background-color' : (col.field=='diff') ? ((getColumnValue(rowData, columns, i) > 0) ?
'#e2fee2' : ((getColumnValue(rowData, columns, i) < 0) ? '#ffa695' : 'white') ) : 'white'}"> <!-- this code only applies on each 2nd and 3rd column, not the first one. The second is always white, the third is either #ffa695, #e2fee2 or white - the first still has its default value -->
This works out completely fine, sadly the rowHover is not only hovering the cells where I did not change the background. Is there a chance to avoid this and still hover the complete row? It is fine if you cannot see the colored background while the row hovers.
Edit:
I assume that it does that because applying the [ngStyle] "keeps tracking" the value of the field and then applies the color to it, so even the selection from rowHover should be overridden. Sadly I have no idea how to work around that.
This is what I would like it to look like: (example created by not applying [ngStyle] of the <td> mentioned above)
Still, the code if it helps:
The full scrollable body (where it should apply):
<ng-template pTemplate="body" let-rowData="rowData" let-columns="columns">
<tr *ngIf="!rowData.hours"><td *ngFor="let col of columns" style="height: 60px" class="psp-row-cell"></td></tr>
<tr *ngIf="rowData.hours">
<ng-template ngFor let-i="index" let-col [ngForOf]="columns">
<ng-template [ngIf]="rowDataIsEmpty(rowData, col)" [ngIfElse]="editableColumn">
<td class="blocked-cell" style="height: 40px">
</td>
</ng-template>
<ng-template #editableColumn>
<ng-template [ngIf]="col.field=='plan'" [ngIfElse]="blockedCell">
<td style="text-align: center; height: 40px" [ttEditableColumn]="rowData">
<p-treeTableCellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" style="text-align: center" [ngModel]="getColumnValue(rowData, columns, i)" (ngModelChange)="setColumnValue(rowData, columns, i, $event)" [ngStyle]="{'width':'100%'}">
</ng-template>
<ng-template pTemplate="output">{{getColumnValue(rowData, columns, i)}}</ng-template>
</p-treeTableCellEditor>
</td>
</ng-template>
<ng-template #blockedCell>
<td style="text-align: center; height: 40px" [ngStyle]="{'background-color' : (col.field=='diff') ? ((getColumnValue(rowData, columns, i) > 0) ?
'#e2fee2' : ((getColumnValue(rowData, columns, i) < 0) ? '#ffa695' : 'white') ) : 'white'}">
{{getColumnValue(rowData, columns, i)}}
</td>
</ng-template>
</ng-template>
</ng-template>
</tr>
</ng-template>
The getColumnValue:
getColumnValue(rowData: any[], columns: any, i: number): number {
let col = columns[i];
let val;
if (col.field == 'diff') {
col = columns[i-2];
val = rowData['hours'].find(entry => entry.year === col.year && entry.month === col.month)[col.field];
col = columns[i-1];
val = val - rowData['hours'].find(entry => entry.year === col.year && entry.month === col.month)[col.field];
} else {
val = rowData['hours'].find(entry => entry.year === col.year && entry.month === col.month)[col.field];
}
return val;
}
As assumed, the background-color seems to be overriden by the [ngStyle] when changed by rowHover. One workaround was to simply change the white back to transparent, so:
[ngStyle]="{'background-color' : (col.field=='diff') ? ((getColumnValue(rowData, columns, i) > 0) ?
'#e2fee2' : ((getColumnValue(rowData, columns, i) < 0) ? '#ffa695' : 'transparent') ) : 'transparent'}
which is kind of working for this problem.

style binding dynamic, 4 different color

I want to style my tabel like this:
I try this code, but for 2 colors.
<table *ngFor="let item of notif">
<tr class="cell" [style.border-color]="item.alarmnr === 1 ? 'green' : 'red' ">
</tr>
</table>
But I need for 4 or more color.
I have 4 alarmnrumber,
alarmnr = 1 --> red
alarmnr = 2 --> blue
alarmnr = 3 --> yellow
alarmnr = 4 --> green
How to implement? Can you suggest me any idea please?
Thnx
I would advise you to do a function in the component something like this :
getColorByAlarmnr(alarmnr: number) : string {
switch(alarmnr){
case 1 : return 'red';
case 2 : return 'blue';
case 3 : return 'yellow';
case 4 : return 'green'
}
}
and in the html :
<table *ngFor="let item of notif">
<tr class="cell" [style.border-color]="getColorByAlarmnr(item.alarmnr)">
</tr>
</table>
Or you can define an object/ a map with key, value pairs for the right colors :
let colors = {
1:'red'
2:'blue'
3:'yellow',
4:'green'
}
and in the html :
<table *ngFor="let item of notif">
<tr class="cell" [style.border-color]="colors[item.alarmnr]">
</tr>
</table>
yes you can create a function in ts file
and return class or style on your logic to a variable and use that variable
to [style.border-color] ="yourvariable"
Try using ngClass for this
<table *ngFor="let item of notif">
<tr class="cell" [ngClass]="{'red': item.alarmnr === 1,
'blue': item.alarmnr === 2,
'yellow': item.alarmnr === 3,
'green' : item.alarmnr === 4}">
</tr>
</table

How to print a table from a 2D Array in Angular 5?

I'm trying to print a table from a 2 dimensional array of objects, holding a attribute 'text'. It only prints the table rows, iterating through the fields doesn't work.
My component.html looks like this:
<section *ngIf="object">
<table>
<tr *ngFor="let row of array; let even = even; let odd = odd"
[ngClass]="{ odd: odd, even: even }">
<td class="field" *ngFor="let field of array[row]">
{{field.text}}
</td>
</tr>
</table>
</section>
The array: object[][] is filled correctly and i can log the 'text' attributes to the console. The Problem is: I don't know how to iterate through the 2nd dimension (*ngFor="let field of array[row]")
Assuming array is an array of arrays,
Your second ngFor should be *ngFor="let field of row"
You can't use array[row] since row contains the array of the second dimension and not the index.
<section *ngIf="object">
<table>
<tr *ngFor="let row of array; let even = even; let odd = odd"
[ngClass]="{ odd: odd, even: even }">
<td class="field" *ngFor="let field of row">
{{field.text}}
</td>
</tr>
</table>
</section>
Example

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