confusedntired
confusedntired

Reputation: 137

Function to add a new row of user inputs in Angular form

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

Upvotes: 0

Views: 1308

Answers (1)

Eliseo
Eliseo

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

Related Questions