I'm trying to add a new row to the current table so that I can have a row under the list of data that can have a save button and an insert to be done e.g. save phone number. I have added html comments of where the new row will go but not sure how to do it in PrimeNg.
See the code below:
<div class="m_datatable m-datatable m-datatable--default m-datatable--loaded">
<p-dataTable [value]="personPhone.phones"
emptyMessage="{{l('NoData')}}"
paginator="false"
rows="5"
tableStyleClass="m-datatable__table">
<p-column header="{{l('Actions')}}" [style]="{'width':'130px','text-align':'center'}">
<ng-template let-record="rowData" pTemplate="body">
<button (click)="deletePhone(phone, personPhone)" class="btn btn-outline-danger m-btn m-btn--icon m-btn--icon-only m-btn--pill">
<i class="fa fa-times"></i>
</button>
</ng-template>
</p-column>
<p-column header="{{l('PhoneType')}}">
<ng-template let-record="rowData" pTemplate="body">
{{getPhoneTypeAsString(record.type)}}
</ng-template>
</p-column>
<p-column header="{{l('PhoneNumber')}}">
<ng-template let-record="rowData" pTemplate="body">
{{record.number}}
</ng-template>
</p-column>
<!--New row to go here-->
</p-dataTable>
</div>
I Just want a row like this:
<tr>
<td>
<button (click)="savePhone()" class="btn btn-sm btn-success">
<i class="fa fa-floppy-o"></i>
</button>
</td>
<td>
<select name="Type" [(ngModel)]="newPhone.type" class="form-control">
<option value="0">{{l("Mobile")}}</option>
<option value="1">{{l("Home")}}</option>
<option value="2">{{l("Business")}}</option>
</select>
</td>
<td><input type="text" name="number" [(ngModel)]="newPhone.number" class="form-control" /></td>
</tr>
First find the length of the data what you are getting like below?
public dataLength:number;
this.myService.getAllResult('query)
.subscribe((response: any[]) => {
this.data = response
this.dataLength = this.data.length;
}
Now in p-template body take another row and use *ngIf and check the dataLength is greater than or equal to current Index:
<ng-template pTemplate="body" let-i="rowIndex" let-data>
<tr>
<td>{{i + 1}}</td>
<td>{{data.name}}</td>
<td>{{data.email}}</td>
</tr>
<tr *ngIf="i >= (dataLength -1)">Print your data</tr>
</ng-template>
I think there should be something like $last and $first index in primeNg as we have in angular for *ngFor.
If we find the last index in Prime Ng. Then no need to take the another dataLength. But Above solution should work for you.
Related
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;
I've got this editable field. I need it to save the new data and store it in the database.
HTML:
<ng-container *ngIf="groupedVolumes">
<ng-container *ngFor="let model of groupKeys() | slice:-3" >
<tr>
<th class="model">{{ carValues(model)[0].model }}</th>
<ng-container *ngFor="let value of carValues(model)">
<td contenteditable='true' class="data">
{{ value.scheduledVolume }}
</td>
</ng-container>
</tr>
</ng-container>
</ng-container>
The HTML data shows the editable field.
This is the button to save with:
<div class="row">
<div class="col-auto">
<button
type="submit"
class="btn btn-success mx-1"
onclick="saveData()">Save
</button>
</div>
</div>
This is not a good approach.
Use input (probably type="text") for input using the angular form api, then you can store the new values in database on completion.
I am trying to write a dropdown list for selecting country, is possible to add flag of country next to the country name??
<div class="chosen-input-group col-sm-10 ">
<select id="country_type" chosen data-placeholder="-- 國家 --" disable-search="false"
ng-options="country_.country_id as country_.name for country_ in vm.country_data"
ng-model="vm.item.country_id">
<option value=""> -- 國家 --</option>
</select>
</div>
You could use ng-repeat on the option tag and then style the option with the image as you want it
<select >
<option ng-repeat="country_ in vm.country_data"
value="country_.country_id"
style="background-image:url({{country_.name}}.png);">
{{ country_.name }}
</option>
</select>
It is not possible using a native select with options.
Have a look to https://github.com/angular-ui/ui-select
Soruce : Angular select with images
I added the icon directly to the ng-template tag, and it works:
<ng-select [clearable]="false" [searchable]="false" [items]="items" bindLabel="libelle" [(ngModel)]="selectedItem">
<ng-template ng-label-tmp let-item="item">
<i class="fa fa-eye"></i>
<b> {{item.libelle}}</b>
</ng-template>
<ng-template ng-option-tmp let-item="item" let-index="index">
<i class="fa fa-eye"></i>
<b> {{item.libelle}}</b>
</ng-template>
</ng-select>
I am new in Angular 4.x. I have a html table. Every row has a checkbox and a checkbox. I want to bind checkbox with button, so that when the checkbox is checked, the button is enabled, and when the checkbox in unchecked, the button is disabled:
here is a sample of code, but it is not working :
<tbody>
<tr *ngFor="let item of mf.data; let i = index;">
<td><input type="checkbox" value="" [checked]="item.checked"></td>
<td>{{i}}</td>
<td>{{item.name}}</td>
<td>{{item.email}}</td>
<td>{{item.age}}</td>
<td>{{item.city | uppercase}}</td>
<td><button type="button" class="btn btn-success" [disabled]="item.checked">start</button></td>
</tr>
</tbody>
Can you help me to make this work please ?
use [(ngModel)]. Because check will not enable the two-way binding. It just handles One-way changing
<td><input type="checkbox" value="" [(ngModel)]="item.checked"></td>
make the button disable not equal to item check, like this [disabled]="!item.checked"
<td><button type="button" class="btn btn-success" [disabled]="!item.checked">start</button></td>
Currently your checkbox only binds one way. To apply changes by clicking it, add the following to your input tag:
(change)="item.checked = !item.checked"
You don't need checked directive. Just binding the model is enough.
<tbody>
<tr *ngFor="let item of mf.data; let i = index;">
<td><input type="checkbox" [(ngModel)]="item.checked"></td>
<td>{{i}}</td>
<td>{{item.name}}</td>
<td>{{item.email}}</td>
<td>{{item.age}}</td>
<td>{{item.city | uppercase}}</td>
<td><button type="button" class="btn btn-success" [disabled]="!item.checked">start</button></td>
<pre>{{item.checked}}</pre>
</tr>
</tbody>
<tbody>
<tr *ngFor="let item of mf.data; let i = index;">
<td><input type="checkbox" value="" [checked]="item.checked"></td>
<td>{{i}}</td>
<td>{{item.name}}</td>
<td>{{item.email}}</td>
<td>{{item.age}}</td>
<td>{{item.city | uppercase}}</td>
<td><button type="button" class="btn btn-success" [disabled]="item.checked">start</button></td>
</tr>
</tbody>
Use this:
<td>
<div class="togglebutton">
<label>
<input type="checkbox" [checked]="record.status" (change)="changeStatus(record.id,$event)">
<span class="toggle"></span>
</label>
</div>
</td>
I have table of emails with <TR>'s being repeated with v-repeat followed with a single <TR> for displaying an empty form for adding a new email.
Problem is that the <TR> with empty form always appears as the FIRST row BEFORE the list of existing email <TR>s.
Is there a way to force the <TR> with the empty email form to render AFTER the list of email <TR>'s?
<section v-show="emails" v-cloak>
<table id="email-list">
<tbody>
<tr
v-repeat="email: emails"
class="email"
v-class="
editing : this == editedEmail
"
>
<td>
<input
class = "edit"
type = "text"
v-model = "email.address | addressValidator"
v-on = "
click : editAddress(this, $index),
blur : doneEdit(this, $index),
keyup : doneEdit(this, $index) | key 'enter',
keyup : cancelEdit(this, $index) | key 'esc'
"
>
</td>
<td>
<a
class="btn btn-xs btn-danger"
style="cursor:pointer;"
v-on="click: removeEmail(this, $index)"
>
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
</tbody>
<tfoot>
<tr
class="email"
v-class="
editing : this == editedEmail
"
>
<form
id="add-new-form"
v-on="submit:addNew"
>
<input
id="0"
autofocus
autocomplete="off"
placeholder="New Email Address"
v-model="newEmail.address | addressValidator"
>
<button
type="submit"
v-show="newEmail.address && validation.address"
class="btn btn-xs btn-success"
style="cursor:pointer;"
>
<i class="fa fa-plus"></i>
</button>
</form>
</tr>
</tfoot>
</table>
</section>
A form can’t be a direct child of a table row. Put it outside of the table as it is not part of the datas.
#Samuel De Backer pointed out the problem in his comment to my question.