Handle selection p-checkbox with the same group - html

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!

Related

Why are the form inputs in my html table unclickable?

I am trying to render a table in html that is the representation of a reactive form array.
I loop over the complex object (FormGroup > FormArray > FormGroup > FormArray) With the final array being the data that we want to represent to the UI in its transformed format. (Happens in the function groupFormGroup())
Everything works fine, the data is correctly transformed and displayed.
However, now I am trying to add inputs (NOT formControlName inputs) to the table and when they load, they load without me being able to click into, or change their value. They are not disabled, just unclickable. No errors come up in the console.
What I have tried:
Modifying the class names so it is no longer class='form-control'
Increasing the z-index of inputs to be on the forefront
Making the inputs position relative
Here is the code:
<div class="row" [formGroup]="address">
<div class="col-12">
<table class="w-100">
<thead>
<th></th>
<th>Order ID</th>
<th>GP Code</th>
<th>Product</th>
<th>Quantity</th>
<th>Preset Suite Number</th>
<th></th>
</thead>
<tbody>
<ng-template formArrayName="addressOrders" ngFor let-addressOrder [ngForOf]="address.get('addressOrders').controls" let-ao="index">
<ng-container [formGroup]="addressOrder">
<ng-template ngFor let-fulfillment [ngForOf]="groupFormGroup(addressOrder.get('fulfillments').getRawValue(),'orderDetailId')" let-f="index">
<tr>
<td class='table-input'>
<input type="checkbox"
(change)="updateFulfillmentFormControl(fulfillment,addressOrder,'selected',$event)"/>
</td>
<td>{{addressOrder.get('orderId').value}}</td>
<td>{{fulfillment['gpItemNumber']}}</td>
<td>{{fulfillment['name']}}</td>
<td>{{fulfillment['quantity']}}</td>
<td>
<ng-container *ngIf="fulfillment['isSuite']">
<!-- <input class="form-control" (keydown)="updateFulfillmentFormControl(fulfillment,addressOrder,'suiteNumber',$event)" /> -->
<input type="text" class="form-control" />
</ng-container>
</td>
<td>Edit Detail</td>
</tr>
</ng-template>
</ng-container>
</ng-template>
</tbody>
</table>
</div>
</div>
And the code generating the Form Group:
draw() {
this.formGroup = this.initFormGroup(this.ordersToDisplay)
}
initFormGroup(ordersToDisplay: Array<BulkFulfillCustomer>):FormGroup {
var queueList = this.queues.map(q => q['queue_id']);
return this.fb.group({
customers: this.fb.array(
ordersToDisplay.map(otd => {
return this.fb.group({
gpCustomerNumber:[otd.gpCustomerNumber],
customerName:[otd.customerName],
customerAddresses: this.initAddressForm(otd.addressOrders, queueList)
})
})
)
})
}
initAddressForm(addressOrders: Array<BulkFulfillAddress>, queues:Array<string>):FormArray {
return this.fb.array(
addressOrders.map(ao => {
return this.fb.group({
addressLine:[ao.addressLine],
bundleShipment:[true],
addressOrders: this.initAddressOrdersForm(ao.orders,queues)
})
})
)
}
initAddressOrdersForm(orders: Array<BulkFulfillOrder>, queues:Array<string>):FormArray {
return this.fb.array(
orders.map(o => {
return this.fb.group({
orderId: [o.order.id],
fulfillments: this.initFulfillmentsForm(o.orderDetailFulfillments,queues)
})
})
)
}
initFulfillmentsForm(fulfillments: Array<FulfillmentLine>, queues:Array<string>) {
return this.fb.array(
fulfillments.map(f => {
return this.fb.group({
selected:[true],
expandDetail:[false],
isSuite:[f.inventory.isSuite],
suitePrefix:[f.inventory.suitePrefix],
gpItemNumber:[f.inventory.gpItemNumber],
name:[f.inventory.name],
queueId:[{value:f.inventory.pulseQueueId,disabled:(!this.isPulseFulfill && f.inventory.fulfillmentMethod != INVENTORY_FULFILLMENT_PULSE)}, Validators.compose([Validators.required, ContainsListValidator(queues,'Queue ID')])],
orderDetailId:[f.orderDetailFulfillment.orderDetailId],
pulseOrderId:[f.orderDetailFulfillment.pulseOrderId],
suiteNumber:[{value:f.orderDetailFulfillment.suiteNumber,disabled:!this.isPulseFulfill || !f.inventory.isSuite}, Validators.required],
quantity:[{value:f.orderDetailFulfillment.quantity,disabled:f.orderDetailFulfillment.fulfillmentMethod != 1},Validators.compose([Validators.required, Validators.min(1),Validators.max(f.orderDetailFulfillment.quantity)])]
})
})
)
}

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>

Bootstrap tooltip is switching width on hover

