AngularJS – Adding/Removing Table Rows Dynamically (Updated)

angularjs
This article is updated to include concepts and related take-away code related to adding/removing the table rows on different Angular versions including Angular 2.* and later version (Angular 4.*, Angular 5.*) and, also, AngularJS 1.* releases.

Add/Delete Table Row (Angular 2.*, Angular 4.*, Angular 5.*)

The code given below demonstrate the following:

  • Display a table consisting of one or more rows with each row representing teachers’ detail
  • Add a teacher using a Model Window
  • Delete a teacher

This is how the screenshot of the table looks like:

Figure 1. Angular - Add Delete Table Rows

angular add delete table row dynamically

The code is designed as following:

  • Teacher Class: There is a teacher class (teacher.ts) which representing teachers’ detail. The code given below represents the same:
    export class Teacher {
      constructor (
          public id: number,
          public name: string,
          public subject: string,
          public address: string,
          public mobile: number
      ) {  }
    }
    
  • Teacher Component: There is a component (named as app.component.ts) representing the teacher table’s view; This component consists of logic in form of functions (addTeacher, deleteTeacher) for adding, deleting the teacher. In real world scenario, the component should be named appropriately representing the context/functionality. For example, teacher.component.ts
    import { Component } from '@angular/core';
      import {Teacher} from './teacher';
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent {
        title = 'Tutosphere';
        id = 1;
        teacher = new Teacher(0, '', '', '', 0);
        TEACHERS = [
          new Teacher(this.id, 'Adarsh', 'Physics', 'Wilmington', 8764562341)
        ];
        addTeacher() {
          this.id += 1;
          const teacherEntry = new Teacher(this.id, this.teacher.name, this.teacher.subject, this.teacher.address, this.teacher.mobile);
          this.TEACHERS.push(teacherEntry);
          this.resetTeacher();
        }
        deleteTeacher(id: number) {
          for (let i = this.TEACHERS.length - 1; i >= 0; i--) {
            if (this.TEACHERS[i].id === id) {
              this.TEACHERS.splice(i, 1);
            }
          }
        }
        resetTeacher() {
          this.teacher.name = '';
          this.teacher.subject = '';
          this.teacher.address = '';
          this.teacher.mobile = 0;
        }
      }
    
  • Teacher View: There is a view, app.component.html which is used to represent UI. In the real world scenario, this can be named as teacher.component.html.
    </pre>
    <pre><div class="container">
    <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4">
      <a class="navbar-brand" href="#">{{title}}</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto flex-row">
    <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              Links
            </a>
    <div class="dropdown-menu" aria-labelledby="navbarDropdown">
              <a class="dropdown-item" href="#">Link 1</a>
    <div class="dropdown-divider"></div>
              <a class="dropdown-item" href="#">Link 2</a>
            </div>
          </li>
    </ul>
    
    <ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
    <li class="nav-item">
            <a class="nav-link" href="#">Signup</a>
          </li>
    <li class="nav-item">
            <a class="nav-link" href="#">Login</a>
          </li>
        </ul>
      </div>
    </nav>
      <form #tableForm="ngForm">
      <button type="button" class="btn btn-primary"  data-toggle="modal" data-target="#addTeacher">Add Teacher</button>
      <input type="text" id="searchTextId" [(ngModel)]="searchText" name="searchText" placeholder="Search By Name">
      </form>
        <div style="margin-top: 10px">
        <table class="table">
          <thead  class="thead-light">
          <th>Full Name</th>
          <th>Subject</th>
          <th>Address</th>
          <th>Mobile No.</th>
          <th>Actions</th>
          </thead>
          <tbody>
          <tr *ngFor="let teacher of (TEACHERS | searchByName: searchText)">
            <td>{{teacher.name}}</td>
            <td>{{teacher.subject}}</td>
            <td>{{teacher.address}}</td>
            <td>{{teacher.mobile}}</td>
            <td><button type="button" class="btn btn-secondary btn-sm" (click)="deleteTeacher(teacher.id)">Delete</button></td>
          </tr>
          </tbody>
        </table>
      </div>
      <!-- Modal -->
      <div class="modal fade" id="addTeacher" tabindex="-1" role="dialog" aria-labelledby="addTeacherTitle" aria-hidden="true">
        <div class="modal-dialog" role="document">
          <form  (ngSubmit)="addTeacher()" #addTeacherForm="ngForm">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="addTeacherTitle">Add Teacher Details</h5>
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                  <label for="teacherName">Teacher Name</label>
                  <input type="text" class="form-control" id="teacherName" [(ngModel)]="teacher.name"  name="teacherName" placeholder="Enter Name">
                </div>
                <div class="form-group">
                  <label for="subject">Subject</label>
                  <input type="text" class="form-control" id="subject"  [(ngModel)]="teacher.subject"  name="subject" placeholder="Enter Subject">
                </div>
              <div class="form-group">
                <label for="address">Address</label>
                <input type="text" class="form-control" id="address"  [(ngModel)]="teacher.address"  name="address" placeholder="Enter Address">
              </div>
                <div class="form-group">
                  <label for="mobile">Mobile No.</label>
                  <input type="number" class="form-control" id="mobile" [(ngModel)]="teacher.mobile" name="mobile" placeholder="Enter Mobile Number">
                </div>
            </div>
            <div class="modal-footer">
              <button type="submit" class="btn btn-primary">Submit</button>
              <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            </div>
          </div>
          </form>
        </div>
      </div>
    </div></pre>
    <pre>
  • Teacher Module: There is a module, namely, app.module.ts which includes code for importing the component. The following is the code:
    import { BrowserModule } from '@angular/platform-browser';
      import { NgModule } from '@angular/core';
      import { FormsModule } from '@angular/forms';
      import { AppComponent } from './app.component';
      @NgModule({
        declarations: [
          AppComponent
        ],
        imports: [
          BrowserModule, FormsModule
        ],
        providers: [],
        bootstrap: [AppComponent]
      })
      export class AppModule { }
    

