turboTable primeng input enterKey - html

Using the incell editing for the primeng TurboTable, I am trying to execute a method by clicking on enter key. Here is the following code:
<td pEditableColumn>
<p-cellEditor>
<ng-template pTemplate="input">
<input type="text" [(ngModel)]="rowData.vin" (keyup.enter)="onKeyPress($event)">
</ng-template>
<ng-template pTemplate="output">
{{rowData.vin}}
</ng-template>
</p-cellEditor>
</td>
The problem is that the method onKeyPress is not executed by clicking on the enterKey. So I've tried with keypress as following:
<td pEditableColumn>
<p-cellEditor>
<ng-template pTemplate="input">
<input type="text" [(ngModel)]="rowData.vin" (keypress)="onKeyPress($event)">
</ng-template>
<ng-template pTemplate="output">
{{rowData.vin}}
</ng-template>
</p-cellEditor>
</td>
And what I've noticed is that the method onKeyPress is executed by clicking on any button except the enter Key.

I think onEditComplete event catches the enter key press.
Check https://www.primefaces.org/primeng/#/table under Events.
To call your function on enter key press you can do this:
<p-table ... (onEditComplete)="onEditComplete($event)">
...
<td [pEditableColumn]="rowData" pEditableColumnField="'vin'">
In your component:
onEditComplete(event) {
console.log(event.data);
}

I Tried to use keydown instead of Keyup and it works fine
<td pEditableColumn>
<p-cellEditor>
<ng-template pTemplate="input">
<input type="text" [(ngModel)]="rowData.vin"
(keydown.enter)="onKeyDown($event)">
</ng-template>
<ng-template pTemplate="output">
{{rowData.vin}}
</ng-template>
</p-cellEditor>
</td>

Related

How to submit a form by pressing Enter Key from any field in the form in Angular Material?

I want to submit the form by pressing enter key without clicking on update button once any field is edited and update button gets enabled as below in the screenshot.
This update form is a dialog which opens up on click of edit functionality on a row of the table.
Case: Now form is edited on Emp Code field and it's highlighted, so on click of enter key this form should be submitted.
Below is code sample of update form in HTML.
<mat-card-content>
<form class="example-form" [formGroup]="docForm">
<table>
<tr>
.
.
<td>
<mat-form-field appearance="outline">
<mat-label>Emp Code</mat-label>
<input matInput name="empCode" formControlName="empCd" maxLength = "4" >
</mat-form-field>
</td>
.
.
</tr>
</table>
</form>
</mat-card-content>
<button mat-raised-button style="width: 95px;" color="primary" [disabled]='docForm.invalid || !docForm.dirty (click)="update()"> Update </button>
I tried some approach, but not working as expected.
<button mat-raised-button (keyup.enter)="!($event.target.tagName == 'TEXTAREA' || $event.target.tagName == 'BUTTON')"
style="width: 95px;" color="primary" [disabled]='docForm.invalid || !docForm.dirty' (click)="update()"> Update </button>
Thanks in advance for any help on this.
you should be able to just bind to the ngSubmit event:
<form class="example-form" [formGroup]="docForm" (ngSubmit)="docForm.valid && docForm.dirty && update()">
for this to trigger, you need a submit type element somewhere inside your form, it may be hidden though:
<input [style.display]="'none'" type="submit">
or if you prefer, you may just bind to the keyup.enter event on the form:
<form class="example-form" [formGroup]="docForm" (keyup.enter)="docForm.valid && docForm.dirty && update()">

Issue when Table with Inputs is inside of a Form

