PrimeNG v5.2.4 p-table global filter not working - primeng

I used p-datatable previously and the global filter worked. However when I changed to p-table, the global filter template displayed nicely but the input box is not clickable.
Here's the code
<p-table #dt
[value]="sensorLocationList"
[columns]="cols"
[(selection)]="selectedSl"
sortMode="multiple" [paginator]="true"
[rows]="20"
[globalFilterFields]="['dummy1','dummy2','dummy3','dummy4']"
>
<ng-template pTemplate="caption">
<div style="text-align: left">
<i class="fa fa-search" style="margin:4px 4px 0 0"></i>
<input type="text" pInputText size="50" placeholder="Global Filter" (input)="dt.filterGlobal($event.target.value, 'contains')" style="width:auto">
</div>
</ng-template>
Header:
<ng-template pTemplate="header" let-columns>
<tr>
<th style="width: 2.25em"></th>
<th *ngFor="let col of columns" [pSortableColumn]="col.field">
{{col.header}}
<p-sortIcon [field]="col.field"></p-sortIcon>
</th>
</tr>
<tr>
<th style="width: 2.25em">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th *ngFor="let col of columns" [ngSwitch]="col.field">
<input *ngSwitchCase="'dummy1'" pInputText placeholder="Search" type="text" class="search-box" (input)="dt.filter($event.target.value, col.field, col.contains)">
<input *ngSwitchCase="'dummy2'" pInputText placeholder="Search" type="text" class="search-box" (input)="dt.filter($event.target.value, col.field, col.contains)">
<input *ngSwitchCase="'dummy3'" pInputText placeholder="Search" type="text" class="search-box" (input)="dt.filter($event.target.value, col.field, col.contains)">
<input *ngSwitchCase="'dummy4'" pInputText placeholder="Search" type="text" class="search-box" (input)="dt.filter($event.target.value, col.field, col.contains)">
</th>
</ng-template>
And one sample of body:
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr [pSelectableRow]="rowData">
<td [pEditableColumn]="rowData" [pEditableColumnField]="'dummy1'" [ngStyle]="cellEdit(rowData)">
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="rowData.dummy1">
</ng-template>
<ng-template pTemplate="output">
{{rowData.dummy1}}
</ng-template>
</p-cellEditor>
</td>
</tr>
</ng-template>
</p-table>
Everything works fine including the column filter. I've searched everywhere for the solution and found most of the problem is because the PrimeNG version was not up-to-date, but my version is updated. Any idea?

Add [pSortableColumnDisabled]="!col.sortable" to the table header tag:
<th *ngFor="let col of columns" [pSortableColumn]="col.field" [pSortableColumnDisabled]="!col.sortable">

Remove "ng-template" from around the GlobalFilter

Related

How can I create a custom command to fill fields in both scenarios with different structures?

So I have 2 scenarios, from different pages on the application I'm testing:
Scenario 1:
<tbody>
<tr>
<td class="colLabel90 colCampo">
<label style="font-weight: bold">* Nome:</label>
</td>
<td>
<input type="text" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all requiredColor role="textbox" aria-disabled="false" aria-readonly="false">
</td>
</tr>
<tr>
.....
</tr>
</tbody>
Scenario 2:
<tr role="row">
<th id="dataTableFormId:DataTableId:j_idt169" class="ui-state-default ui-sortable-column ui-filter-column ui-resizable-column colFilterSize" role="columnheader" aria-label="Nome: activate to sort column ascending" scope="col" style="width:90%" aria-sort="other">
<span class="ui-column-resizer ui-draggable ui-draggable-handle"> </span>
<span class="ui-column-title">Name</span>
<span class="ui-sortable-column-icon ui-icon ui-icon-carat-2-n-s"> </span>
<input id="dataTableFormId:DataTableId:j_idt169:filter" name="dataTableFormId:DataTableId:j_idt169:filter" class="ui-column-filter ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" autocomplete="off" role="textbox" aria-disabled="false" aria-readonly="false">
</th>
<th id="dataTableFormId:DataTableId:j_idt171" class="ui-state-default ui-sortable-column ui-filter-column ui-resizable-column colFilterSize" role="columnheader" aria-label="Fabricante: activate to sort column ascending" scope="col" style="width:90%">
<span class="ui-column-resizer ui-draggable ui-draggable-handle" style="display: none;"> </span>
<span class="ui-column-title">Manufacturer</span>
<span class="ui-sortable-column-icon ui-icon ui-icon-carat-2-n-s"></span>
<input id="dataTableFormId:DataTableId:j_idt171:filter" name="dataTableFormId:DataTableId:j_idt171:filter" class="ui-column-filter ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" autocomplete="off" role="textbox" aria-disabled="false" aria-readonly="false">
</th>
</tr>
Here is what I'm trying to do on Cypress:
Cypress.Commands.add("typeOnFields", (field, value) => {
cy.get('#center').contains(field).parent().find('input').clear().type(value)
})
//Where field is the name of the field in <label> or <span>, in this case it's 'Name'
This is not working, find() won't find the input in any scenario.
Because the two scenarios have different structures and parent elements, you would need to use a variant of .parents() that keeps moving up to the first parent that contains an input
cy.contains(field) // return the <label> or <span> with "field"
.parents(':has(input)') // move up until element has an <input> inside
.eq(0) // take first (multiple are returned)
.find('input') // find the <input> element
.clear().type(value)
To avoid complexity, I would actually use two commands here one for the table header and one for the table body.

