I want the behavior of my form to be like this, when I click on the modify button, I want this line only to be modified, but when I click on it, all three lines are active
How to do that?
pictures :
edit
save
app.component.html :
<table mat-table [dataSource]="dataSources[i]" class="mat-elevation-z0">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Nom</th>
<td mat-cell *matCellDef="let element" matTooltip="{{ element.value }}" matTooltipClass="tooltip" matTooltipPosition="right">{{ element.name | summary: 20 }}</td>
</ng-container>
<ng-container matColumnDef="value">
<th mat-header-cell *matHeaderCellDef class="align-right">Valeur</th>
<td mat-cell *matCellDef="let element" matTooltip="{{ element.value }}" matTooltipPosition="right" matTooltipClass="tooltip" class="align-right">
<input type="text" [disabled]='toggleButton' placeholder="{{ element.value }}" value="{{ element.value }}" >
<button mat-icon-button title="Modifier" (click)="enable()" *ngIf="toggleButton"><mat-icon>editer</mat-icon></button>
<button mat-icon-button title="Enregistrer" *ngIf="!toggleButton"><mat-icon>done</mat-icon></button>
<button mat-icon-button title="Annuler" (click)="disable()" *ngIf="!toggleButton"><mat-icon>clear</mat-icon></button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="['name', 'value']"></tr>
<tr mat-row *matRowDef="let row; columns: ['name', 'value']"></tr>
</table>
app.component.ts :
public toggleButton: boolean = true;
enable() {
this.toggleButton = false;
}
disable(){
this.toggleButton = true;
}
You can send in the dataSource a property toggleButton, i.e. element.toggleButton, then:
<td mat-cell *matCellDef="let element" matTooltip="{{ element.value }}" matTooltipPosition="right" matTooltipClass="tooltip" class="align-right">
<input type="text" [disabled]="element.toggleButton" placeholder="{{ element.value }}" value="{{ element.value }}" >
<button mat-icon-button title="Modifier" (click)="element.toggleButton = !element.toggleButton" *ngIf="element.toggleButton"><mat-icon>editer</mat-icon></button>
<button mat-icon-button title="Enregistrer" *ngIf="!element.toggleButton"><mat-icon>done</mat-icon></button>
<button mat-icon-button title="Annuler" (click)="element.toggleButton = !element.toggleButton" *ngIf="!element.toggleButton"><mat-icon>clear</mat-icon></button>
</td>
public toggleInputs = {};
enable(index: number) {
this.toggleInputs[index] = true;
}
disable(index: number){
this.toggleInputs[index] = false;
}
<td mat-cell *matCellDef="let element; let i = index" matTooltip="{{ element.value }}" matTooltipPosition="right" matTooltipClass="tooltip" class="align-right">
<input type="text" [disabled]="!toggleInputs[i]" placeholder="{{ element.value }}" value="{{ element.value }}" />
Related
I have a PrimeNG datatable as follows, with frozen columns initially loaded:
When i try to hide one of the frozen columns, the table does not realign itself to accomodate the remaining frozen columns in the blank space but rather leaves an empty space as follows:
The more frozen columns i try to hide ,the blank space expands.
Another anomaly observed is when i try to resize my screen dimensions, the attribute responsiveLayout="scroll" does not work and my table breaks as follows:
Here below is the HTML Code:
<div class="col-12">
<p-table #dt
[columns]="selectionService.selectedScrollableColumns"
[loading]="loading"
[value]="selectionService?.listOfRetrievedDepositValuations"
(onHeaderCheckboxToggle)="onClickHeaderCheckbox()"
(onRowSelect)="onRowSelect()" (onRowUnselect)="onRowUnselect()"
(onFilter)="updateGroupingTotalsAfterFilters($event)"
responsiveLayout="scroll" scrollDirection="both"
[paginator]="true" [rows]="25" [scrollable]="true"
[(selection)]="selectionService.selectedDepositValuation"
[resizableColumns]="false" stateStorage="session" stateKey="{{userLoggedInWithTenant}}-valuation-selection"
dataKey="uid"
styleClass="sticky-datatable p-datatable-striped">
<ng-template pTemplate="header" let-columns *transloco="let t">
<tr>
<ng-container *ngFor="let col of columns; let colIndex = index">
<th *ngIf="col.field === 'checkbox'" [style]="getColumnWidth(col.type)"
pResizableColumn [id]="'headerCheckbox'+colIndex" pFrozenColumn [frozen]="col.isFrozenColumn">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th *ngIf="col.field !== 'checkbox'" pResizableColumn pFrozenColumn [frozen]="col.isFrozenColumn" [pSortableColumn]="col.field" style="text-align:center ;" [style]="getColumnWidth(col.type)"
[pTooltip]="col.header" [id]="'header'+colIndex" [ngClass]="col?.class">
<div class="text-overflow-ellipsis p-fluid">
{{col.header}}
<p-sortIcon [field]="col.field"></p-sortIcon>
</div>
</th>
</ng-container>
</tr>
<tr>
<ng-container *ngFor="let col of columns; let colIndex = index">
<th *ngIf="col.field === 'checkbox'" [style]="getColumnWidth(col.type)"
pFrozenColumn [frozen]="col.isFrozenColumn">
</th>
<th class="filter-header-height" [ngSwitch]="col.type" *ngIf="col.field!=='checkbox'" style="text-align:center;" pFrozenColumn [frozen]="col?.isFrozenColumn" [style]="getColumnWidth(col.type)"
[id]="'filterHeader' + colIndex">
<div class="p-fluid">
<p-columnFilter type="text" [field]="col.field" [matchMode]="'contains'" *ngSwitchCase="'deposit'"></p-columnFilter>
<p-columnFilter *ngSwitchCase="'code'" [field]="col.field" matchMode="in" [showMenu]="false">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-multiSelect
[options]="getProperty(col.options)" [placeholder]="t('common.choose')"
[emptyFilterMessage]="t('common.empty-message')" [ngModel]="dt.filters[col.field]?.value"
(onChange)="filter($event.value, col.field, 'in')" [panelStyle]="{width:'12em'}" appendTo="body">
</p-multiSelect>
</ng-template>
</p-columnFilter>
<p-columnFilter *ngSwitchCase="'currency'" [field]="col.field" matchMode="in" [showMenu]="false">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-multiSelect
[options]="getProperty(col.options)" [placeholder]="t('common.choose')"
[emptyFilterMessage]="t('common.empty-message')" [ngModel]="dt.filters[col.field]?.value"
(onChange)="filter($event.value, col.field, 'in')" [panelStyle]="{width:'12em'}" appendTo="body">
</p-multiSelect>
</ng-template>
</p-columnFilter>
<ng-bdi-number-filter [width]="100" [decimalPlaces]="2" *ngSwitchCase="'number'"
[value]="dt.filters[col.field.toString()] ? dt.filters[col.field.toString()].value : null"
(onChange)="dt.filter($event, col.field.toString(), 'number_range')">
</ng-bdi-number-filter>
<ng-bdi-number-filter [width]="100" [decimalPlaces]="0" *ngSwitchCase="'value'"
[value]="dt.filters[col.field] ? dt.filters[col.field].value : null"
(onChange)="dt.filter($event, col.field, 'number_range')">
</ng-bdi-number-filter>
</div>
</th>
</ng-container>
</tr>
</ng-template>
<ng-template pTemplate="body" let-deposit let-columns="columns">
<tr [pSelectableRow]="deposit">
<ng-container *ngFor="let col of columns">
<td *ngIf="col.field==='checkbox'" pFrozenColumn [frozen]="col?.isFrozenColumn" [style]="getColumnWidth(col.type)" >
<p-tableCheckbox [value]="deposit"></p-tableCheckbox>
</td>
<td *ngIf="col.field!=='checkbox'" pFrozenColumn [frozen]="col?.isFrozenColumn" [style]="getColumnWidth(col.type)" [ngClass]="col.scrollable === true ? 'non-frozen' : null">
<div *ngIf="col.type==='deposit'" class="text-left p-fluid">
{{resolveRowData(deposit, col.field)}} </div>
<div *ngIf="col.type==='code'" class="text-center p-fluid">
{{resolveRowData(deposit, col.field)}} </div>
<div *ngIf="col.type==='currency'" class="text-center p-fluid">
<app-currency-flag [isoCode]="resolveRowData(deposit, col.field)"></app-currency-flag>
</div>
<div *ngIf="col.type==='number'" [style.color]="getColor(deposit[col.field])"
class="text-right p-fluid">
<em [ngClass]="determinePerformance(resolveRowData(deposit,col.field))"
*ngIf="col.field==='performance'"></em>
{{resolveRowData(deposit, col.field) | number : '1.2-2'}}
</div>
<div *ngIf="col.type==='value'" [style.color]="getColor(deposit[col.field])"
class="text-right p-fluid"> {{resolveRowData(deposit, col.field) | number : '1.0-0'}}
</div>
</td>
</ng-container>
</tr>
</ng-template>
<ng-template pTemplate="footer" let-columns>
<tr>
<ng-container *ngFor="let col of columns">
<td [style]="getColumnWidth(col.type)" pFrozenColumn [frozen]="col?.isFrozenColumn">
<span *ngIf="col.field==='depositReferenceCurrencyNegativeValue'"
class="text-right">
{{totalNegativeReferenceCurrencyValue | number : '1.0-0'}} </span>
<span *ngIf="col.field==='depositReferenceCurrencyPositiveValue' "
class="text-right">
{{totalPositiveReferenceCurrencyValue | number : '1.0-0'}} </span>
<span *ngIf="col.field==='depositReferenceCurrencyValue' "
class="text-right">
{{totalReferenceCurrencyValue | number : '1.0-0'}} </span>
<span class="text-right"
*ngIf="col.field!=='depositReferenceCurrencyValue' &&
col.field!=='depositReferenceCurrencyPositiveValue' && col.field!=='depositReferenceCurrencyNegativeValue' ">
</span>
</td>
</ng-container>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage" >
<tr>
<td [attr.colspan]="selectionService.frozenColumns.length" *transloco="let t">
{{ t('common.table.empty') }}
</td>
</tr>
</ng-template>
<ng-template pTemplate="summary">
<tr>
<td colspan="3" >
<strong style="float:left">#: {{dt?.totalRecords}}</strong>
</td>
</tr>
</ng-template>
</p-table>
</div>
Below is the code to filter the selected columns:
displayAndHideColumns(event: any): void {
this.selectionService.selectedColumns.forEach(x=>{
if(this.selectionService.frozenColumns.find(col => x.field===col.field)){
x.isFrozenColumn=true;
}
else{
x.isFrozenColumn=false;
}
})
const selectedScrollableColumns = [...this.selectionService.selectedColumns];
this.selectionService.selectedScrollableColumns = [];
this.selectionService.selectedColumns.forEach(x=>{
this.selectionService.selectedScrollableColumns.push(x);
})
this.selectionService.selectedScrollableColumns.sort((a, b) => a.order - b.order);
this.loadFreezeTableHeaders();
}
Any suggestions to the above two issues?
I have a form this form takes up 1/3 of the screen adjacent to the left , so ı want to this form display with full width (occupy the entire screen from left to right.). I searched on google and tried some methods which are width : 100% , fxFlexFill, (fxLayout="column" fxLayoutAlign=" stretch"), fxFlexs .Maybe i used them wrong . I couldn't do it in any way.
calander page:
<form [formGroup]="userForm" (ngSubmit)="sendRequest()">
<div fxLayout="row" style="background-color: white">
<div fxLayout="column" fxFlex="10">
<mat-form-field appearance="fill">
<mat-label>Date</mat-label>
<input
matInput
#pick
[matDatepicker]="picker"
(dateInput)="OnDateChange(pick)"
[min]="todayDate"
[max]="maxDate"
readonly
/>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker touchUi #picker [startAt]="todayDate"></mat-datepicker>
</mat-form-field>
</div>
<div fxLayout="column" fxFlex="15"></div>
<div fxLayout="column" fxFlex="30">
<mat-form-field appearance="fill">
<mat-label>Name</mat-label>
<input matInput formControlName="firstName" />
</mat-form-field>
</div>
<div fxLayout="column" fxFlex="15"></div>
<div fxLayout="column" fxFlex="30">
<mat-form-field appearance="fill">
<mat-label>Phone Number</mat-label>
<input matInput formControlName="phone" />
</mat-form-field>
</div>
<div></div>
</div>
<div fxLayout="row">
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- hour Column -->
<ng-container matColumnDef="hour">
<th mat-header-cell *matHeaderCellDef>hour(90 min)</th>
<td mat-cell *matCellDef="let element">{{ element.hour }}</td>
</ng-container>
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>No.</th>
<td mat-cell *matCellDef="let element">{{ element.position }}</td>
</ng-container>
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row">
<mat-checkbox
(click)="$event.stopPropagation()"
*ngIf="row.statu == 'Open'"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)"
>
</mat-checkbox>
</td>
</ng-container>
<!-- statu Column -->
<ng-container matColumnDef="statu">
<th mat-header-cell *matHeaderCellDef>statu</th>
<td mat-cell *matCellDef="let element">{{ element.statu }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: displayedColumns"
(click)="selection.toggle(row)"
></tr>
</table>
</div>
<div>
<button mat-raised-button class="my-class" type="submit" color="accent">
Send
</button>
</div>
</form>
calander page css:
table {
width: 100%;
}
.example-form .mat-form-field + .mat-form-field {
margin-left: 8px;
}
.my-class{
margin-top: 10px;
width: 100%!important;
}
.mat-form-field-empty.mat-form-field-label {
color: green;
}
.mat-form-field-underline {
background-color: green;
}
What exactly should take up the whole screen? If you want the three input fields to stretch to the far right, you can change
<div fxLayout="row" style="background-color: white">
to
<div fxLayout="row" id="row" style="background-color: white; display: flex">
I think that could help you https://tburleson-layouts-demos.firebaseapp.com/#/docs
They said : "Using 'fxFill' to fill available width and height of parent container"
So ... you must have the size of the parent at 100%.
I currently have the Angular Material Table set up with data from a List.
I would like to populate this list with data from a JSON url.
I assume i would have to first parse the data in to the list, however i have tried numerous ways of doing this online and have had no joy. I have stripped my code down so that it has the current working table pulling infor from a hardcoded list.
Please can anyone advise on how i would do this.
App.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { MatToolbarModule } from '#angular/material/toolbar';
import { MatMenuModule } from '#angular/material/menu';
import { MatTableModule } from '#angular/material/table';
import { MatPaginatorModule } from '#angular/material/paginator';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
MatToolbarModule,
MatMenuModule,
MatTableModule,
MatPaginatorModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts:
import { AfterViewInit, Component, ViewChild } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { MatPaginator } from '#angular/material/paginator';
import { MatTableDataSource } from '#angular/material/table';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit{
title = 'UnitySLATable';
displayedColumns: string[] = ['groups', 'areas', 'applications', 'regions', 'as_of_dates'];
dataSource = new MatTableDataSource<SLAList>(SLAS);
#ViewChild(MatPaginator) paginator: MatPaginator;
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
}
export interface SLAList {
groups: string;
areas: string;
applications: string;
regions: string;
as_of_dates: string;
}
const SLAS: SLAList[] = [
{groups: 'test', areas: 'test', applications: 'test', regions: 'test', as_of_dates: 'test'},
];
app.component.html:
<body>
<mat-toolbar>
<span>Unity: Daily SLA Dashboard</span>
</mat-toolbar>
<mat-toolbar>
<button mat-flat-button [matMenuTriggerFor]="home">Home</button>
<mat-menu #home="matMenu">
<button mat-menu-item>Overview</button>
</mat-menu>
<button mat-flat-button [matMenuTriggerFor]="selfServ">Self Service</button>
<mat-menu #selfServ="matMenu">
<button mat-menu-item>SLA Management</button>
<button mat-menu-item>SLA Batch Update</button>
<button mat-menu-item>Permission Management</button>
<button mat-menu-item>Report Management</button>
<button mat-menu-item>View Management</button>
<button mat-menu-item>Group Attribute Editor</button>
</mat-menu>
<button mat-flat-button [matMenuTriggerFor]="legDash">Legacy Dashboards</button>
<mat-menu #legDash="matMenu">
<button mat-menu-item>Barclays Wealth</button>
<button mat-menu-item>Commodities</button>
<button mat-menu-item>Credit</button>
<button mat-menu-item>Operations and Cross Product Technology (OCPT)</button>
<button mat-menu-item>Enterprise Solutions</button>
<button mat-menu-item>Equities</button>
<button mat-menu-item>Fixed Income</button>
<button mat-menu-item>Reform</button>
<button mat-menu-item>Retail/Corporate Banking</button>
<button mat-menu-item>FX</button>
<button mat-menu-item>MIHBUS</button>
<button mat-menu-item>MIHBUS Impact Analysis</button>
<button mat-menu-item>Options & Structured Rates</button>
<button mat-menu-item>Prime Services</button>
<button mat-menu-item>Risk & Analytics</button>
<button mat-menu-item>Sales</button>
<button mat-menu-item>Securitised Products</button>
<button mat-menu-item>TWS</button>
</mat-menu>
<button mat-flat-button [matMenuTriggerFor]="download">Download</button>
<mat-menu #download="matMenu">
<button mat-menu-item>SLA Download</button>
<button mat-menu-item>Historical SLA Delivery</button>
<button mat-menu-item>Usage Report</button>
</mat-menu>
<button mat-flat-button [matMenuTriggerFor]="support">Support</button>
<mat-menu #support="matMenu">
<button mat-menu-item [matMenuTriggerFor]="documentation">Documentation</button>
<button mat-menu-item>Contacts</button>
</mat-menu>
<mat-menu #documentation="matMenu">
<button mat-menu-item>Batch Update Template</button>
<button mat-menu-item>SLA Template</button>
<button mat-menu-item>User Guide</button>
<button mat-menu-item>SLA Mass Upload/Download</button>
<button mat-menu-item>Wiki</button>
</mat-menu>
</mat-toolbar>
<table mat-table [dataSource]="dataSource">
<!-- Groups Column -->
<ng-container matColumnDef="groups">
<th mat-header-cell *matHeaderCellDef> Group </th>
<td mat-cell *matCellDef="let element"> {{element.groups}} </td>
</ng-container>
<!-- Areas Column -->
<ng-container matColumnDef="areas">
<th mat-header-cell *matHeaderCellDef> Area </th>
<td mat-cell *matCellDef="let element"> {{element.areas}} </td>
</ng-container>
<!-- Applications Column -->
<ng-container matColumnDef="applications">
<th mat-header-cell *matHeaderCellDef> Application </th>
<td mat-cell *matCellDef="let element"> {{element.applications}} </td>
</ng-container>
<!-- Regions Column -->
<ng-container matColumnDef="regions">
<th mat-header-cell *matHeaderCellDef> Region </th>
<td mat-cell *matCellDef="let element"> {{element.regions}} </td>
</ng-container>
<!-- AsOfDates Column -->
<ng-container matColumnDef="as_of_dates">
<th mat-header-cell *matHeaderCellDef> As of </th>
<td mat-cell *matCellDef="let element"> {{element.as_of_dates}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</body>
I hope you can help me.
So you actually just have to load your data and set it to the dataSource:
dataSource = new MatTableDataSource();
In ngOnInit call your api (to get the Json) and assign your data to the table:
this.dataService.getData().subscribe(data => {
this.dataSource.data = data ;
}, err => {
console.log(err);
});
}
Hope this solves your Problem.
i have mat-table in that i need to edit table. in table their is edit icon button ,if i clicked on edit button the first 3 columns should be editable and need to updated after editing.
edit should in same inline only not as mat-dialogue box . if we pressed on edit button name, age, phone-number should be editable . please help me in this
.html file
<div class="table-container mat-elevation-z8">
<mat-table mat-stretch-tabs [dataSource]="dataSource" matSort matSortActive="name" matSortDirection="asc" matSortDisableClear>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header > Name <mat-icon>filter_list</mat-icon> </mat-header-cell>
<mat-cell *matCellDef="let datalist " > {{datalist.name}} </mat-cell>
</ng-container>
<ng-container matColumnDef="description">
<mat-header-cell *matHeaderCellDef mat-sort-header > Age <mat-icon>filter_list</mat-icon> </mat-header-cell>
<mat-cell *matCellDef="let datalist" > {{datalist.age}} </mat-cell>
</ng-container>
<ng-container matColumnDef="databaseId">
<mat-header-cell *matHeaderCellDef mat-sort-header > <mat-icon>filter_list</mat-icon> </mat-header-cell>
<mat-cell *matCellDef="let datalist" > {{datalist.phonenumber}} </mat-cell>
</ng-container>
<ng-container matColumnDef="isActive">
<mat-header-cell *matHeaderCellDef > IsActive/InActive </mat-header-cell>
<mat-cell *matCellDef="let datalist" ><mat-slide-toggle color="primary" [checked]="datalist.isActive"></mat-slide-toggle></mat-cell>
</ng-container>
<ng-container matColumnDef="edit">
<mat-header-cell *matHeaderCellDef > Edit </mat-header-cell>
<mat-cell *matCellDef="let row">
<button mat-icon-button color="primary" >
<mat-icon>edit</mat-icon>
</button>
</mat-cell>
</ng-container>
<ng-container matColumnDef="delete">
<mat-header-cell *matHeaderCellDef > Delete </mat-header-cell>
<mat-cell *matCellDef="let datalist">
<button mat-icon-button color="primary" (click)="clickEvent(datalist,datalist.principalId)" [ngClass]="{'myClass':datalist.isClicked}">
<mat-icon>remove_circle</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns" ></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="onRowClicked(datalist)"></mat-row>
</mat-table>
</div>
<div>
<div class='left'>
<button class="mat-button menu-button">
<mat-icon color="primary"> add_to_photos </mat-icon>
Add Site
</button>
</div>
<div *ngIf="showButtons" class='right'>
<button mat-button type="button" class="close-button" (click)="cancel()">
<mat-icon>block</mat-icon>
CANCEL
</button>
<button (click)="delete()">Save</button>
</div>
</div>
This answer is not specific to mat-table, but try using PrimeNG for editable tables.
https://www.primefaces.org/primeng/#/table/edit
I am using Angular Material to design a basic form, but I am stuck with trying to create the functionality to add a dynamic row to the form. I.e., when I click an "add" button next to a row, it should add a new empty row.
I have tried numerous ways to make use of this example, but my data either repeats, or my list bombs out:
The form code:
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Price</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let field of fieldArray; let i = index">
<td>
<input [(ngModel)]="field.code" class="form-control" type="text" name="{{field.code}}" />
</td>
<td>
<input [(ngModel)]="field.name" class="form-control" type="text" name="{{field.name}}" />
</td>
<td>
<input [(ngModel)]="field.price" class="form-control" type="text" name="{{field.price}}" />
</td>
<td>
<button mat-raised-button class="form-button-spacing" color="warn" type="button" (click)="deleteFieldValue(i)">
Delete</button>
</td>
</tr>
<tr>
<td>
<input class="form-control" type="text" id="newAttributeCode" [(ngModel)]="newAttribute.code" name="newAttributeCode" />
</td>
<td>
<input class="form-control" type="text" id="newAttributeName" [(ngModel)]="newAttribute.name" name="newAttributeName" />
</td>
<td>
<input class="form-control" type="text" id="newAttributePrice" [(ngModel)]="newAttribute.price" name="newAttributePrice"
/>
</td>
<td>
<button mat-raised-button class="form-button-spacing" color="primary" type="button" (click)="addFieldValue()">
Add</button>
</td>
</tr>
</tbody>
</table>
The component code:
private fieldArray: Array<any> = [];
private newAttribute: any = {};
addFieldValue() {
this.fieldArray.push(this.newAttribute)
this.newAttribute = {};
}
deleteFieldValue(index) {
this.fieldArray.splice(index, 1);
}
How can I use my code below to create the same dynamically added rows:
<mat-expansion-panel [expanded]="step === 4" (opened)="setStep(4)" hideToggle="true">
<mat-expansion-panel-header>
<mat-panel-title>
<h4>Permits</h4>
</mat-panel-title>
<mat-panel-description>
<div></div>
<mat-icon>whatshot</mat-icon>
</mat-panel-description>
</mat-expansion-panel-header>
<div class="form">
<form class="permits-form" #permitsForm="ngForm" (ngSubmit)=onSubmit(permitsForm)>
<input type="hidden" name="AssetID" #AssetID="ngModel" [(ngModel)]="assetDataService.selectedAsset.AssetID">
<table class="full-width" cellspacing="0">
<tr>
<td>
<mat-form-field>
<mat-select placeholder="Permits" id="Permits" name="Permits" #Permits="ngModel" [(ngModel)]="assetDataService.selectedAsset.Permits"
required>
<mat-option *ngFor="let permit of permits" [value]="permit.name" required>
{{ permit.name }}
</mat-option>
</mat-select>
</mat-form-field>
</td>
<td>
<mat-form-field class="full-width">
<input matInput placeholder="Title of Permit" id="PermitTitle" name="PermitTitle" #PermitTitle="ngModel" [(ngModel)]="assetDataService.selectedAsset.PermitTitle"
required>
</mat-form-field>
</td>
<td>
<mat-form-field class="full-width">
<input matInput [matDatepicker]="PermitIssueDate" placeholder="Issue Date" id="PermitIssueDate" name="PermitIssueDate" #PermitIssueDate="ngModel"
[(ngModel)]="assetDataService.selectedAsset.PermitIssueDate" required>
<mat-datepicker-toggle matSuffix [for]="PermitIssueDate"></mat-datepicker-toggle>
<mat-datepicker touchUi="true" #PermitIssueDate></mat-datepicker>
</mat-form-field>
</td>
<td>
<mat-form-field class="full-width">
<input matInput [matDatepicker]="PermitEndDate" placeholder="Expiry Date" id="PermitEndDate" name="PermitEndDate" #PermitEndDate="ngModel"
[(ngModel)]="assetDataService.selectedAsset.PermitEndDate">
<mat-datepicker-toggle matSuffix [for]="PermitEndDate"></mat-datepicker-toggle>
<mat-datepicker touchUi="true" #PermitEndDate></mat-datepicker>
</mat-form-field>
</td>
<td>
<mat-icon>add_circle_outline</mat-icon>
</td>
</tr>
</table>
</form>
</div>
</mat-expansion-panel>
Thank you in advance!
You should use reactive forms and you can add form controls dynamically.
I was able to resolve my need by implementing the following:
First, in my view I created another mat-table to hold and loop my added lines, as well as fetch the data source and assigning it to the table:
<mat-table #table [dataSource]="getPermitDataSource()">
<!-- Id Column -->
<ng-container matColumnDef="permit">
<mat-header-cell *matHeaderCellDef> Permit </mat-header-cell>
<mat-cell *matCellDef="let permit"> {{permit.Permits}} </mat-cell>
</ng-container>
<!-- Make Column -->
<ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef> Permet Title </mat-header-cell>
<mat-cell *matCellDef="let permit"> {{permit.PermitTitle}} </mat-cell>
</ng-container>
<!-- Model Column -->
<ng-container matColumnDef="issue">
<mat-header-cell *matHeaderCellDef> Issue Date </mat-header-cell>
<mat-cell *matCellDef="let permit"> {{permit.PermitIssueDate | date}} </mat-cell>
</ng-container>
<!-- Regitration Column -->
<ng-container matColumnDef="expiry">
<mat-header-cell *matHeaderCellDef> Expiry Date </mat-header-cell>
<mat-cell *matCellDef="let permit"> {{permit.PermitEndDate | date}} </mat-cell>
</ng-container>
<!-- actions -->
<ng-container matColumnDef="actions">
<mat-header-cell *matHeaderCellDef>Edit | Delete</mat-header-cell>
<mat-action-row>
<mat-cell *matCellDef="let permit; let i=index;">
<button mat-icon-button class="form-button-spacing float-right" color="primary" (click)="onPermitDelete(permitsForm)">
<mat-icon aria-label="Delete">delete</mat-icon>
</button>
</mat-cell>
</mat-action-row>
</ng-container>
<!-- <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> -->
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
Secondly, I implemented the functionality in my component:
addNewPermitToArray(form: NgForm) {
this.permitArray.push(form.value);
this.getPermitDataSource();
form.reset();
}
getPermitDataSource() {
this.displayedColumns = this.displayedColumns = ['permit', 'title', 'issue', 'expiry', 'actions'];
return this.permitDataSource = new MatTableDataSource(this.permitArray);
}
I hope this will help someone else out there!