I'm using the td-data-table from the teradata/covalent framework but independet from the framework I'd like to use *ngFor in an like this:
<ng-template *ngFor="let column of columns" tdDataTableTemplate="{{column.name}}" let-value="value">
<div>
<span>{{value.content}}</span>
<br>
<span *ngIf="enabler">{{value.subContent}}</span>
</div>
</ng-template>
I've read that the syntax for using *ngFor with an is different, so I've tried this:
<ng-template ngFor let-column [ngForOf]="columns" tdDataTableTemplate="{{column.name}}" let-value="value">
<div>
<span>{{value.content}}</span>
<br>
<span *ngIf="enabler">{{value.subContent}}</span>
</div>
</ng-template>
Is it the framework which is preventing the code to work or have I written something wrong?
Related
I am new to angular and ngx-datatable and before asking this questions on SO. I've already gone through the answers with same problem which I'm facing related to adding custom buttons in each row in ngx-datatable of angular.
My HTML template looks like this:
<ngx-datatable [rows]="rows" [loadingIndicator]="loadingIndicator" class="bootstrap"
[selected]="selected" (activate)="onActivate($event, NewEventContent)">
<ngx-datatable-column *ngFor="let column of columns; let i = index;"
name="{{column.name}}" prop="{{column.prop}}">
<ngx-datatable-column name="Actions" prop="skuCode"></ngx-datatable-column>
<ng-template let-value="value" let-row="row" let-rowIndex="rowIndex"
*ngIf="column.name==='Actions'" ngx-datatable-cell-template>
<button type="button" class="btn btn-outline-success">Success {{rowIndex}}</button>
</ng-template>
</ngx-datatable-column>
</ngx-datatable>
My .ts file look like this
columns = [{name: 'Actions', prop: 'Id' }...];
I have no idea what I'm doing wrong it this and I've seen a similar type of approach in other answers of similar type of question but none of them worked for me.
Kindly help.
I've found an alternative way to solve this problem and successfully implemented custom button in each row. So I thought to answer the question so that it could be helpful for anyone.
After the change, my HTML template look like this.
<ngx-datatable [rows]="rows" class="material" [loadingIndicator]="loadingIndicator"
[columnMode]="'force'"
[selected]="selected" (activate)="onActivate($event, NewEventContent)"
[headerHeight]="50" [footerHeight]="50" [rowHeight]="'auto'" [columns]="columns">
<ngx-datatable-column *ngFor="let column of columns;
let i = index;" name="{{column.name}}"
prop="{{column.prop}}">
</ngx-datatable-column>
<ngx-datatable-column name="Actions" sortable="false" prop="Id">
<ng-template let-row="row" let-value="value" let-rowIndex="rowIndex"
ngx-datatable-cell-template>
<button class="btn btn-dark" (click)="onSelect(row)">
Edit{{rowIndex + 1}}
</button>
</ng-template>
</ngx-datatable-column>
</ngx-datatable>
kindly pay attention to the ng-template part and onSelect(row) function. The above solution works very well in my case.
Original answer
https://github.com/swimlane/ngx-datatable/issues/489#issuecomment-356765048
In Angular there is a tag called ng-container used like so
<ng-container *ngIf="false">this wont be shown</ng-container>
now as per the angular docs
The Angular is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
Now this is really handy in angular since there are often times I would like to group a set of html elements without using a <div></div>
For example
<div class="flex-div">
<ng-container *ngIf="true">
<img src="cool-img" alt="awesome">
<h1>Cool Title</h1>
<p>Cool Text</p>
</ng-container>
<ng-container *ngIf="false">
<img src="not-so-cool-img" alt="awesome">
<h1>Not So Cool Title</h1>
<p>Not So Cool Text</p>
</ng-container>
</div>
here I have a div that has a position of flex on it and also rules about what the elements inside do..
Now If I wrapped the elements in a normal div it will break my flex styles but with the ng-container it contains my elements but is not rendered to them DOM
Is there an equivalent in Vue??
You could use conditional grouping on a template as mentioned in the docs here. The template will serve as an invisible wrapper.
<div class="flex-div">
<template v-if="true">
<img src="cool-img" alt="awesome">
<h1>Cool Title</h1>
<p>Cool Text</p>
</template>
<template v-if="false">
<img src="not-so-cool-img" alt="awesome">
<h1>Not So Cool Title</h1>
<p>Not So Cool Text</p>
</template>
</div>
I have this html code
<empty-list [hidden]="!emptylist" text="There is currently No User"</empty-list>
<div *ngFor="let userObser of userObservables">
<ion-item #emptylist *ngIf="userObser | async as user">
<h2>{{user.displayName}}</h2>
<h3>{{user.email}}</h3>
</ion-item>
</div>
I want to show the empty list if there is no user & hide it if there is at least one.
I know I can do it using a subscribe method,but I want to use async pipe also I need to unsubscribe each time I use a subscribe which is really not efficient.
My question is there a way I could create a local variable inside the ion-item the ntest test if it exists outside & therefore use it in the hidden input ? It's just a suggestion I can't really seem to make it work.
You can use a simple else inside the ngIf to display another template if the condition doesn't match:
<ng-container *ngIf="userObservables.length > 0; else emptyList">
<ng-container *ngFor="let user of userObservables">
<ion-item *ngIf="user | async as user">…</ion-item>
</ng-container>
</ng-container>
<ng-template #emptyList>
<empty-list>…</empty-list>
</ng-template>
Note that I also replaced your seemingly unnecessary div with a ng-container to avoid unnecessary DOM nodes.
As a side note to your own suggestion: template references cannot be accessed from outside the template boundary. Structural directives like *ngIf and *ngFor create their own template, so this becomes a boundary. That's why
<h2>{{ ref.innerText }}</h2>
<ng-container>
<span #ref>Hello, World</span>
</ng-container>
will work, but
<h2>{{ ref.innerText }}</h2>
<ng-container *ngIf="true">
<span #ref>Hello, World</span>
</ng-container>
won't work.
I am using swimlane/ngx-datatable component and I developed a wrapper for ngx-datatable.
Wrapper:
<div class="wrapper">
<ngx-datatable [rows]="rows">
<ng-content></ng-content>
</ngx-datatable>
</div>
Use:
<app-wrapper>
<ngx-datatable-column name="Name">
<ng-template ngx-datatable-cell-template let-rowIndex="rowIndex" let-value="value" let-row="row">
<span>{{ value }}</span>
</ng-template>
</ngx-datatable-column>
</app-wrapper>
This does not work, custom html that I wrote inside app-wrapper is not passed to the component. How would someone go through this if the component already uses ng-template?
This is not directly related to ngx-datatable. Angular doesn't currently support content projection with ng-content more that 2 levels of components deep. No, using ng-content inside ngx-datatable inside app-wrapper will not work.
I'm trying to create a table with a complex header (multi-line header) like this:
using the angular-2-data-table library found here:
https://github.com/swimlane/angular2-data-table
They have something called "Expressive cell templates" in which you can define columns like this:
<datatable
class="material"
[rows]="rows"
[options]="options">
<datatable-column name="Name">
<template let-column="column">
Hi + {{column.name}}
</template>
<template let-value="value">
Hi: <strong>{{value}}</strong>
</template>
</datatable-column>
<datatable-column name="Gender">
<template let-row="row" let-value="value">
My name is: <i [innerHTML]="row['name']"></i> and <i>{{value}}</i>
<div>{{joke}}</div>
</template>
</datatable-column>
</datatable>
plnkr here
But it seems like the column name is always defined as text, and it's unclear how you would have nested column names. Any ideas if complex headers are possible in angular2-data-table? It's possible in regular datatables (https://datatables.net/examples/advanced_init/complex_header.html).
Thanks in advance!