prime ng row expansion data key issue

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.

angular smart table - pagination doesn't work on refreshing data object

I'm using angular-smart-table, where I'm able to display my data correctly with pagination.
And I do add new records/ update existing records on the same page. Here's the screenshot for reference -
But here, I'm facing problems with pagination after adding a new record/ updating existing one. That is on refreshing an object, it doesn't consider pagination and shows all records on same page at once.
Here is my controller code -
$scope.smartTablePageSize = 10;
$scope.rowsPerPage = [5, 10, 15, 20, 25];
// my function to add a new record
vm.insertAccount = function() {
if(vm.validateAll())
$http({
method: 'POST',
url: addAccountUrl,
data: vm.accountInfo,
headers: { 'Content-Type': 'application/json' }
}).then(function(success) {
vm.getAllAccountsData(); // refreshing data object
}, function(error) {
});
}
// function to refresh data object
vm.getAllAccountsData = function() {
$http.get(accountListUrl)
.then(function(success) {
if (success.data) {
vm.allAccountsData = success.data; // updating data here
}
}, function(error) {
})
}
And the respective HTML -
<div class="col-xlg-12 col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="col-xs-12 form-inline form-group mt-20">
<label for="rows">Rows on page</label>
<select class="form-control show-tick" id="rows" title="Rows on page" selectpicker ng-model="smartTablePageSize" ng-options="i for i in rowsPerPage">
</select>
</div>
<table class="table mt-20 mb-20" ng-if="vm.allAccountsData.length > 0" st-table="vm.allAccountsData">
<thead class="sortable">
<tr>
<th class="table-id" st-sort="id" st-sort-default="true">#</th>
<th st-sort="accounttype">Account Type</th>
<th st-sort="vendor">Vendor</th>
<th st-sort="accountnumber">Account No.</th>
<th st-sort="paymentmode">Payment Mode</th>
<th st-sort="ponumber">PO No.</th>
<th st-sort="vendorcode">Vendor Code</th>
<th st-sort="costcenter">Cost Center</th>
<th st-sort="glcode">GL Code</th>
<th>Action</th>
</tr>
<tr>
<th></th>
<th>
<input st-search="accounttype" placeholder="Search Account Type" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="vendor" placeholder="Search Vendor" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="accountnumber" placeholder="Search Account No." class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="paymentmode" placeholder="Search Payment Mode" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="ponumber" placeholder="Search PO No." class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="vendorcode" placeholder="Search Vendor Code" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="costcenter" placeholder="Search Cost Center" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="glcode" placeholder="Search GL Code" class="input-sm form-control search-input" type="search" />
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in vm.allAccountsData">
<td class="table-id">{{item.index + 1}}</td>
<td>{{item.accounttype}}</td>
<td>{{item.vendor}}</td>
<td>{{item.accountnumber}}</td>
<td>{{item.paymentmode}}</td>
<td>{{item.ponumber}}</td>
<td>{{item.vendorcode}}</td>
<td>{{item.costcenter}}</td>
<td>{{item.glcode}}</td>
<td>
<button class="btn btn-info editable-table-button btn-xs" ng-click="vm.editAccount(item);">View/Edit</button>
<button class="btn btn-danger editable-table-button btn-xs" ng-click="vm.confirmDeleteAccountModal('app/pages/utilities/pdfNormalizer/confirm-delete-account.html', 'sm', item)">Delete</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="10" class="text-center">
<div st-pagination="" st-items-by-page="smartTablePageSize" st-displayed-pages="10"></div>
</td>
</tr>
</tfoot>
</table>
</div>
So, on refreshing object, What I expect is the similar table with pagination as shown above. And What I'm getting is the table with all records without considering pagination -
I struggled a bit and found an answer! We can use st-safe-src directive on angular-smart-table.
I used it as -
<table class="table mt-20 mb-20" st-table="allAccountsData" st-safe-src="vm.allAccountsData">
Where, allAccountsData is a temporary data object & vm.allAccountsData is an actual one.
Then, I iterated over allAccountsData as -
<tr ng-repeat="item in allAccountsData">
That's it! No any changes in controller code!

Badident error when using "as" in ng-repeat

