0

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.

userfields

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;
}

2
  • the best way is using a FormArray Commented Nov 12, 2019 at 14:08
  • @Eliseo I read angulars documentation on FormArray, however I am not sure how to implement it in my code. Would you mind helping me get started please ? Commented Nov 13, 2019 at 14:14

1 Answer 1

1

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!

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.