Add a Table Row

For adding a table row, the following needs to be paid attention to:

  • The form which captures the data input from the end user. Note some of the following in the code given below:
    • The syntax [(ngModel)] is used to bind the form inputs with the model.
    • Note the name attribute is added to input element. Defining a name attribute is a requirement when using [(ngModel)] in combination with a form.
    • The syntax #addTeacherForm=”ngForm” is used to assign a reference, addTeacherForm, to the ngFormdirective. Note that the NgForm directive supplements the form element with additional features. It holds the controls you created for the elements with an ngModel directive and name attribute, and monitors their properties, including their validity.
    • Note the handler (ngSubmit)=”addTeacher()” on form element. This results in invocation of addTeacher on form submission.
    </pre>
    <pre><div class="modal fade" id="addTeacher" tabindex="-1" role="dialog" aria-labelledby="addTeacherTitle" aria-hidden="true">
        <div class="modal-dialog" role="document">
          <form  (ngSubmit)="addTeacher()" #addTeacherForm="ngForm">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="addTeacherTitle">Add Teacher Details</h5>
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                  <label for="teacherName">Teacher Name</label>
                  <input type="text" class="form-control" id="teacherName" [(ngModel)]="teacher.name"  name="teacherName" placeholder="Enter Name">
                </div>
                <div class="form-group">
                  <label for="subject">Subject</label>
                  <input type="text" class="form-control" id="subject"  [(ngModel)]="teacher.subject"  name="subject" placeholder="Enter Subject">
                </div>
              <div class="form-group">
                <label for="address">Address</label>
                <input type="text" class="form-control" id="address"  [(ngModel)]="teacher.address"  name="address" placeholder="Enter Address">
              </div>
                <div class="form-group">
                  <label for="mobile">Mobile No.</label>
                  <input type="number" class="form-control" id="mobile" [(ngModel)]="teacher.mobile" name="mobile" placeholder="Enter Mobile Number">
                </div>
            </div>
            <div class="modal-footer">
              <button type="submit" class="btn btn-primary">Submit</button>
              <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            </div>
          </div>
          </form>
        </div>
      </div>
    </div></pre>
    <pre>
  • The code given below represents addTeacher function which gets invoked as a result of form submission shown in the above point. The method takes care of adding the form entries as a teacher model to array of teachers (TEACHERS).
    addTeacher() {
      this.id += 1;
      const teacherEntry = new Teacher(this.id, this.teacher.name, this.teacher.subject, this.teacher.address, this.teacher.mobile);
      this.TEACHERS.push(teacherEntry);
      this.resetTeacher();
    }
    