I have a specific problem with my angular web-application. I'm viewing a matrix in my application with data in it. When I hover over my data in this matrix it will show some basic information about the object. anyway: everytime when I hover over it with my cursor, it changes the width from right to left.
my HTML:
<table class="table table-bordered" style="margin-top: 22px">
<colgroup *ngFor="let y of yArray">
<col style="width: 5%" *ngFor="let x of xArray"/>
</colgroup>
<tr *ngFor="let y of yArray">
<td *ngFor="let x of xArray" [style.background]="getBackground(y+1,x+1)"
[tooltip]="getTooltipContent(y+1,x+1)" placement="bottom">
{{ setBerechnung(y+1, x+1).messwert}}
</td>
</tr>
</table>
my GetTooltipContent-Function (TS/Angular):
public getTooltipContent(yKoordinate: number, xKoordinate: number)
{
const sensor = this.fullZoneResponse.sensorInSurface
.filter(x => x.xKoordinate == xKoordinate && x.yKoordinate == yKoordinate);
let zoneAssignment: IzoneAssignment[] = [];
this.fullZonenResponse.zoneInSurface.forEach((value) => {
zoneAssignment.push(...value.assignmentOfZone);
});
const sensorIsInSurface = zoneAssignment.filter(x => x.idSensor == sensor[0].id);
if (sensorIsInSurface.length > 0) {
this.zoneAssignment = this.fullZonenResponse.zoneInSurface.filter(x => x.id == sensorAssignment[0].idZone);
return this.tooltipContent = this.zoneAssignment[0].description;
}
else
{
return this.tooltipContent = "";
}
}
here is a screenshot of it's normal behaviour:
and another one of it's bad behaviour:
I would be very very thankful if you could help me out!
I fixed it by my own!
The problem was that my ngx-bootstrap tooltip got added to my DOM on runtime. I just added the "container='body'"-attribute, so the tooltip get's added on the right element.
my HTML now:
<tr *ngFor="let y of yArray">
<td *ngFor="let x of xArray" container="body" [style.background]="getBackground(y+1,x+1)" [tooltip]="getTooltipContent(y+1,x+1)" placement="bottom">
{{ setBerechnung(y+1, x+1).messwert}}
</td>
</tr>

Angular4 - execute function if NOT all checkboxes are selected

I have a main checkbox which has ngModel value as [(ngModel)]="formModel.acknowledged1 and on component it is set to false like
formModel = {
acknowledged1 :false
}
And I have a table with n number of rows, each row having checkboxes with ngModel as [(ngModel)]="formModel.acknowledged so when i click on main checkbox, all checkboxes on tables get selected and then my function deleterow gets executed, but i want
If I select only singly checkbox from table rows, then some other function should get executed. see below to make my question clear.
html -
<p>
<checkbox [(ngModel)]="formModel.acknowledged1" id="box1" name="acknowledgement1"></checkbox></p>
<tbody infiniteScroll
[infiniteScrollDistance]="2"
[infiniteScrollThrottle]="300"
(scrolled)="onScroll()"
[scrollWindow]="false">
<ng-container *ngFor="let data of allData>
<tr class= "row-break">
<checkbox [(ngModel)]="formModel.acknowledged1" id="box2" name="acknowledgement2">
</checkbox>
<td>
<a>{{data.Code}}</a>
</td>
<td>
{{data.Description}}
</td>
</tr>
</ng-container>
</tbody>
Component.ts -
export class CodesComponent implements OnInit{
formModel = {
acknowledged1 :false
}
ngOnInit (){
deleteallrow(){
if(this.formModel.acknowledged1==true){
this.reasonCodesActions.deleterow();
}
deletesinglerow(){ }
}
You need to create an array with single booleans for every checkbox.
component.html
...
<ng-container *ngFor="let data of allData; let i = index;">
<tr class="row-break">
<checkbox
(change)="changeBox(i)"
[checked]="checkboxes[i]"
id="box2"
name="acknowledgement2"
></checkbox>
...
</tr>
</ng-container>
component.ts
...
checkboxes = [];
changeBox(index) {
if (this.checkboxes[index]) {
return this.checkboxes[index] = !this.checkboxes[index];
}
return this.checkboxes[index] = true;
}
...
Something in the code could be wrong, I don't use Angular for a while, but that is the logic that I've used in the last time that I've made it!

Api Delete Angular 5

Hello i'm working in Angular 5 and my api delete works (postman & site --> link = api/employees/:id --> localhost:4200/api/employees/5a2025db26589c230865527a) , but I think my HTML code is wrong or the steps in between. Can somebody help me plz i've been stuck at this all day..
HTML :
<h2>Info employees</h2>
<table class="table">
<tr>
<th>Name</th>
<th>Age</th>
<th>Email</th>
<th>Wage</th>
</tr>
<tr *ngFor="let employee of employees">
<td>{{ employee.name }}</td>
<td>{{ employee.age }}</td>
<td> {{ employee.email }} </td>
<td> {{ employee.wage}}</td>
<td>{{employee._id}}</td>
<td>
Delete
</td>
</tr>
</table>
Component.ts :
deleteEmployee(id){
var employees = this.employees;
this._dataService.deleteEmployee(id)
.subscribe(data => {
if(data.n == 1){
for(var i = 0;i < employees.length;i++){
if(employees[i]._id == id){
employees.splice(i, 1);
}
}
}
});
}
data.service :
deleteEmployee(id){
return this._http.delete('/api/employees/'+id)
.map(res => res.json());
}
replace data-ng-click with (click) and make the HTML element a <button> since it's not redirecting anywhere.
Edit: employees.splice(i, 1); replace with this.employees.splice(i, 1); to reflect the change in the view.
Actually, you need to change the logic of
if(data.n == 1){
for(var i = 0;i < employees.length;i++){
if(employees[i]._id == id){
employees.splice(i, 1);
}
}
}
Because basically you are deleting user in the view without considering the data of the backend service. What response do you get from that DELETE endpoint ? Does it return the deleted user or the id of the deleted user ?
maybe little late ..but that if you try something like this .. with .filter() ES6 (also Typescript) Array native method ..
so like:
eleteEmployee(id){
var employees = this.employees; //why use it?? ..no need it
this._dataService.deleteEmployee(id)
.subscribe(data => {
if(data.n == 1){
this.employees = this.employees.filter(xx=> xx._id != id) // <--- so filter and RETURN ALL non matching given ID
}
});
}
Hope it helps you !! ...