I have the following code that filters through a table of results:
<strong>CLIENTS [ {{ results.length }} ]</strong>
<thead ng-show="clientSearch">
<tr>
<th><i class="fa fa-search"></i></th>
<th class="search-box">
<input type="text" placeholder="Search Name" ng-model="searchResult.firstname">
</th>
<th class="search-box">
<input type="text" placeholder="Search Surname" ng-model="searchResult.lastname">
</th>
<th class="search-box">
<input type="text" placeholder="Search Address" ng-model="searchResult.address">
</th>
<th class="search-box">
<input type="text" placeholder="Search Email" ng-model="searchResult.email">
</th>
<th class="search-box">
<input type="number" placeholder="Search Mobile" ng-model="searchResult.mobile">
</th>
<th class="search-box">
<input type="date" class="datepicker" placeholder="Search By Date" ng-model="searchResult.registrationDate">
</th>
</tr>
</thead>
This is the code the produces the table data:
<tr ng-repeat="client in clients as results | filter : searchResult " ng-dblclick="open(client)">
<td>{{$index + 1}}</td>
<td>{{client.firstname}}</td>
<td>{{client.lastname}}</td>
<td>{{client.address}}</td>
<td>{{client.email}}</td>
<td>{{client.mobile}}</td>
<td>{{client.registrationDate | date: 'medium'}}</td>
<td ng-if="results.length === 0">NO RESULTS FOUND</td>
</tr>
But I get this error https://code.angularjs.org/1.3.16/docs/error/ngRepeat/badident when I try to use ngRepeat.
Any suggestions on how I can fix this.

how to validate input in angularJS before the button press to add item in html table

How to validate the input elements before performing any operation, I have four html input element and html table when you click item on add to list it added item in HTML table now my problem is validation, I want to validate input elements on button click.
<div ng-controller="BookStore">
<br />
<h2>Add New Book</h2>
<div style="border: 1px solid blue;">
<table>
<tr>
<td>ISBN: </td>
<td>
<input type="text" ng-model="item.ISBN" />
</td>
</tr>
<tr>
<td>Name: </td>
<td>
<input type="text" ng-model="item.Name" /></td>
</tr>
<tr>
<td>Price(In Rupee): </td>
<td>
<input type="number" ng-model="item.Price" /></td>
</tr>
<tr>
<td>Quantity: </td>
<td>
<input type="number" ng-model="item.Quantity" /></td>
</tr>
<tr>
<td colspan="2">
<input type="Button" value="Add to list" ng-click="addItem(item)" />
</td>
</tr>
</table>
</div>
<div style="padding-top: 15px;">
<table border="1" class="mytable">
<tr>
<td>ISBN</td>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Total Price</td>
<td>Action</td>
</tr>
<tr ng-repeat="item in items">
<td>{{item.ISBN}}</td>
<td>
<span ng-hide="editMode">{{item.Name}}</span>
<input type="text" ng-show="editMode" ng-model="item.Name" />
</td>
<td>
<span ng-hide="editMode">{{item.Price}}</span>
<input type="number" ng-show="editMode" ng-model="item.Price" /></td>
<td>
<span ng-hide="editMode">{{item.Quantity}}</span>
<input type="number" ng-show="editMode" ng-model="item.Quantity" /></td>
<td>{{(item.Quantity) * (item.Price)}}</td>
<td><span>
<button type="submit" ng-hide="editMode" ng-click="editMode = true; editItem(item)">Edit</button></span>
<span>
<button type="submit" ng-show="editMode" ng-click="editMode = false">Save</button></span>
<span>
<input type="button" value="Delete" ng-click="removeItem($index)" /></span></td>
</tr>
<tr ng-show="!(items).length">
<td style="text-align: center" colspan="7">No item exist</td>
</tr>
</table>
</div>
<br />
<div style="font-weight: bold">Grand Total: {{totalPrice()}}</div>
<br />
</div>
Click here to see code
You need to use validation of the form. For this wrap your table into form tag and use ngSubmit directive (or ngClick on the type="submit" button).
In your case you want required constraint added to form fields. Then it makes sense to disable submit button until form is valid ng-disabled="bookForm.$invalid".
All together:
<form novalidate ng-submit="addItem(item)" name="bookForm">
<table>
<tr>
<td>ISBN: </td>
<td>
<input type="text" ng-model="item.ISBN" required />
</td>
</tr>
<tr>
<td>Name: </td>
<td>
<input type="text" ng-model="item.Name" required />
</td>
</tr>
<tr>
<td>Price(In Rupee): </td>
<td>
<input type="number" ng-model="item.Price" required />
</td>
</tr>
<tr>
<td>Quantity: </td>
<td>
<input type="number" ng-model="item.Quantity" required />
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" ng-disabled="bookForm.$invalid" value="Add to list" />
</td>
</tr>
</table>
</form>
Demo: http://plnkr.co/edit/JIozQNai88dHipaIfeLH?p=preview
i have found the answer i make button disabled when the texboxes are empty
<div class="col-xs-12 col-sm-12">
<button class="btn btn-xs btn-primary" type="button" value="Add To List" ng-disabled="!item.Description || !item.FileName || !item.Path" ng-click="item.Description;addItem(item)">Add</button>
</div>
Click Here to see the plunker code

Resources