I'm building an Angular application with PrimeNG. I have a form that contains a p-table (list of products) with inputs (quantity and price), when I select the first product from a dialog and enter the inputs (quantity and price), then select a second product, I lose the first quantity and price that enter for the first product.
This issue only happened when putting the table with inputs inside of the form.
Is there a right way to resolve this? My code is below.
HTML:
<form #form="ngForm" (ngSubmit)="valider(form)">
<p-table [value]="object.produits" >
<ng-template pTemplate="header">
<tr>
<th>Code Produit</th>
<th>Quantité</th>
<th>Price</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-produit>
<tr [pSelectableRow]="produit">
<td>{{produit.codeProduit}}</td>
<td>
<input type="text" size="10" pInputText name="quantite" [readonly]="action=='show'" pKeyFilter="num" [ngModel]="produit.quantite" (ngModelChange)="produit.quantite = $event;">
</td>
<td>
<input type="text" size="10" pInputText name="prixUnitaire" [readonly]="action=='show'" pKeyFilter="num" [ngModel]="produit.prixUnitaire"(ngModelChange)="produit.prixUnitaire = $event;">
</td>
</tr>
</ng-template>
<ng-template pTemplate="summary">
<button type="button" (click)="showDialogProduit()" pButton label="Ajouter Produit"></button>
</ng-template>
</p-table>
</form>
<p-dialog header="Liste des produits" [(visible)]="dialogProduit" >
<p-table #dt_produits [value]="produits" selectionMode="multiple" [(selection)]="operationCommodities.produits" >
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Désignation</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-produit>
<tr [pSelectableRow]="produit">
<td>{{produit.codeProduit}}</td>
<td>{{produit.designation}}</td>
</tr>
</ng-template>
<ng-template pTemplate="summary">
<button pButton type="button" label="Terminer" (click)="closeDialogProduit()"></button>
</ng-template>
</p-table>
</p-dialog>
TS:
showDialogProduit() {
this.dialogProduit = true;
}
closeDialogProduit() {
this.dialogProduit = false;
}
Stackblitz Demo:
https://stackblitz.com/edit/primeng-tablebasic-demo-a7bdgm?file=src%2Fapp%2Fapp.component.html
The problem is that input fields don't have a unique name which messes up how ngModel directive works. When I updated the code as follows, it was fixed. Note that the [name] attributes of both input fields are dynamic values based on produit.codeProduit
<tr [pSelectableRow]="produit">
<td>{{produit.codeProduit}} </td>
<td>
<input type="text" size="10" pInputText [name]="'quantite_' + produit.codeProduit" [readonly]="action=='show'" pKeyFilter="num" [ngModel]="produit.quantite" (ngModelChange)="produit.quantite = $event;">
</td>
<td>
<input type="text" size="10" pInputText [name]="'prixUnitaire_' + produit.codeProduit" [readonly]="action=='show'" pKeyFilter="num" [ngModel]="produit.prixUnitaire"(ngModelChange)="produit.prixUnitaire = $event;">
</td>
</tr>
Please check Forked stackblitz with updated code.
As an aside, I recommend you change your implementation to use Angular Reactive Forms instead of ngModel;

How to make my ngForm dirty after modifying an Angular Material table inside the form

I have an Angular form like below and it has a save button that is disabled until a input field is changed (made dirty) and it works fine with input elements.
Then I placed a Angular Material UI table inside the form and I want the form to be dirty if I make a change to the table ex. select a row, edit a row value, add a row, delete a row, etc.
Is there a way to make the form dirty, to enable the save button, either manually setting it in the ts file or some other way so that my save button will be enabled?
I tried putting a form-control class in the table class, but I don't think it worked and it messed up all my css, because I'm using an Angular Material table with lots of pre defined CSS.
Here is my code that show my basic form with a mat table in it
// just to show here how my ngForm is in the ts file
#ViewChild('editForm', {static: false}) editForm: NgForm;
<form #editForm="ngForm" id="editForm" (ngSubmit)="updateData()">
<button class="btn btn-primary btn-sm" type="submit" [disabled]="!editForm.dirty">Save</button>
<input type="text" class="form-control" placeholder="ex. Chuck" [(ngModel)]="matterData.firstName" name="firstName">
<div class="form-row">
<div class="form-group col-md-12">
<table mat-table [dataSource]="generalSmokingSource" class="smoking-table" name=smokingTable>
<ng-container matColumnDef="product">
<th mat-header-cell *matHeaderCellDef> Product </th>
<td mat-cell *matCellDef="let element"> {{element.product}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="generalSmokingColumns"></tr>
<tr mat-row *matRowDef="let row; columns: generalSmokingColumns;"></tr>
</table>
</div>
</div>
</form>
I think one solution, maybe not the best, is to add a second check in the disabled attribute Like
[disabled]="!editForm.dirty || tableModified"
and then when I modify something in a table (ex. add a row, select a row checkbox, etc) I can set this bool to true. And then after I save, set it to false!
Any thoughts? Is there a better way?
I think you can use (ngModelChange) event in input tag eg.
import {Component} from '#angular/core'
import {FormsModule} from '#angular/forms'
#Component({
selector: 'template-driven-form',
template: `
<section>
<h1>(ngModelChange) Example:</h1>
<form #f="ngForm" (ngSubmit)="onSubmitTemplateBased()">
<p>
<label>Name:</label>
<input type="text"
[ngModel]="username"
(ngModelChange)="onChange($event)"
name="username"
required>
</p>
<p>
<button type="submit" [disabled]="!f.valid">Submit</button>
</p>
</form>
</section>
`
})
export class TemplateDrivenForm {
username: string = 'nome';
onSubmitTemplateBased() {
console.log(this.username);
}
onChange(event) {
console.log(event);
}
}
May this help. Thank You

