I'm trying to make a table with angularJs2 2.0.0-beta.0. This table lists items. I would decouple the item from the list.
I have this code:
app.item.list.html
<table class="table table-condensed" [hidden]="items?.length==0">
<thead>
<tr>
<th >id</th>
<th >col 2</th>
<th >col 3</th>
<th >col 4</th>
<th >col 5</th>
<th >col 6</th>
</tr>
</thead>
<tbody>
<tr *ngFor="#item of items" >
<item-detail [item]="item"></item-detail>
</tr>
</tbody>
</table>
The app.item.list.ts
import {Component, EventEmitter, Output, Input, OnChanges, SimpleChange} from 'angular2/core';
import {FORM_DIRECTIVES} from 'angular2/common';
import {Item} from './model/model.item';
#Component({
selector: 'item-list',
templateUrl: 'app/app.item.list.html',
directives: [FORM_DIRECTIVES, Item]
})
export class ItemList{
#Input() Items:Array<Item> = new Array();
public item: Item;
}
the app.item.html
<td >{{item.id}}</td>
<td >{{item.col1}}</td>
<td >{{item.col2}}</td>
<td >{{item.col3}}</td>
<td >{{item.col4}}</td>
<td >{{item.col5}}</td>
And the app.item.ts
import {Component, Input, EventEmitter, Output, OnChanges, SimpleChange} from 'angular2/core';
import {FORM_DIRECTIVES, NgFor} from 'angular2/common';
#Component({
selector: 'item-detail',
templateUrl: 'app/app.item.html',
directives: [ FORM_DIRECTIVES, NgFor]
})
export class Item{
#Input() item:Item;
}
The Items informations are all displayed, but there is a format problem. All my items are raggrouped under the first column of the header (the id column).
But I want to have the item.id under the id header, the item.col1 under col1 ....
What can I do having the list and the item decoupled?
P.S.: When they were in a single html and ts file, it worked well
Ok I recived an answer on Github, and I post the solution here:
I have to change app.item.list.html
and app.item.ts
#Component({
selector: '[item-detail]',
...
})
export class Item{
#Input('item-detail') item:Item;
}
Related
I have a very puzzling problem. I have in my component a variable teams defined like this:
import { DateFunctionTeams } from '../_models/teams';
import { User } from '../_models/user';
import { AccountService } from '../_services';
import { first } from 'rxjs/operators';
#Component({
selector: 'app-raport-test',
templateUrl: './raport-for-date.component.html',
styleUrls: ['./raport-for-date.component.less']
})
export class RaportForDateComponent implements OnInit {
teams: Team[] = [];
...
}
The relevant part of my HTML looks like this:
<fieldset *ngFor="let team of teams">
<legend>{{team.function}} Users:</legend>
<div class="border border-primary">
<table id=scheduledTable class="table table-striped">
<thead>
<tr>
<th style="width:30%">Function</th>
<th style="width:30%">User</th>
<!--th style="width:30%">UserAvailability</th-->
<th style="width:10%"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of team.users">
<td>{{user.function}} </td>
<td>{{user.firstName}} </td>
</tr>
</tbody>
</table>
</div>
</fieldset>
The line with fieldset *ngFor="let team of teams" in HTML causes the error Type 'HTMLSelectElement' is not assignable to type 'NgIterable<any>'.
Interesting bit is that if I change the name teams to something else (e.g. tms) it works just fine.
Any help appreciated.
in my project i have a table with information (FirstName, LastName, PhoneNumbre, Age, Date). i create an function making me to export file excel but i don't want to export all the data i need just to export (FirstName, LastName, Age).
this is what i do
excel.html :
<div class="panel-body table-responsive">
<table id="excel-table" class="table">
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>PhoneNumber</th>
<th>Age</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let excel of excels'>
<td>{{excel.FirstName}}</td>
<td>{{excel.LastName}}</td>
<td>{{excel.PhoneNumber}}</td>
<td>{{excel.Age}}</td>
<td>{{excel.Date}}</td>
<td>
<button (click)="exportexcel()">ExportExcel</button>
</td>
</tr>
</tbody>
</table>
</div>
excel.ts :
#Component({
selector: 'app-execls',
templateUrl: './execls.component.html',
styleUrls: ['./execls.component.css']
})
export class RegionsComponent implements OnInit {
constructor(private modalService: NgbModal, private fb: FormBuilder, private toastr: ToastrService) { }
fileName = 'ExcelFile.xlsx';
exportexcel(): void {
let element = document.getElementById('excel-table');
const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(element);
const wb: XLSX.WorkBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
XLSX.writeFile(wb, this.fileName);
}
So I believe you are using sheetJS based on your code, and looking at the documentation, there is not a way to pass in columns you wish to display. https://docs.sheetjs.com/docs/api/utilities/#html-table-input. One option is to create another table with just the columns you want to display, but set that table to hidden.
<table id="excel-table-to-export" class="table" hidden>
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let excel of excels'>
<td>{{excel.FirstName}}</td>
<td>{{excel.LastName}}</td>
<td>{{excel.Age}}</td>
</tr>
</tbody>
</table>
How can I split my table row elements between columns when I use table row from different component. All the row goes to 'First Name' <th> column
client-list.html
<table mdbTable>
<thead class="black white-text">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone number</th>
<th>Procedure</th>
<th>Doctor</th>
<th>Registration</th>
<th>Registration</th>
<th>Edit</th>
<th>Serve</th>
</tr>
</thead>
<tbody>
<div *ngFor="let c of clients">
<tr *ngIf="!c.isAlreadyServed" client-list-item [client]="c"></tr>
</div>
</tbody>
</table>
client-list-item.html
<td>{{client.firstName}}</td>
<td>{{client.lastName}}</td>
<td>{{client.phone}}</td>
<td>{{client.procedure}}</td>
<td>{{client.doctorsName}}</td>
<td>{{client.registrationDate | date: 'medium'}}</td>
<td>Edit</td>
<td>Serve</td>
client-list-item.ts
#Component({
selector: '[client-list-item]',
templateUrl: './client-list-item.component.html',
styleUrls: ['./client-list-item.component.css']
})
export class ClientListItemComponent {
#Input() client: Client;
}
Replacing the div with a ng-container should do the trick. ng-container element does not make it to the final rendered DOM and is used for having structural directives without polluting the DOM.
<ng-container *ngFor="let client of clients">
<tr *ngIf="!c.isAlreadyServed" client-list-item [client]="c"></tr>
</ng-container>
I have this code which parses JSON and list data into the table using ngFor.
The result will be like.
Yes, listing data into the table is working fine.
But how can I implement it to output single data of specific ID?
For example - I want the name of id=3 the output should be "Edward".
I can't figure out how to do this. Can someone help me or guide me?
Thanks.
app-components.ts
import { Component } from '#angular/core';
import {Http, Response} from '#angular/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private data;
constructor(private http:Http){
}
ngOnInit(){
this.getData();
}
getData(){
this.http.get('/localhost/data.json')
.subscribe(res => this.data = res.json());
}
}
app-component.html
<table>
<tr>
<th>#</th>
<th>Name</th>
<th>Amount</th>
</tr>
<tr *ngFor="let info of data">
<td>{{info.id}}</td>
<td>{{info.name}}</td>
<td>{{info.amount}}</td>
</tr>
</table>
data.json
[
{
"id":"1",
"name":"John",
"amount":"112"
},
{
"id":"2",
"name":"Maria",
"amount":"44"
},
{
"id":"3",
"name":"Edward",
"amount":"40"
}
]
Please tell me that am I providing sufficient information or not.
You can use <ng-container> for the same, this have to use because you cannot apply two directives on a single element like we are using *ngIf and *ngFor.
<table>
<tr>
<th>#</th>
<th>Name</th>
<th>Amount</th>
</tr>
<ng-container *ngFor="let info of data">
<tr *ngIf='info.id == 3'>
<td>{{info.id}}</td>
<td>{{info.name}}</td>
<td>{{info.amount}}</td>
</tr>
</ng-container>
</table >
working example
Instead of adding an *ngIf directive , why don't you create a component separately to output only one table row ?
For example :
table.component.html will have :
<table>
<tr>
<th>#</th>
<th>Name</th>
<th>Amount</th>
</tr>
<tr>
<td>{{info.id}}</td>
<td>{{info.name}}</td>
<td>{{info.amount}}</td>
</tr>
</table>
and table.component.ts will have :
#Input() info : any;
Now you can loop over the <app-table [info]='info'></app-table> inside app-component.html also , you can just pass <app-table [info]='info[3]'></app-table> .
I have 2 components here: app.component.html and app-server.component.html
app.component.html
<table class="table" style="width:200px;">
<tr>
<td>Names</td>
<td>Age</td>
</tr>
<tr><app-server-element *ngFor="let student of students" [student]='student'></app-server-element></tr>
</table>
server-element.component.html:
<td class="column">{{student.name}}</td>
<td class="column">{{student.age}}</td>
but the result is like this why?:
In addition to the problem others have suggesting - there seems to be another problem. Your <app-server-element *ngFor="let student of students" [student]='student'></app-server-element> acts as a cell because it is a direct child of your tr. The td elements inside app-server-element have no effect. You could use replace in your directive to get rid of the wrapper - that way the td element would be a direct child of the tr element and it would work as expected.
Edit
After gathering more information regarding your problem, please make the following changes to your code:
Change the server-element.component.ts to:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: '[appServerElement]',
templateUrl: './server-element.component.html',
styleUrls: ['./server-element.component.css']
})
export class ServerElementComponent implements OnInit {
#Input()
appServerElement: { name: string, age: string };
constructor() {
//
}
ngOnInit() {
//
}
}
and change selector: 'app-server-element' to selector: '[appServerElement]'.
Change the app.component.html to the following:
<table class="table" style="width:200px;">
<tr>
<td>Names</td>
<td>Age</td>
</tr>
<tr [appServerElement]="student" *ngFor="let student of students"></tr>
</table>
As ankit suggested you need to iterate of <tr>:
<table class="table" style="width:200px;">
<tr>
<td>Names</td>
<td>Age</td>
</tr>
<tr *ngFor="let student of students"><app-server-element *ngFor="let student of students" [student]='student'></app-server-element></tr>
your code iterate over app-server-element which results:
<tr>
<app-server-element></app-server-element>
<app-server-element></app-server-element>
<app-server-element></app-server-element>
<app-server-element></app-server-element>
</tr>
while you want: <tr><app-server-element></app-server-element></tr>
<tr><app-server-element></app-server-element></tr>
<tr><app-server-element></app-server-element></tr>