Friday 23 March 2018

Dynamic model with add and delete operations - Angular

Angular 2(+)Dynamic modelAdd

In this article I am going to discuss about setting a dynamic model for ngFor (looped) items. Our html contains a text box and a select box, user can add more similar blocks by clicking on add button. Each blocks are associated with a delete button so that user can delete as well. After filling all fields user can click on save button where we will be getting the complete list of the changes. Check below image.

As we need to loop the items to show in the UI, set dynamic model for values. So that we can collect all the details added by user. It is very simple, check the component code first.

Component


import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-general',
  templateUrl: './general.component.html',
  styleUrls: ['./general.component.scss']
})
export class GeneralComponent {

  userDetails: any = [];

  constructor() { }

  ngOnInit() {
    this.additemToUserDetails();
  }
  additemToUserDetails() {
    let _userItem = {
      name: '',
      gender: '',
      id: new Date().getTime()
    }
    this.userDetails.push(_userItem);
  }
  deleteItem(user) {
    for (var i = 0; i < this.userDetails.length; i++) {
      if (user.id == this.userDetails[i].id) {
        this.userDetails.splice(i, 1);
      }
    }
  }
  saveModel() {
    console.log(this.userDetails);
  }
}

Here we have created a simple object and pushing to userDetails while clicking on add button. I am calling the method under ngOnInit as well to keep one item default in the list. However you can modify the code according to your needs. Check below html code more info.

Html


<div class="dynamicModel">

  <div *ngFor="let user of userDetails">

    <input [(ngModel)]="user.name" type="text" value="" placeholder="name"> Gender:

    <select [(ngModel)]="user.gender">
      <option value="True">Male</option>
      <option value="False">Female</option>
    </select>

    <button class="btn btn-primary btn-sm" *ngIf="userDetails.length>1" (click)="deleteItem(user)">Delete</button>

  </div>

  <button class="btn btn-primary btn-sm" (click)="additemToUserDetails()">Add +</button>

</div>

<div>
  <button class="btn btn-primary" (click)="saveModel()">Save</button>
</div>

You can update the look and feel using css. Clicking on delete button we are splicing the selected item from our main object and the same will be updated in the html as well. I have used current time as id for this demo. This line *ngIf="userDetails.length > 1" is for hiding delete button if only one item is available. On click of saveModel we can collect all the user entered values. You can build your validation logic on top of this, for example disabling submit button until all the mandatory fields are filled etc.

I have added a console.log() for the output. Click on save button and see your browser console for the result.

You can fetch select box values also from the component instead of hardcoding in the html. For example check below code.

Component


 genderList: any = [
    { name: 'Male', value: 'male' },
    { name: 'Female', value: 'female' }
  ]

Html


<select [(ngModel)]="user.gender">
   <option *ngFor="let g of genderList" [value]="g.value">{{g.name}}</option>
</select>

There is no other changes required. Click on save you can see the user entered values in the console. Similarly you can add more things and no need to worry about fetching the user entered values, Angular will take care that.

In this article we have discussed about setting a dynamic model and also about fetching those results. By using angular you can easily add or delete items from a list of blocks or from a grid.

Angular 2(+)Dynamic modelAdd

Related Info

1. Get Url parameter using Angular 2/5.

2. Share data between non related components - Angular 2/5.

1 comment :