prime ng row expansion data key issue - primeng

I am using prime ng table with row expansion, but I think the problem is with my data key. row is not expanding when I use dataKey="id" if I use Munit.id all rows expand instead of one
html file
<p-table #dt dataKey= "id" [columns]="cols" [value]="mUnit" [paginator]="true" [rows]="5" [showCurrentPageReport]="true"
paginatorright currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[rowsPerPageOptions]="[5,10,15]" [globalFilterFields]="['mUnitName']" rowExpandMode="single" expandableRows="true"
styleClass="p-datatable-striped" #tableContextMenu>
<ng-template pTemplate="caption" class=" hidden">
<div class=" grid justify-content-between ">
<span class="p-input-icon-left">
<i class="pi pi-search"></i>
<input pInputText type="text" (input)="dt.filterGlobal($event.target.value, 'contains')"
placeholder="Search keyword" />
</span>
<span class="wrap ml-auto ">
<button mat-button class='bd ' (click)="routed()">Add</button>
<button mat-button class='bd' (click)="print()">Print</button>
</span>
</div>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr>
<!-- <th pSortableColumn="id">ID <p-sortIcon field="id"></p-sortIcon></th>
<th pSortableColumn="Name">ID <p-sortIcon field="mUnitName"></p-sortIcon></th> -->
<th style="width: 2.25e ml"></th>
<th *ngFor="let col of columns" pSortableColumn="{{col.field}}">
{{col.header}}
<p-sortIcon field="{{col.field}}"></p-sortIcon>
<p-columnFilter type="text" field="{{col.field}}" display="menu"></p-columnFilter>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns" let-expanded="expanded">
<tr>
<!-- (click)="showIt(rowData)" -->
<td>
<button type="button" pButton pRipple [pRowToggler]="columns"
class="p-button-text p-button-rounded p-button-plain"
[icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
</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 colspan="3">
<div class="p-3">
<div>its row</div>
<p-table [value]="mUnit" dataKey="id">
<ng-template pTemplate="header">
<tr>
<th *ngFor="let col of columns" pSortableColumn="{{col.field}}">
{{col.header}}
<p-sortIcon field="{{col.field}}"></p-sortIcon>
<p-columnFilter type="text" field="{{col.field}}" display="menu"></p-columnFilter>
</th>
<th style="width: 4rem"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr>
(click)="showIt(rowData)"
<td>
<button type="button" pButton pRipple [pRowToggler]="rowData"
class="p-button-text p-button-rounded p-button-plain"
[icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
</td>
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="6">There are no order for this product yet.</td>
</tr>
</ng-template>
</p-table>
</div>
</td>
</tr>
</ng-template>
</p-table>
my ts. file
showData() {
this.MUnitService.getData().subscribe(
(data: any) => {
if (data) {
this.mUnit = data
this.cols = [
{ field: 'id', header: 'ID' },
{ field: 'mUnitName', header: 'Name' },
];
}
}
);
showData is called in ngOnInit()

you must repeat dataKey= "id" of your table
<p-table #dt dataKey= "id"
in
<ng-template pTemplate="rowexpansion" dataKey= "id"
I hope and serve you.

Related

PrimeNG p-table column widths on scrollable table

I have a p-table defined with [scrollable]="true"
<p-table
*ngIf="!loading"
[value]="data"
[resizableColumns]="true"
[reorderableColumns]="true"
[columns]="columns"
[autoLayout]="true" <---
[scrollable]="true" <---
scrollHeight="75vh"
>
The [scrollable] changes the table layout from display: table-cell to display:flex and thus the [autoLayout] is now ignored.
I have tried setting the styles here to percentage widths (i.e. 10%/10%/80%) but it has no effect with the flex display table.
<th
*ngFor="let col of columns"
pSortableColumn="{{ col.field }}"
pReorderableColumn
pResizableColumn
[ngStyle]="{'width': col.width}" <---
>
I see there is a PrimeNG issue commenting on this, but are there any workarounds I can use to get set column widths when using [scrollable]?
https://github.com/primefaces/primeng/issues/5510#issuecomment-432155295
try the following:
<!-- File: employee-grid.component.html -->
<p-table #dt id='employees-grid' [value]='employees' [responsive]='true'
scrollHeight='420px' [scrollable]='true'
[(selection)]='selectedEmployee' selectionMode='single'
(onRowSelect)='onRowSelect($event)' dataKey='EmployeeId'>
<ng-template pTemplate='caption'>
<div class='nsg-row nsg-text-center'>
<h5 class='nsg-primary-color'>Employee Selection</h5>
</div>
</ng-template>
<ng-template pTemplate='header'>
<tr>
<th style='flex: 0 0 320px;'>
Name
<p-columnFilter type='text' field='EmployeeName' matchMode='contains' display='menu'></p-columnFilter>
</th>
<th style='flex: 0 0 160px;'>
Company
<p-columnFilter type='text' field='CompanyShortName' display='menu'></p-columnFilter>
</th>
<th>
Div/Depart
<p-columnFilter type='text' field='DeptDivShortName' display='menu'></p-columnFilter>
</th>
<th>
Job Title
<p-columnFilter type='text' field='JobTitle' display='menu'></p-columnFilter>
</th>
</tr>
</ng-template>
<ng-template pTemplate='body' let-rowData let-idx='rowIndex'>
<tr [pSelectableRow]='rowData' [pSelectableRowDisabled]='!editable' [ngClass]="{'nsg-state-highlight' : idx === selectedRowIdx}">
<td style='flex: 0 0 320px;'>
<span class='p-column-title'>Name</span>
{{rowData.EmployeeName}}
</td>
<td style='flex: 0 0 160px;'>
<span class='p-column-title'>Company</span>
{{rowData.CompanyShortName}}
</td>
<td>
<span class='p-column-title'>Division/Depart</span>
{{rowData.DeptDivShortName}}
</td>
<td>
<span class='p-column-title'>Job Title</span>
{{rowData.JobTitle}}
</td>
</tr>
</ng-template>
</p-table>
<!-- End of employee.grid.component.html -->
Also check the Primefaces forum for solutions, but generally Stack Overflow is the best source.

Smart table reset / refresh on input field search does not load the original data

When refreshing the table data with search input field, it displays table data with the last search input field value.
How can I remove the filter on the click of the refresh/clear button and get the original data?
Please find the page view GUI
$scope.Refresh = function () {
$scope.searchall="";
$scope.DataLoad();
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.min.js"></script>
<button type="button" class="btn-sm btn-default" ng-click="Refresh()">Refresh</button>
<div>
<select autocomplete="off" style="width: 60px;" ng-model="CountPerPage"
ng- options="x for x in CountPerPageOptionValues">
<option value="">All</option>
</select>
</div>
<table ng-show="DataLoaded" st-table="Collection" class="table table-striped animate-show" st-safe-src="data" >
<thead>
<tr>
<th st-sort="Id">ID</th>
<th st-sort="Name">Name</th>
<th st-sort="Timestamp" style="min-width:68px;">Timestamp</th>
<th st-sort="Message" style="min-width:136px;">Message</th>
</tr>
<tr>
<th>
<input ng-model="searchall" ng-show="!nomsg" st-search="Name" placeholder="search for Name" class="input-sm form-control" style="width:140px" type="search" />
</th>
</tr>
</thead>
<tbody data-ng-hide="isLoading" data-ng-animate="'fade'">
*emphasized text*<tr ng-repeat="latestData in Collection">
<td>{{latestData .Id}}</td>
<td>{{latestData .Name}}</td>
<td>{{latestData .Timestamp | date:'dd MMM yyyy hh:mm:ss a'}}</td>
<td>
{{latestData.Message}}
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="CountPerPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>

Check if PrimeNG checkbox checked or unchecked

check if primeNG checkbox checked or unchecked.
I am using primenNG 5.
https://www.primefaces.org/primeng-5.2.7/#/table/selection
<p-table [columns]="cols" [value]="cars" [(selection)]="selectedCars3" dataKey="vin">
<ng-template pTemplate="header" let-columns>
<tr>
<th style="width: 3em">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr>
<td>
<p-tableCheckbox [value]="rowData" (click)="onRowSelect($event)"></p-tableCheckbox>
</td>
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
<ng-template pTemplate="summary">
<ul>
<li *ngFor="let car of selectedCars3" style="text-align: left">
{{car.vin + ' - ' + car.brand + ' - ' + car.year + ' - ' + car.color}}
</li>
</ul>
</ng-template>
</p-table>

AngularJS Sort table columns

I have a table filter whichs show the content according to the user parameters, this is working perfectly but now I want to let the user filter according to each column.
This is the issue:
When you type "User" on the text input (Filter by columns" I want to only display the "User Column", if you type "Start Date" then only displays "Start Date column" I'm wondering if this is possible using filter option or how can I approach to this requirement.
Here's my code:
<div class="col-xs-10 grid-container">
<div class="row form-entry">
<div class="col-xs-3 input-container">
<input type="text" placeholder="Search in Grid" ng-model="searchFills"/>
</div>
<div class="col-xs-3 input-container">
<input type="text" placeholder="Filter by columns" />
</div>
</div>
<div class="col-xs-10 grid-container">
<div class="generic-grid">
<table class="table-bordered grid-table table-hover">
<thead>
<tr>
<th>id</th>
<th>User</th>
<th>Alt User</th>
<th>Creation Date</th>
<th>Start Date</th>
<th>Recieved Date</th>
<th>1</th>
<th>2</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="fill in fills_list | filter:searchFills">
<td>
{{fill.id}}
</td>
<td>
{{fill.user}}
</td>
<td>
{{fill.useralt}}
</td>
<td>
{{fill.creationdate}}
</td>
<td>
{{fill.startdate}}
</td>
<td>
{{fill.recieveddate}}
</td>
<td>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</div>
</div>
You can add ng-model="columnFilter" to your input:
<input type="text" placeholder="Filter by columns" `ng-model="columnFilter"` />
Then addng-hide="columnFilter == 'Start Date'" to <td>{{fill.user}}</td>
Add ng-hide="columnFilter == 'User'" to <td>{{fill.startdate}}</td>
And add ng-hide="columnFilter == 'User' || columnFilter == 'Start Date'" to the rest of the <td>'s.
If you want to filter by column, then you need ng-repeat by columns. After that you can use the same filter that you are using for filtering rows
controller.js
controllers.controller("MainController", ["$scope", function($scope) {
return ["$scope", function ($scope) {
$scope.columns = [{
title: "id",
alias: "id"
}, {
title: "User",
alias: "user"
}, {
title: "Alt User",
alias: "useralt"
}, {
title: "Creation Date",
alias: "creationdate"
}, {
title: "Start Date",
alias: "startdate"
}, {
title: "Recieved Date",
alias: "recieveddate"
}];
}]);
template.html
<div ng-controller="MainController">
<div class="col-xs-10 grid-container">
<div class="row form-entry">
<div class="col-xs-3 input-container">
<input type="text" placeholder="Search in Grid" ng-model="searchFills" />
</div>
<div class="col-xs-3 input-container">
<input type="text" placeholder="Filter by columns" ng-model="searchColumn" />
</div>
</div>
<div class="col-xs-10 grid-container">
<div class="generic-grid">
<table class="table-bordered grid-table table-hover">
<thead>
<tr>
<th ng-repeat="column in columns | filter:searchColumn">{{column.title}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="fill in fills_list | filter:searchFills">
<td ng-repeat="column in columns | filter:searchColumn">{{fill[column.alias]}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
That will filter any column in a table.

First matching element using CSSSelector

So, I am trying to get the test of the column Title or Names or DateTime
I'm trying to get the test td element and I have tried the following using CSSSelector:
div#body-inner div#ctl00_ContentPlaceHolder1_Control1_pnlList div table#ctl00_ContentPlaceHolder1_Control1_gv.gv tbody tr.item td:nth-child(4)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head id="ctl00_PageHead">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Employee</title>
<body id="ctl00_PageBody">
<form name="aspnetForm">
<div>
</div>
<div>
</div>
<table class="global-table" cellpadding="0" cellspacing="0">
<tr class="body">
<td>
<div id="body">
<div id="body-inner">
<h1>
Employee Information</h1>
<div id="ctl00_ContentPlaceHolder1_Control1_pnlList" style="width: 100%;">
<div class='filter'>
</div>
<div>
<table class="gv" cellspacing="0" border="0" id="ctl00_ContentPlaceHolder1_Control1_gv" style="border-collapse: collapse;">
<tr class="header">
<th class=" nolink" scope="col">
</th>
<th scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$Phone')">
Phone</a>
</th>
<th class=" sorted-desc" scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$Title')">
Title</a>
</th>
<th scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$SubTitle')">
SubTitle</a>
</th>
<th scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$Names')">
Names</a>
</th>
<th scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$Names')">
Enames</a>
</th>
<th scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$Active')">
Active</a>
</th>
<th scope="col">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Sort$DateTime')">
DateTime</a>
</th>
</tr>
<tr class="item">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$0')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
8/23/2011
</td>
</tr>
<tr class="altItem">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$1')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test1
</td>
<td>
1
</td>
<td>
Employee
</td>
<td>
</td>
<td>
</td>
<td>
7/31/2014
</td>
</tr>
<tr class="item">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$2')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test2</td>
<td>
111
</td>
<td>
Employer
</td>
<td>
</td>
<td>
</td>
<td>
7/31/2013
</td>
</tr>
<tr class="altItem">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$3')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test3</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
8/23/2011
</td>
</tr>
<tr class="item">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$4')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test4</td>
<td>
2
</td>
<td>
Employer
</td>
<td>
</td>
<td>
</td>
<td>
7/31/2012
</td>
</tr>
<tr class="altItem">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$5')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test5</td>
<td>
3
</td>
<td>
Employer
</td>
<td>
</td>
<td>
</td>
<td>
7/31/2012
</td>
</tr>
<tr class="item">
<td align="center">
<a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$Control1$gv','Select$6')">
Edit</a>
</td>
<td align="center" style="width: 15px;">
</td>
<td>
Test6
</td>
<td>
a
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
7/20/2012
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</td>
</tr>
<tr class="footer">
<td>
</td>
</tr>
</table>
</form>
</body>
</html>
the result I am getting is all the matching elements but how can I get only the td which is test?
<td >
test
</td>
<td >
DEMO TEST OCT 25
</td>
<td class="firefinder-match">
DEMO TEST OCT 25
</td>
<td >
DEMO TEST OCT 25
</td>
<td >
DEMO TEST OCT 25
</td>
<td >
DEMO TEST OCT 25
</td>
The issue lies with tr.item. There are multiple rows with that class and you are selecting all of them. Be more specific by using the first-child pseudo class so it will only select the first tr.item and not all of them.
Here is how I able to get:
table#ctl00_ContentPlaceHolder1_Control1_gv.gv tbody tr.item:nth-child(3) > td:nth-of-type(3)

Resources