How to disable kendo-grid-checkbox-column?

How to disable kendo-grid-checkbox-column?
I have tried
[disabled]="true"
[attr.disabled]="true"
disabled ="true"
disabled
readonly
But nothing is helped to disable this below column
<kendo-grid-checkbox-column width="50" showSelectAll="true">
</kendo-grid-checkbox-column>
You can produce a disabled checkbox by specifying custom templates and adding a condition to the [disabled] attribute.
<kendo-grid-checkbox-column width="80" [locked]="true">
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex" >
<input *ngIf="!dataItem.IsNew"
[disabled]="dataItem.IsNew === true"
type="checkbox"
class="k-checkbox"
id="checkbox-{{rowIndex}}"
[kendoGridSelectionCheckbox]="rowIndex"
/>
<label class="k-checkbox-label"
for="checkbox-{{rowIndex}}">
</label>
</ng-template>
</kendo-grid-checkbox-column>
This will render out a Kendo checkbox that will be disabled according to your conditions specified above.
If you want to display a select all checkbox in the header you need to add this template to the checkbox column:
<ng-template kendoGridHeaderTemplate >
<input kendoGridSelectAllCheckbox type="checkbox"
class="k-checkbox"
id="headerCheckbox"
/>
<label class="k-checkbox-label"
for="headerCheckbox"
></label>
</ng-template>
You can use the Grid rowClass input and provide a function that will return the "k-disabled" class (or any other custom class that would prevent the user from interacting with the given row), for all data items that pass some condition, e.g.:
public isDisabled(args) {
return {
'k-disabled': args.dataItem.UnitsOnOrder === 0
};
}
I hope this helps.
========OR========
<kendo-grid-checkbox-column>
<ng-template kendoGridCellTemplate let-dataItem let-
rowIndex="rowIndex" >
<div class="{{dataItem.UnitsOnOrder === 0 ? 'k-disabled' : ''}}">
<input [kendoGridSelectionCheckbox]="rowIndex" />
</div>
</ng-template>
CSS class was changed from k-disabled to k-state-disabled in recent Kendo UI theme versions
Resource: https://www.telerik.com/forums/kendo-angular-grid---row-selection

How to fire "focusout" event when focus lost of input placed in table?

I have a table where inputis placed:
<tr *ngFor="let persons of ReceivedData">
<td *ngFor="let person of persons">
<div *ngIf="person.personId === editRowId && person.editable === true ">
<input type="number" [(ngModel)]="person.CarCount"
(focusout)="focusOutFunction()"/>
</div>
<div *ngIf="person.editable === false " (click)="toggle(person)">
{{ person.CarCount ? person.CarCount : '-' }}
</div>
</td>
<tr>
But the focusout event isn't fired.
Here's the method handling the focusout function:
focusOutFunction() {
}
Interestingly focusout works perfectly when input is not placed inside table:
<input type="number" (focusout)="focusOutFunction()" />
How can I fire an event when I focus inside of the table?
Here's a working plnkr of focusout proc'ing inside a table with a similar setup as you have. The other key is to include an autofocus attribute:
<input type="number" [(ngModel)]="person.CarCount"
(focusout)="focusOutFunction()" autofocus/>
Use blur event to get focus out.
<input type="number" [(ngModel)]="person.CarCount"
(blur)="focusOutFunction()"/>