Delete a Table Row

  • Pay attention to the click handler which is defined on Delete Button shown in diagram shown above (figure 1).
    <button type="button" class="btn btn-secondary btn-sm" (click)="deleteTeacher(teacher.id)">Delete</button>
    
  • The code given below represents the method which actually delete the appropriate row entry.
    deleteTeacher(id: number) {
      for (let i = this.TEACHERS.length - 1; i &amp;amp;amp;gt;= 0; i--) {
          if (this.TEACHERS[i].id === id) {
              this.TEACHERS.splice(i, 1);
          }
      }
    }
    

References

Check the details in relation to above on following pages:

Add/Delete Table Row (AngularJS 1.*)

Adding a Table Row Dynamically

If the rows are created using JSON data (companies in the example below), following code adds a row to the existing table. The addRow is a method invoked by the form submission.

<script>
var helloApp = angular.module("helloApp", []);
helloApp.controller("CompanyCtrl", function($scope) {

$scope.companies = [
{ 'name':'Infosys Technologies',
'employees': 125000,
'headoffice': 'Bangalore'},
{ 'name':'Cognizant Technologies',
'employees': 100000,
'headoffice': 'Bangalore'},
];

$scope.addRow = function(){
$scope.companies.push({ 'name':$scope.name, 'employees': $scope.employees, 'headoffice':$scope.headoffice });
$scope.name='';
$scope.employees='';
$scope.headoffice='';
};
)};
</script>

Removing a Table Row Dynamically

The directive ng-click is used in each row. The ng-click invokes the method removeRow whose code is represented below.

<script>
      var helloApp = angular.module("helloApp", []);
      helloApp.controller("CompanyCtrl", function($scope) {
      $scope.companies = [
          { 'name':'Infosys Technologies',
            'employees': 125000,
             'headoffice': 'Bangalore'},
             { 'name':'Cognizant Technologies',
                'employees': 100000,
               'headoffice': 'Bangalore'},
          ];
          $scope.removeRow = function(name){
          var index = -1;
          var comArr = eval( $scope.companies );
          for( var i = 0; i &lt; comArr.length; i++ ) {
                if( comArr[i].name === name ) {
                    index = i;
                    break;
                 }
          }
          if( index === -1 ) {
               alert( "Something gone wrong" );
          }
          $scope.companies.splice( index, 1 );
       };
)};
</script>
<!-- Code within body displaying table rows using ng-repeat repeater directive. Note the ng-click directive -->
<table class="table">
 <tr>
 <th>Name
 </th>
 <th>Employees
 </th>
 <th>Head Office
 </th>
 <th>Action
 </th>
</tr>
<tr ng-repeat="company in companies">
 <td>
 </td>
 <td>
 </td>
 <td>
 </td>
 <td>
 <input type="button" value="Remove" class="btn btn-primary" ng-click="removeRow(company.name)"/>
 </td>
</tr>
</table></pre>
<pre>

The above code along with demo and the details could also be found on the following pages:



Ajitesh Kumar
Follow me

Ajitesh Kumar

I have been recently working in the area of Data analytics including Data Science and Machine Learning / Deep Learning. I am also passionate about different technologies including programming languages such as Java/JEE, Javascript, Python, R, Julia, etc, and technologies such as Blockchain, mobile computing, cloud-native technologies, application security, cloud computing platforms, big data, etc. For latest updates and blogs, follow us on Twitter. I would love to connect with you on Linkedin. Check out my latest book titled as First Principles Thinking: Building winning products using first principles thinking. Check out my other blog, Revive-n-Thrive.com
Posted in Javascript, Web. Tagged with , , .

3 Responses

Leave a Reply

Your email address will not be published. Required fields are marked *