Angular how to fit child component with <td> into parent component <tr>? - html

So basically I want to have child components be in control of generating some content and put each one of them as td element, but it's not working in angular because of the extra div angular generates.
How could I make this work?
Parent-component.html
<table>
<tr>
<td>something1</td>
<td>something2</td>
<app-child-component></app-child-component>
</tr>
<table>
Child-component.html
<ng-container *ngTemplateOutlet="content"></ng-container>
<ng-template #content>
<td>something</td>
<td>something else</td>
<td><app-another-component></td>
</ng-template>

Add this to your CSS to get the child component's container out of the way:
:host{display: contents; }

Related

Access iterable in sibling tag

As stated i want to access an iterable from a sibling tag. Unfortunatly its in a table so i cant just do it by wrapping the stuff with a diff and push the iteration one lvl outside. Also the items are tablerows so i cant make the sibling to a child. I guess this is easier with an example(thats what i want to do):
<table>
<tr v-for="element in elements">
...
</tr>
<tr v-for="hit in element.hits">
...
</tr>
</table>
Obviously this doesnt work since once i close the first tr i drop out of scope. Is there any work around that?
Regardiest regards,
Sean
v-for can be used on <template> that wraps <tr>, in this case it isn't rendered itself:
<template v-for="element in elements">
<tr>
...
</tr>
<tr v-for="hit in element.hits">
...
</tr>
</template>

Visual Studio 'can't contain td inside div'

I am using primeNG p-table in my Angular application. I need to put this p-table in div. However Visual Studio gives a warning that I can't have td in div. But I have the whole table in it. Is it a good practice to put table into a div?
<div>
<p-table [value]="someData">
<ng-template pTemplate="header">
<tr>
<th>some header</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-car>
<tr>
<td>some value</td>
</tr>
</ng-template>
</p-table>
</div>

ngIf for closing/opening tag

I have a table and I'm iterating in a over an array. In some scenarios, I'll want to add an extra <tr>. I'm looking for something like this:
<table>
<tr *ngFor="let element in array">
<td>
some content
</td>
//Starting block that will only be activated if some variable is true
</tr>
<tr>
<td>
some extra content
</td>
//End of the block that will only be activated if some variable is true
</tr>
</table>
Is there a way to create a boulder html that can wrap it like this?
The options I've tried so far are changing the data structure (array) so it include the element I'm looking for but I'm not pleased with having extra data there just for displaying purpose.
This should do what you want
<table>
<ng-container *ngFor="let element in array"
<tr>
<td>
some content
</td>
</tr>
<tr *ngIf="someVar">
<td>
some extra content
</td>
</tr>
</ng-container>
</table>
Perhaps the best option is to work with ng-repeat.
Example with ng-repeat:
<table ng-controller="myCtrl">
<tr ng-repeat="x in records">
<td>{{x.Name}}</td>
<td>{{x.Country}}</td>
</tr>
</table>
Ng-repeat makes a for in your object or array.
See if this can help you.

Using ngIf without an extra element in Angular 2

Can I use ngIf without an extra container element?
<tr *ngFor="...">
<div *ngIf="...">
...
</div>
<div *ngIf="!...">
...
</div>
</tr>
It doesn't work in a table because that would make invalid HTML.
ng-container is preferred over template:
<ng-container *ngIf="expression">
See:
Angular 2 ng-container
https://github.com/angular/angular.io/issues/2303
I found a method for that on: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#star-template.
You can simply use the <template> tag and replace *ngIf with [ngIf] like this.
<template [ngIf]="...">
...
</template>
You can't put div directly inside tr, that would make invalid HTML. tr can only have td/th/table element in it & inside them you could have other HTML elements.
You could slightly change your HTML to have *ngFor over tbody & have ngIf over tr itself like below.
<tbody *ngFor="...">
<tr *ngIf="...">
...
</tr>
<tr *ngIf="!...">
...
</tr>
..
</tbody>
adding brackets resolves this issue
<ng-container *ngIf="(!variable| async)"></ng-container>
You can try this:
<ng-container *ngFor="let item of items;">
<tr *ngIf="item.active">
<td>{{item.name}}</td>
</tr>
</ng-container>
Here, I have iterate loop in ng container so it will not create extra dom and later in tr tag check condition if I want to render or not.

CSS: Is it possible for a td to infer style from its header or vice versa?

I am formatting my tables, and some of them have hyperlinks in the right hand column which I want right aligned. Is there a way from css to infer that the column has links in it, and right align the whole column, including the header?
Alternatively, is there a way to apply a class to just the header and have it affect the alignment of all of the columns underneath it?
I recognize that I can apply a style to the individual th and td elements, but I was hoping for something a little more elegant.
EDIT: There is only one table.
<table>
<thead>
<tr>
<th>Some Column</th>
<th>actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>Some data</td>
<td>Edit</td>
</tr>
</tbody>
<table>
I am asking if I can apply a style to the element for the actions and write CSS which will cause all of the elements in that column be style a particular way.
This functionality is not part of CSS. Shaun Inman suggested something like a parent selector that would allow parents to inherit from their children, but there are tons of issues with this methodology.
I would suggest, instead, that you try a javascript solution. You could search the table to see if it contains links, then add a class to the table in the case that they do. Something like this:
HTML
<table>
<thead>
<tr>
<th>Normal</th>
<th>Align Me</th>
<th>Normal</th>
</tr>
</thead>
<tbody>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>
jQuery
$('td > a').each(function(){
var $td = $(this).parent();
$td.addClass('align-right');
var $th = $td.closest('table').find('th').eq($td.index()).addClass('align-right');
});
Here is a fiddle for you to check out.
CSS can only be applied to child or siblling elements. Children cannot tell their parents what to do.
Applying a class to the TD is the right thing to do.
What you want can not be done with CSS.
But in your special case, you can refer to the fact, that the column with the links is the last one in each row.
There is a special "pseudo-class" in CSS for this: last-child.
th:last-child { ... }
td:last-child { ... }
I came up with a solution, but it only works when the actions are the last column in the table.
<table class="hasActions">
...
</table>
And CSS:
table.hasActions td:last-of-type, table.hasActions th:last-of-type {
text-align: right;
}
Since this doens't work for arbitrary columns, I'll leave the question open for now.