could not get query Selector inside <ng-template> in angular - html

I have table component.
I want to add a property to a element when [draggable]="true".
parent class
<ngx-custom-table [value]="users" [draggable]="true">
<ng-template #header let-columns>
<tr>
// removed
</tr>
</ng-template>
<ng-template #body let-data>
<tr >
<td>
</td>
<td>{{ data.id }}</td>
<tr>
</ng-template>
</ngx-custom-table>
child class
ngOnInit() {
console.log( (<HTMLElement>document.querySelector('ngx-custom-table'))); // this is defined
console.log( (<HTMLElement>document.querySelector('tr'))); // but this is null
});
Why (<HTMLElement>document.querySelector('tr')); this is null??
How can I add a property to <tr> element?

Related

Target iterated fa-icon row in table - Angular , primeNg

I have a nested table made using primeNg. Each row denotes a task. Every row has a start fa-icon which starts the task and if a particular task is started, the start button gets replaced by a stop fa-icon, incase any user wants to stop the on-going task.
The task are nested (Note the expand-arrows to the left of rows). With my current code, whenever I click on start fa-icon, all the fa-icons in the table gets 'started'. I need to specifycally grab the play fa-icon of the row where the task is initiated and replace that exact play fa-icon with stop fa-icon.
I'm replacing start fa-icon with stop fa-icon using *ngIf and Boolean variables.
.ts:
playTask:boolean = true;
stopTask:boolean = false;
playClicked(array , i , j, event:any){
this.playTask = false;
this.stopTask = true;
var target = event.target || event.srcElement || event.currentTarget;
var idAttr = target.attributes.id
console.log( "id: ", idAttr);
}
stopClicked(array , i , j, event:any){
this.playTask = true;
this.stopTask = false;
}
html:
<p-table id="main-table" [value]="tasks" dataKey="col1">
<ng-template pTemplate="header">
<tr>
<th></th>
<th>Col 1 <fa-icon [icon]="faChevronUp"></fa-icon><fa-icon [icon]="faChevronDown"></fa-icon></th>
<th>Col 2 <fa-icon [icon]="faChevronUp"></fa-icon><fa-icon [icon]="faChevronDown"></fa-icon></th>
<th>Col 3 <fa-icon [icon]="faChevronUp"></fa-icon><fa-icon [icon]="faChevronDown"></fa-icon></th>
<th>Col 4 <fa-icon [icon]="faChevronUp"></fa-icon><fa-icon [icon]="faChevronDown"></fa-icon></th>
<th>Col 5 <fa-icon [icon]="faChevronUp"></fa-icon><fa-icon [icon]="faChevronDown"></fa-icon></th>
<th>Col 6</th>
<th>Action</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-i="rowIndex" let-parentTasks let-expanded="expanded" >
<tr *ngFor="let parentTasks of tasks">
<td>
<button type="button" pButton pRipple [pRowToggler]="parentTasks" [icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-up'"></button>
</td>
<td>{{parentTasks.row1}}</td>
<td>{{parentTasks.row2}}</td>
<td>{{parentTasks.row3}}</td>
<td>{{parentTasks.row4}}</td>
<td>{{parentTasks.row5}}</td>
<td>{{parentTasks.row6}}</td>
<td>
<fa-icon *ngIf="playTask" [icon]="faPlayCircle"></fa-icon>
<fa-icon *ngIf="stopTask" [icon]="faStopCircle"></fa-icon>
<fa-icon [icon]="faCommentDots"></fa-icon>
</td>
</tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-parentTasks let-i="rowIndex">
<tr>
<td>
<div class="expandedRow">
<p-table [value]="parentTasks.appointments" dataKey="row1">
<ng-template pTemplate="body" let-childTasks let-j="rowIndex" let-childTasks.viewDetails="false">
<tr>
<td>
<i (click)="childTasks.viewDetails = !childTasks.viewDetails" [ngClass]="childTasks.viewDetails ? 'pi pi-chevron-down' : 'pi pi-chevron-up'"></i>
</td>
<td>{{childTasks.row1}}</td>
<td>{{childTasks.row2}}</td>
<td>{{childTasks.row3}}</td>
<td>{{childTasks.row4}}</td>
<td>{{childTasks.row5}}</td>
<td>{{childTasks.row6}}</td>
<td>
<fa-icon *ngIf="playTask" (click)="playClicked(childTasks, i, j , $event)" id="{{'play'}}" [icon]="faPlayCircle"></fa-icon>
<fa-icon *ngIf="stopTask" (click)="stopClicked(childTasks, i, j, $event)" id="{{'pause'}}" [icon]="faStopCircle"></fa-icon>
<fa-icon [icon]="faCommentDots"></fa-icon>
</td>
</tr>
</ng-template>
</p-table>
</div>
</td>
</tr>
</ng-template>
</p-table>
I have tried using $event for getting any unique ID of that row but it always returns as empty. Note: View childTasks for the (click) event.
Only the issue with above code I see, you use two way binding for icon attribute. Which is updating your icon global for entire rows of grid.
<fa-icon *ngIf="stopTask" (click)="stopClicked(childTasks, i, j, $event)" id="{{'pause'}}" [icon]="faStopCircle">
#Please try below
<i class="fa fa-stop" *ngIf="stopTask" (click)="stopClicked(childTasks, i, j, $event)" >

SelectAll checkbox in header should get unchecked when move to next page when using p-tableHeaderCheckbox and p-table

I am using <p-table> which has <p-tableHeaderCheckbox></p-tableHeaderCheckbox> to check and uncheck the check box. Everything is working fine but when I am move to next page in table then everything is unchecked but selectAll option is still checked . How to uncheck the header checkbox.
<p-table #dtGrid [columns]="staticColumns" [value]="serviceIdData"
[styleClass]="'table'" scrollHeight="{{scrollHeight}}" [rows]="10"
[paginator]="true" (onRowSelect)="onRowSelect($event)" [pageLinks]="3"
(onRowUnselect)="onRowUnselect($event)" [rowsPerPageOptions]="[10,25,50,100]"
styleClass="table-light" (onHeaderCheckboxToggle)="handleHeaderCheckboxToggle($event)"
[scrollable]="true" [lazy]="true" [(selection)]="selectedRecords"
(onLazyLoad)="onLazyLoad($event);" [totalRecords]="totalRecords" scrollHeight="450px" [responsive]="true">
<ng-template pTemplate="colgroup" let-columns>
<colgroup>
<col *ngFor="let col of columns" [ngStyle]="{'width': col.width}">
</colgroup>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr>
<th role="columnheader" style="width:20px;">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th *ngFor="let col of columns" [pSortableColumn]="col.fieldName" (click)="placeSortIcon()">
<div>
<span pTooltip={{col.tooltip}} tooltipPosition="top" [innerHtml]="col.label" [ngClass]="'ui-column-title'"></span>
<span *ngIf="dtGrid.sortField === col.fieldName" class="fa" [ngClass]="{'fa-sort-desc': dtGrid.sortOrder === -1, 'fa-sort-asc': dtGrid.sortOrder === 1}"></span>
</div>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-columns="columns" let-data>
<tr [pSelectableRow]="data" [pSelectableRowDisabled]="data.moved">
<td class="rowDataStyle" style="width:20px;">
<span *ngIf="data.moved"><img name="loading" src="assets/images/lock.png"></span>
<p-tableCheckbox [value]="data" [hidden]="data.moved" [disabled]="data.moved" binary="data.selected"></p-tableCheckbox>
<!-- {{data.selected}} , {{data.moved}} -->
</td>
<td *ngFor="let column of columns">
<span [ngClass]="'ui-cell-data'">
{{data[column.fieldName]}}</span>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage" let-columns>
<tr>
<td [attr.colspan]="columns.length">
No records found
</td>
</tr>
</ng-template>
</p-table>
Checkbox still checked on moving to next page, click on this to see screenshot of the output table
// Declair variables
checkBoxSelection = [];
checkBoxSelectionOldStore = [];
// put after serviceIdData variable ex. blelow
// After API Success
this.serviceIdData = response.data;
this.checkBoxSelection = _.cloneDeep(Array(Number((this.totalRecords/e.rows).toFixed())).fill([]));
this.checkBoxSelection = this.checkBoxSelectionOldStore.length ? _.cloneDeep(this.checkBoxSelectionOldStore) : this.checkBoxSelection;
handleHeaderCheckboxToggle($event: any) {
const isChecked = $event.checked;
this.selectedItems = [];
this.checkBoxSelection[this.pageIndex] = isChecked ? _.cloneDeep(this.items) : [];
this.onRowSelect();
}
onRowSelect() {
this.checkBoxSelectionOldStore = _.cloneDeep(this.checkBoxSelection);
this.selectedItems = [];
_.forEach(this.checkBoxSelectionOldStore, (value) => {
if (value.length > 0) {
_.forEach(value, (v) => {
this.selectedItems.push(v);
});
}
});
}
// finally Your selected records in this.selectedItems
<p-table [value]="serviceIdData" (onHeaderCheckboxToggle)="handleHeaderCheckboxToggle($event)" [(selection)]="selectedRecords" (onLazyLoad)="onLazyLoad($event);" [totalRecords]="totalRecords" (onRowSelect)="onRowSelect()" [(selection)]="checkBoxSelection[pageIndex]">
</p-table>

Handle selection p-checkbox with the same group

I have a list like below:
rows: any[] = [{"id":"1721079361", "type":"0002", "number":"2100074912"},
{"id":"1721079363", "type":"0003", "number":"2100074913"},
{"id":"1721079363", "type":"0004", "number":"2100074914"},
{"id":"1721079361", "type":"0001", "number":"2100074911"}];
I want to load on the table with the checkbox.
The user only selects the items which have the same Id.
Here is HTML
<p-table [value]="rows">
<ng-template pTemplate="header">
<tr>
<td>
</td>
<th>ID</th>
<th>Type</th>
<th>Number</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-row>
<tr [pSelectableRow]="row">
<td>
<p-checkbox [(ngModel)]="selectedValues" value="{{row.id}}"></p-checkbox>
</td>
<td>{{row.id}}</td>
<td>{{row.type}}</td>
<td>{{row.number}}</td>
</tr>
</ng-template>
</p-table>
Test : {{selectedValues}}
But until now, I cannot find the solution for it. Pls advice
https://stackblitz.com/edit/angular-8ddptg
You can use disable property and bind it with row value, dynamically on change event of any checkbox.
component.html
<p-checkbox [disabled]="row && row.isDisable" [(ngModel)]="selectedValues" value={{row.id}}" (onChange)="updateList(selectedValues)" ></p-checkbox>
component.ts
updateList(val){
if(val.length === 0){
for(let i = 0; i<this.rows.length ;i++){
this.rows[i]['isDisable'] = false;
}
}else{
let id = val[0];
for(let i = 0; i<this.rows.length ;i++){
if(this.rows[i]['id']!== id){
this.rows[i]['isDisable'] = true;
}
}
}
}
Here is working code
Hope this solve your purpose!

How to build a tree node with Angular 6?

I have to generate a tree node with Angular. The object is called Page and each Page can have children and those children can also have their own children and so on.
Now I have to show the hierarchical structure in HTML from my Angular Page object.
Also, what I would want to indent the children like this:
Page parent #1
.... Child page of #1
......... Child of child page #1
Page parent #2
.... Child page of #2
........ Child of child page #2
You get the idea.
My page object is:
export class PageModel {
id!: number;
title?: string | undefined;
typeId?: string | undefined;
parentId?: number | undefined;
children?: PageModel[] | undefined;
publishedDateLocal?: string | undefined;
}
My html component is for now a simple table...
<table class="table">
<thead>
<tr>
<td>Title</td>
<td>Page Type</td>
<td>Published</td>
<td></td>
</tr>
</thead>
<tbody>
<tr *ngFor="let page of model.pageModels">
<td>{{ page?.title }}</td>
<td>{{ page?.pageTypeId }}</td>
<td>{{ page?.publishedDateLocal }}</td>
<td>
<a class="remove" (click)="deletePage(page.id)" [routerLink]="">
<span class="glyphicon glyphicon-trash text-danger"></span>
</a>
<a [routerLink]="['/pageAddEdit', page.id]">
Edit
</a>
</td>
</tr>
</tbody>
</table>
Thank you for any help
I would recommend using a recursive structure for this.
Create a very simply component that takes PageModel as an input. You can then display that, and look through each of the children using *ngFor, like so:
#Component({
selector: 'hello',
template: `
<li>{{model.title}}</li>
<ul>
<hello *ngFor="let child of model.children" [model]="child"></hello>
</ul>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
#Input() model: PageModel;
}
Here is a simple
StackBlitz example

PrimeNG Turbotable expand by default

I have a PrimeNg turbotable with row expansion feature.
How can I expand the rows by default.
Here is my Code :
HTML
<p-table [columns]="cols" [value]="cars" dataKey="vin">
<ng-template pTemplate="header" let-columns>
<tr>
<th style="width: 2.25em"></th>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-expanded="expanded" let-columns="columns">
<tr>
<td>
<a href="#" [pRowToggler]="rowData">
<i [ngClass]="expanded ? 'fa fa-fw fa-chevron-circle-down' : 'fa fa-fw fa-chevron-circle-right'"></i>
</a>
</td>
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-rowData let-columns="columns">
<tr>
<td [attr.colspan]="columns.length + 1">
<div class="ui-g ui-fluid" style="font-size:16px;padding:20px">
<div class="ui-g-12 ui-md-3" style="text-align:center">
<img [attr.alt]="rowData.brand" src="assets/showcase/images/demo/car/{{rowData.brand}}.png">
</div>
<div class="ui-g-12 ui-md-9">
<div class="ui-g">
<div class="ui-g-12">
<b>Vin:</b> {{rowData.vin}}
</div>
<div class="ui-g-12">
<b>Vin:</b> {{rowData.color}}
</div>
<div class="ui-g-12">
<b>Brand:</b> {{rowData.brand}}
</div>
<div class="ui-g-12">
<b>Color:</b> {{rowData.color}}
</div>
</div>
</div>
</div>
</td>
</tr>
</ng-template>
</p-table>
Ts
export class TableRowExpansionDemo implements OnInit {
cars: Car[];
cols: any[];
constructor(private carService: CarService) { }
ngOnInit() {
this.carService.getCarsSmall().then(cars => this.cars = cars);
this.cols = [
{ field: 'vin', header: 'Vin' },
{ field: 'year', header: 'Year' },
{ field: 'brand', header: 'Brand' },
{ field: 'color', header: 'Color' }
];
}
}
}
I tried using expandedRowKeys attribute, but it is not working for me.
What am I missing here?
Thanks
Update: For Version >7.x
Setting value to 1 won't work on version 7+ use boolean(true/false)
const thisRef = this;
this.cars.forEach(function(car) {
thisRef.expandedRows[car.vin] = true;
});
Working StackBlitz
For Version <7.x
I tried using expandedRowKeys attribute
Yes you're right. So add [expandedRowKeys]="expandedRows"> to p-table element :
<p-table [columns]="cols" [value]="cars" dataKey="vin" [expandedRowKeys]="expandedRows">
and then, you just need to fill expandedRows object with vin values of the rows you want to expand (because dataKey is vin).
Because you want all rows to be expanded, you can fill it like that :
const thisRef = this;
this.cars.forEach(function(car) {
thisRef.expandedRows[car.vin] = 1;
});
in order to have something like
expandedRows = {"dsad231ff": 1, "gwregre345": 1, ...}
See working Plunker
In the accepted answer, the expandedRows mapping to the turbo table expandedRowKeys is one way i.e. it can set the state of rows at the time of loading only.
If someone want to collapse or expand it after the table is loaded, you can directly edit the 'expandedRowKeys' variable by passing the table reference from the html.
Define Your table with a reference variable #dt
<p-table #dt [columns]="cols" [value]="cars" dataKey="vin">
Edit your table body like this to get a on click function trigger
<ng-template pTemplate="body" let-rowData let-expanded="expanded" let-columns="columns">
<tr>
<td>
<a href="#" [pRowToggler]="rowData">
<i [ngClass]="expanded ? 'fa fa-fw fa-chevron-circle-down' : 'fa fa-fw fa-chevron-circle-right'"></i>
</a>
</td>
<td *ngFor="let col of columns">
<a >
<span (click)="onItemClick(rowData, dt)">
{{rowData[col.field]}}
</span>
</a>
</td>
</tr>
</ng-template>
in your TS file add the function as
onItemClick(rowData:any, dt:any) {
if(dt.expandedRowKeys[rowData._id]){
dt.expandedRowKeys[rowData._id] = 0;
}
else {
dt.expandedRowKeys[rowData._id] = 1;
}
}
This approach gives you more freedom in changing state of table on a trigger of event from outside of table and expanding or collapsing multiple rows at once.
After hitting many solution i tried and found easiest way to resolve
<p-table [columns]="cols" [value]="cars" dataKey="vin" [expandedRowKeys]="expandedRows">
Replace datakey value to your unique id key from list of objects fetched from service or http calls.
<p-table [columns]="cols" [value]="repaymentsList" dataKey="id" expandableRows="true" rowExpandMode="single" [responsive]="true">