I built the following stackblitz example
https://stackblitz.com/edit/angular-y454qb?file=src%2Fapp%2Ftable-header%2Ftable-header.component.css
As you can see I have parent table table which has one child component called table-header
If I write this code directly in my table component then my th colspan attribute will get applied
and will get the whole width of the table
<thead>
<th class="tableHeader" colspan="12">my table header</th>
</thead>
but if I put the same code inside nested component - in my casetable-header
then the code does not work and the colspan attribute does not get applied to the table and does not get the full width of the table.
How can I fix this?
The problem is how the app-table-header component is rendered by Angular. If you look at the result of the table being rendered you will see something like....
result of original table render
<table>
<thead>
<th class="tableHeader" colspan="12">my table header</th>
</thead>
<app-table-header>
<thead>
<th colspan="12">my table header</th>
</thead>
</app-table-header>
</table>
When app-table-header rendered there is an extra element between the <table> and the <thead> which breaks the table.
A possible solution is to make app-table-header an attribute selector, [app-table-header] and use a thead in your table with the attribute selector <thead app-table-header>.
table-header.compnonent.ts
#Component({
selector: 'thead[app-table-header]',
templateUrl: './table-header.component.html',
styleUrls: ['./table-header.component.css']
})
export class TableHeaderComponent implements {
#Input()
public heading: string = '';
}
table-header.component.html
<!-- Remove the thead from here -->
<th class="tableHeader" colspan="12">{{ heading }}</th>
table.component.html
<table>
<thead>
<th class="tableHeader" colspan="12">my table header</th>
</thead>
<thead app-table-header heading="Passing heading down with #Input"></thead>
</table>
This will result in the below html
<table>
<thead>
<th class="tableHeader" colspan="12">my table header</th>
</thead>
<thead app-table-header>
<th colspan="12">Passing heading down with #Input</th>
</thead>
</table>
See stackblitz below
https://stackblitz.com/edit/angular-bojuuf
EDIT
Updated the selector to thead[app-table-header] as suggested by #
Mazedul Islam.
Added #Input() to show you can pass values down with inputs.
Updated stackblitz
Related
I have a web app, front end has a bootstrap table, whose data rendered from Django rest framework.
As the data is rendered using data-field, it only has table header, does not have table column.
I want to make some some column editable but some not, but but failed to do so. The contenteditable='true'/'false' flag does not function on a column level.
How could I make some column editable but some not?
<table contenteditable='true' class="table table-bordered table-sm" width="100%" cellspacing="0" style="font-size: 1.0rem;"
id="bk-table"
data-toggle="table"
data-toolbar="#toolbar"
data-cookie="true"
data-cookie-id-table="materialId"
data-show-columns="true"
data-show-refresh="true"
data-show-fullscreen="true"
data-height="650"
data-click-to-select="true"
data-id-field="id"
data-show-footer="true"
data-url="/api/materials/"
data-query-params="queryParams"
data-remember-order="true"
data-pagination="true"
data-side-pagination="client"
data-total-field="count"
data-data-field="results">
<thead class="thead-dark" >
<tr contenteditable='true'>
<th data-field="state" data-checkbox="true"></th>
<th data-field="type">Course Type</th>
</tr>
</thead>
</table>
use bootstrap table plugin "x-editable" to make a column editable or non-editable use
data-editable="true" data-editable="false" respectively on <tr>
for example
<table id="my_table_id"
<thead>
<tr>
<th class="col-md-1">#</th>
<th class="col-md-4" data-editable="true">Name</th>
<th class="col-md-7" data-editable="false">Description</th>
</tr>
</thead>
</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 am display large set of data content in table using ng-repeat and it contains only one <tr> element. I am trying to display odd row in one color and even row in another color. I am not getting how to display the striped color for single row by making use of ng-repeat. Please let me know where I am going wrong.
HTML:
<thead class="rowhead">
<tr>
<th class="mid">Sl.</th>
<th id="tnm">Name</th>
<th class="mid">Age</th>
<th class="mid">Members</th>
<th class="mid">View-content</th>
<th class="mid">on-going-Process</th>
</tr>
</thead>
<tbody ng-repeat="info in cspinfo">
<tr class="clr">
<td>{{$index+1}}</td>
<td id="bnm">{{info.name}}</td>
<td>{{info.age}}</td>
<td>{{info.member}}</td>
<td>{{info.View-content}}</td>
<td>{{on-going-Process}}</td>
</tr>
</tbody>
You can directly select the odd and even rows of table using the selector in css and apply style you need. You don't have to worry about the applying class to each row you create using ng-repeat.
tr:nth-child(odd){
background-color: #yourcolor
}
tr:nth-child(even){
background-color: #yourcolor
}
Here you can read more about css selectors https://developer.mozilla.org/en-US/docs/Web/CSS/%3Anth-child
In your css define a rule for the style. Then in your html:
<tbody>
<tr class="clr" ng-class="{style-created: $index % 2 === 0}" ng-repeat="info in cspinfo">
<td>{{$index+1}}</td>
<td id="bnm">{{info.name}}</td>
<td>{{info.age}}</td>
<td>{{info.member}}</td>
<td>{{info.View-content}}</td>
<td>{{on-going-Process}}</td>
</tr>
</tbody>
I'm trying to align the html table correctly but it comes off. The challenge that I have is with respect to the inner loop (modification) which is a list inside of Revision (in other words Revision 'has a' modification list.
While the result on screen are correct, the table is completely off. I speculate the problem is in the 2 *ngFor loop. Any pointer?
<table class="table table-striped">
<thead>
<tr>
<th>Revision No</th>
<th>Date</th>
<th>Username</th>
<th>Field</th>
<th>Old Value</th>
<th>New Value</th>
</tr>
</thead>
<tbody>
<tr>
<div *ngFor="let r of revisions">
<div *ngFor="let m of r.modifications">
<td>{{r.revision}}</a></td>
<td>{{r.date}}</td>
<td>{{r.username}}</td>
<td>{{m.forItem}}<td>
<td>{{m.oldInfo}}<td>
<td>{{m.newInfo}}</td>
</div>
</div>
</tr>
</tbody>
</table>
Nothing can go between your tr and td. Put the first ngfor in a tbody wrapped around your tr. Then put your second ngfor on the tr
You can't have a <div> at that position inside a table
Use
<ng-container *ngFor="let r of revisions">
instead of
<div *ngFor="let r of revisions">
I am using table-striped style provided by Bootstrap in a table. And I am using angular js to populate the data. It is not showing the table in stripe format. Can someone help me in recognizing the error that I am making?
<table class="table table-striped">
<thead>
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
<th>H4</th>
<th>H5</th>
<th>H6</th>
</tr>
</thead>
<tbody ng-repeat="e in data.events">
<tr>
<td>{{e.e1}}</td>
<td>{{e.e2}}</td>
<td>{{e.e3}}</td>
<td>{{e.e4}}</td>
<td>{{e.e5}}</td>
<td>{{e.e6}}</td>
</tr>
</tbody>
</table>
I think you meant to put the ng-repeat on the tr element instead of the body. You're repeating the body instead of rows.
Bootstrap alternates the colours on the rows, and since you are creating a new table body with 1 row each, it's only going to show one color.
I believe your issue is the placement of the repeat directive. If you move it to your tr element, it should be fine. As is, it is creating a new tbody element for each item in your events array. Since table-striped alternates the background color of even rows, and each tbody contains only 1 row, you aren't seeing that style applied.
<table class="table table-striped">
<thead>
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
<th>H4</th>
<th>H5</th>
<th>H6</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="e in data.events">
<td>{{e.e1}}</td>
<td>{{e.e2}}</td>
<td>{{e.e3}}</td>
<td>{{e.e4}}</td>
<td>{{e.e5}}</td>
<td>{{e.e6}}</td>
</tr>
</tbody>
</table>
<table class="table table-striped">
<thead>
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
<th>H4</th>
<th>H5</th>
<th>H6</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="e in data.events">
<td>{{e.e1}}</td>
<td>{{e.e2}}</td>
<td>{{e.e3}}</td>
<td>{{e.e4}}</td>
<td>{{e.e5}}</td>
<td>{{e.e6}}</td>
</tr>
</tbody>
</table>
This should work fine, but you need to repeat the table rows <tr>, not the table body <tbody>.