Reputation: 137
I have a form where I want the user to be able to generate OR remove a row of inputs if they so desire. What would be the best way to go about this? I believe I have to include this somwhere in my html file. *ngFor="let userline of users"
.
Here is what the form looks like currently. When the green "+" is pressed I would like a new row to populate. Likewise when the red "x" is clicked I want that row to get deleted.
form.component.html
<h3 align="center">Requested Dates</h3>
<!-- PrimeNG InputName -->
<div class="ui-g form-group">
<div class="ui-g-12 ui-md-1" id="test">
<button pButton type="button" id="deleteButton" icon="pi pi-times" class="ui-button-danger" (click)="onRemoveClicked()"></button>
</div>
<div class="ui-g-12 ui-md-2" id="test">
<!-- <label for="name">Name</label> -->
<input type="text" pInputText name="fname" class="form-control" [(ngModel)]="user.name" placeholder="Name" />
</div>
<div class="ui-g-12 ui-md-2">
<p-dropdown [options]="leave2" [(ngModel)]="selectedLeave2" (ngModelChange)='setLeave($event)' name="selectedLeave2" placeholder="Select Leave Code *" optionLabel="name"></p-dropdown>
</div>
<div class="ui-g-12 ui-md-2" id="test">
<p-calendar [showIcon]="true" [(ngModel)]="user.fromDate" name="fromDate" placeholder="From Date*" dateFormat="mm.dd.yy">
</p-calendar>
</div>
<div class="ui-g-12 ui-md-1" id="test">
<!-- <label for="fromTime">From Time</label> -->
<input type="text" pInputText name="lname" class="form-control" [(ngModel)]="user.fromTime" placeholder="From Time*" />
</div>
<div class="ui-g-12 ui-md-2" id="test">
<p-calendar [showIcon]="true" [(ngModel)]="user.toDate" name="toDate" placeholder="To Date*">
</p-calendar>
</div>
<div class="ui-g-12 ui-md-1" id="test">
<!-- <label for="toTime">To Time</label> -->
<input type="text" pInputText name="lname" class="form-control" [(ngModel)]="user.toTime" placeholder="To Time*" />
</div>
<br>
<div class="ui-g-12 ui-md-2" id="test">
<input type="submit" value="save" class="btn btn-success">
</div>
<button pButton type="button" id="addButton" icon="pi pi-plus" class="ui-button-success" (click)="onAddClicked()"></button>
<!-- </div> -->
</div>
</div>
</form>
form.component.ts
import { Component, OnInit } from '@angular/core';
import{User} from '../user';
import{Router} from '@angular/router';
import{UserService} from '../shared_service/user.service';
interface Supervisor {
name: string;
code: string;
}
interface Leave {
name: string;
code: string;
}
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
private user:User;
constructor(private _userService:UserService, private _rotuer: Router) {
this.supervisor2 = [
{ name: 'Samuel Chan', code: 'SC' },
{ name: 'Max Cardone', code: 'MC' },
{ name: 'Kylie Brooks', code: 'KB' },
];
this.leave2 = [
{ name: 'Personal Leave', code: 'PL' },
{ name: 'Sick Leave', code: 'SL' },
{ name: 'Vacation Leave', code: 'VL' },
{ name: 'Any Leave', code: 'AL' }
];
}
ngOnInit() {
this.user =this._userService.getter();
this.user = { id: null , name:'', fromDate: '', fromTime:'', toDate:'', toTime:'', selectedSupervisor2:'', selectedLeave2:'',};
//this._userService.getter();
}
supervisor2: Supervisor [];
selectedSupervisor2: Supervisor;
leave2: Leave [];
selectedLeave2: Leave;
// seefromDate(event) {
// console.log(event);
// }
// Method to Add row of dates on button click. Will go up to 7 fields
onAddClicked() {
if (this.dates.length < 8) {
this.dates.push({ leaveCode: "", fromDate: "", fromTime: "", toDate: "", toTime: "" })
;
}
}
// Method to remove dates on button click. Will always have one date field displayed
onRemoveClicked() {
if (this.users.length > 1) { this.users.pop(); }
}
setSupervisor(event){
if (event && event.name)
this.user.selectedSupervisor2 = (event.name);
}
setLeave(event){
if (event && event.name)
this.user.selectedLeave2 = (event.name);
}
processForm(){
console.log(this.user);
if(this.user.id==undefined){
this._userService.addItem(this.user).subscribe((user)=>{
console.log(user);
this._rotuer.navigate(['/table']);
},(error)=>{
console.log(error);
});
}else{
this._userService.saveOrUpdateItem(this.user).subscribe((user)=>{
console.log(user);
this._rotuer.navigate(['/table']);
},(error)=>{
console.log(error);
});
}
}
}
user.ts
export class User {
id:Number;
name:String;
fromDate: String;
fromTime:String;
toDate: String;
toTime:String;
selectedSupervisor2: String;
selectedLeave2: String;
}
Upvotes: 0
Views: 1308
Reputation: 57971
Quickly You define a FormArray in your .ts
formArray:FormArray=new FormArray([]);
You has a function that return a formGroup
getFormGroup(data: User) {
data = data || ({} as User);
return new FormGroup({
id: new FormControl(data.id),
name: new FormControl(data.name),
fromDate: new FormControl(data.fromDate),
fromTime: new FormControl(data.fromTime),
toDate: new FormControl(data.toDate),
toTime: new FormControl(data.toTime),
selectedSupervisor2: new FormControl(data.selectedSupervisor2),
selectedLeave2: new FormControl(data.selectedLeave2)
});
}
Then, in the own .html you can has a button like
<button (click)="formArray.push(getFormGroup(null))">Add</button>
And the .html
<div [formGroup]="formArray">
<div *ngFor="let group of formArray.controls;let i=index" [formGroup]="group">
<input formControlName="id">
<input formControlName="name">
<input formControlName="fromDate">
<input formControlName="fromTime">
<input formControlName="toDate">
<input formControlName="toTime">
<input formControlName="selectedSupervisor2">
<input formControlName="selectedLeave2">
<button (click)="formArray.removeAt(i)">Remove</button>
</div>
</div>
You can see in stackblitz
Don't forget import ReactiveFormModule!
Upvotes: 1