Thursday, October 10, 2019

Create dynamic row and custom multiselect dropdowns using angular 7


Introduction

In this article we will learn how we create dynamic row and custom multiselect dropdowns using angular 7. 

How it will work ?

Angular multiselect dropdown component for web applications. Easy to integrate and use. It can be bind to any custom data source.Multi dropdown checkbox is already available in angular called ng-multiselect-dropdown but here we are not using that one but we are creating our own plus we will give the functionality to select only two values in checkbox it means when we try to select more than two values it will remove first value and select third like this we are going to create in this article.

Prerequisite
  • Basic knowledge of Angular
  • Visual Studio Code must be installed
  • Angular CLI must be installed
  • Node JS must be installed
Step 1 

Lets create a angular project using following npm command

1.   ng new multiSelectCheckbox   

Step 2

Open the newly created project in visual studio code and install bootstrap in this project

1.   npm install bootstrap --save  

Now open styles.css file and add Bootstrap file reference.To add reference in styles.css file add this line.

1.   @import '~bootstrap/dist/css/bootstrap.min.css';  

Step 3 Now lets create a new component by using following command.

1.   ng g c home   

Step 4 Now create a new class ,to create class using the following command .

1.   ng generate class blankRow  

Now open the class and add the follow code.

1.   export class BlankRow {  
2.       RollNo:number;  
3.       Name:string;  
4.       Medium:any;  
5.       Class:any;  
6.       Section:any;  
7.       Books:any=[];  
8.       SelectedBooks:any=[];  
9.       Subject=[];  
10.     SelectedSubject=[];  
11. }  

Step 5 Now open home.component.ts file and add the following code in this file.

1.   import { Component, OnInit } from '@angular/core';  
2.   import { BlankRow } from '../models/blankRow';  
3.     
4.   @Component({  
5.   selector: 'app-home',  
6.   templateUrl: './home.component.html',  
7.   styleUrls: ['./home.component.css']  
8.   })  
9.   export class HomeComponent implements OnInit {  
10.   
11. blankRowArray: Array<BlankRow> = [];  
12.   
13. blankRowData = new BlankRow();  
14. hideMultiSelectDropdownAll: boolean[] = [];  
15. hideMultiSelectDropdown: boolean[] = [];  
16. hideMultiSelectedSubjectDropdown: boolean[] = [];  
17. hideMultiSelectedSubjectDropdownAll: boolean[] = [];  
18. tempData = [];  
19. savedSubjects =[];  
20. Books = [];  
21. Subject = [];  
22.   
23. constructor() { }  
24.   
25. ngOnInit() {  
26. this.Subject = [  
27. { value: "English", IsChecked: false },  
28. { value: "History", IsChecked: false },  
29. { value: "Geography", IsChecked: false },  
30. { value: "Hindi", IsChecked: false },  
31. { value: "Marathi", IsChecked: false },  
32. { value: "Civics", IsChecked: false },  
33. { value: "Science", IsChecked: false },  
34. { value: "Mathematics", IsChecked: false }  
35. ];  
36. this.Books = [  
37. { value: "CBSE Class 10 English Literature Reader Book", IsChecked: false },  
38. { value: "CBSE Class 10 English Book", IsChecked: false },  
39. { value: "CBSE Class 10th Maths Book", IsChecked: false },  
40. { value: "CBSE Class 10th Hindi Book", IsChecked: false },  
41. { value: "CBSE Class 10 Science Book", IsChecked: false },  
42. { value: "Class 10 CBSE Geography Book", IsChecked: false },  
43. { value: "Class 10th Economics Book", IsChecked: false },  
44. { value: "CBSE Class 10 Sanskrit Book", IsChecked: false }  
45. ];  
46. }  
47. addBlankRow() {  
48.   
49. const blankRowData = new BlankRow();  
50. blankRowData.RollNo = 0,  
51. blankRowData.Name = '',  
52. blankRowData.Medium = 0,  
53. blankRowData.Class = 0,  
54. blankRowData.Section = 0,  
55. blankRowData.Books = [],  
56. blankRowData.Subject = [],  
57.   
58. blankRowData.SelectedSubject = [{ IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false },  
59. { IsChecked: false }, { IsChecked: false }, { IsChecked: false }],  
60.   
61. blankRowData.SelectedBooks = [{ IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false },  
62. { IsChecked: false }, { IsChecked: false }, { IsChecked: false }],  
63.   
64.   
65. this.blankRowArray.push(blankRowData)  
66.   
67. }  
68.   
69. openMultiSelectDD(i) {  
70. for (var x = 0; x < this.blankRowArray.length; x++) {  
71. this.hideMultiSelectDropdownAll[x] = false;  
72. this.hideMultiSelectedSubjectDropdownAll[x] = false;  
73. this.hideMultiSelectedSubjectDropdown[x] = false;  
74. }  
75.   
76. this.hideMultiSelectDropdownAll[i] = true;  
77. this.hideMultiSelectDropdown[i] = !this.hideMultiSelectDropdown[i];  
78.   
79. }  
80.   
81. openMultiSelectDDForSubject(i) {  
82.   
83. for (var x = 0; x < this.blankRowArray.length; x++) {  
84. this.hideMultiSelectedSubjectDropdownAll[x] = false;  
85. this.hideMultiSelectDropdownAll[x] = false;  
86. this.hideMultiSelectDropdown[x] = false;  
87. }  
88.   
89. this.hideMultiSelectedSubjectDropdownAll[i] = true;  
90. this.hideMultiSelectedSubjectDropdown[i] = !this.hideMultiSelectedSubjectDropdown[i];  
91. }  
92.   
93. //MultiSelect DropDown For Books  
94. booksChecked(list: any, i, x, isChecked: boolean) {  
95. let selectedBooks = list.value;  
96. if (isChecked) {  
97. this.blankRowArray[i].Books.push(selectedBooks);  
98. this.blankRowArray[i].SelectedBooks[x].IsChecked = true;  
99.   
100.          else {  
101.          this.blankRowArray[i].Books = this.blankRowArray[i].Books.filter(obj => obj !== selectedBooks);  
102.          this.blankRowArray[i].SelectedBooks[x].IsChecked = false;  
103.          }  
104.          }  
105.            
106.          //On Subject Checked  
107.          onSubjectChecked(list: any, i, x, isChecked: boolean) {  
108.          let selectedSubject = list.value;  
109.          if (this.blankRowArray[i].Subject.length < 2) {  
110.            
111.          if (isChecked) {  
112.          if (this.blankRowArray[i].Subject.length == 0) {  
113.          this.tempData = [];  
114.          }  
115.          if (this.tempData.length < 2) {  
116.          this.tempData.push(x);  
117.          }  
118.          if(this.tempData.length == 2){  
119.          let saveSub =this.tempData.join(',');  
120.          this.savedSubjects[i] = saveSub;  
121.          console.log(this.savedSubjects[i]);  
122.          }  
123.          this.blankRowArray[i].Subject.push(selectedSubject);  
124.          this.blankRowArray[i].SelectedSubject[x].IsChecked = true;  
125.          this.Subject[x].IsChecked = true;  
126.            
127.          else {  
128.          this.tempData.filter(obj => obj !== x);  
129.          this.blankRowArray[i].Subject = this.blankRowArray[i].Subject.filter(obj => obj !== selectedSubject)  
130.          this.blankRowArray[i].SelectedSubject[x].IsChecked = false;  
131.          }  
132.          else {  
133.          if (isChecked) {  
134.            
135.          this.blankRowArray[i].Subject[0] = this.blankRowArray[i].Subject[1];  
136.          this.blankRowArray[i].SelectedSubject[x].IsChecked = true;  
137.            
138.          let saveSub0=this.savedSubjects[i].split(',')[0]?this.savedSubjects[i].split(',')[0]:this.tempData[0];  
139.          let saveSub1=this.savedSubjects[i].split(',')[1]?this.savedSubjects[i].split(',')[1]:this.tempData[1];  
140.            
141.          var temp = saveSub0;  
142.          this.tempData[0] = saveSub1;  
143.          this.tempData[1] = x;  
144.          this.blankRowArray[i].SelectedSubject[temp].IsChecked = false;  
145.            
146.          this.Subject[x].IsChecked = true;  
147.          this.blankRowArray[i].Subject[1] = selectedSubject;  
148.          this.savedSubjects[i] =this.tempData.join(',');  
149.          else {  
150.          var temp = this.tempData.find(a => a == x);  
151.            
152.          this.tempData = [];  
153.          this.tempData[0] = temp;  
154.            
155.          this.blankRowArray[i].Subject = this.blankRowArray[i].Subject.filter(obj => obj !== selectedSubject)  
156.          this.blankRowArray[i].SelectedSubject[x].IsChecked = false;  
157.            
158.          }  
159.          }  
160.            
161.          }  
162.          deleteRow(index) {  
163.          this.blankRowArray.splice(index, 1);  
164.          }  
165.            
166.          }  


1.   deleteRow(index) {    
2.      this.blankRowArray.splice(index, 1);    
3.    }    

deleteRow method is use to delete created row.

1.   addBlankRow() {  
2.     
3.   const blankRowData = new BlankRow();  
4.   blankRowData.RollNo = 0,  
5.   blankRowData.Name = '',  
6.   blankRowData.Medium = 0,  
7.   blankRowData.Class = 0,  
8.   blankRowData.Section = 0,  
9.   blankRowData.Books = [],  
10. blankRowData.Subject = [],  
11.   
12. blankRowData.SelectedSubject = [{ IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false },  
13. { IsChecked: false }, { IsChecked: false }, { IsChecked: false }],  
14.   
15. blankRowData.SelectedBooks = [{ IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false }, { IsChecked: false },  
16. { IsChecked: false }, { IsChecked: false }, { IsChecked: false }],  
17.   
18.   
19. this.blankRowArray.push(blankRowData)  
20.   
21. }  

addBlankRow method is ues to add new blank row on click of the Add new Row button.

1.   openMultiSelectDD(i) {  
2.   for (var x = 0; x < this.blankRowArray.length; x++) {  
3.   this.hideMultiSelectDropdownAll[x] = false;  
4.   this.hideMultiSelectedSubjectDropdownAll[x] = false;  
5.   this.hideMultiSelectedSubjectDropdown[x] = false;  
6.   }  
7.     
8.   this.hideMultiSelectDropdownAll[i] = true;  
9.   this.hideMultiSelectDropdown[i] = !this.hideMultiSelectDropdown[i];  
10.   
11. }  

 openMultiSelectDD method is used to open dropdown (related to books) when it gets clicked. I used "for" loop here to close all particular dropdown and open only selected one.


1.   openMultiSelectDDForSubject(i) {  
2.     
3.   for (var x = 0; x < this.blankRowArray.length; x++) {  
4.   this.hideMultiSelectedSubjectDropdownAll[x] = false;  
5.   this.hideMultiSelectDropdownAll[x] = false;  
6.   this.hideMultiSelectDropdown[x] = false;  
7.   }  
8.     
9.   this.hideMultiSelectedSubjectDropdownAll[i] = true;  
10. this.hideMultiSelectedSubjectDropdown[i] = !this.hideMultiSelectedSubjectDropdown[i];  
11. }  

 openMultiSelectDDForSubject method is used to open dropdown (related to subject) when it gets clicked. I used "for" loop here to close all particular dropdown and open only selected one.


1.   //MultiSelect DropDown For Books  
2.   booksChecked(list: any, i, x, isChecked: boolean) {  
3.   let selectedBooks = list.value;  
4.   if (isChecked) {  
5.   this.blankRowArray[i].Books.push(selectedBooks);  
6.   this.blankRowArray[i].SelectedBooks[x].IsChecked = true;  
7.     
8.   else {  
9.   this.blankRowArray[i].Books = this.blankRowArray[i].Books.filter(obj => obj !== selectedBooks);  
10. this.blankRowArray[i].SelectedBooks[x].IsChecked = false;  
11. }  
12. }  

 In above code i have used some paremeters here which i will explain one by one.
  • list :It Stores the selected value from the checkbox. 
  • i :It stores the current blank row index value.
  • x :It stores the current checkbox index value.
  • isChecked :It Stores the boolean value of the checkbox (for checked 'true' and for unchecked 'false' ).

 If Checked then it will push into an array and assign SelectedBooks.Ischecked as true.It can cheked or unchecked all checkbox.


1.   //On Subject Checked  
2.   onSubjectChecked(list: any, i, x, isChecked: boolean) {  
3.   let selectedSubject = list.value;  
4.   if (this.blankRowArray[i].Subject.length < 2) {  
5.     
6.   if (isChecked) {  
7.   if (this.blankRowArray[i].Subject.length == 0) {  
8.   this.tempData = [];  
9.   }  
10. if (this.tempData.length < 2) {  
11. this.tempData.push(x);  
12. }  
13. if(this.tempData.length == 2){  
14. let saveSub =this.tempData.join(',');  
15. this.savedSubjects[i] = saveSub;  
16. console.log(this.savedSubjects[i]);  
17. }  
18. this.blankRowArray[i].Subject.push(selectedSubject);  
19. this.blankRowArray[i].SelectedSubject[x].IsChecked = true;  
20. this.Subject[x].IsChecked = true;  
21.   
22. else {  
23. this.tempData.filter(obj => obj !== x);  
24. this.blankRowArray[i].Subject = this.blankRowArray[i].Subject.filter(obj => obj !== selectedSubject)  
25. this.blankRowArray[i].SelectedSubject[x].IsChecked = false;  
26. }  
27. else {  
28. if (isChecked) {  
29.   
30. this.blankRowArray[i].Subject[0] = this.blankRowArray[i].Subject[1];  
31. this.blankRowArray[i].SelectedSubject[x].IsChecked = true;  
32.   
33. let saveSub0=this.savedSubjects[i].split(',')[0]?this.savedSubjects[i].split(',')[0]:this.tempData[0];  
34. let saveSub1=this.savedSubjects[i].split(',')[1]?this.savedSubjects[i].split(',')[1]:this.tempData[1];  
35.   
36. var temp = saveSub0;  
37. this.tempData[0] = saveSub1;  
38. this.tempData[1] = x;  
39. this.blankRowArray[i].SelectedSubject[temp].IsChecked = false;  
40.   
41. this.Subject[x].IsChecked = true;  
42. this.blankRowArray[i].Subject[1] = selectedSubject;  
43. this.savedSubjects[i] =this.tempData.join(',');  
44. else {  
45. var temp = this.tempData.find(a => a == x);  
46.   
47. this.tempData = [];  
48. this.tempData[0] = temp;  
49.   
50. this.blankRowArray[i].Subject = this.blankRowArray[i].Subject.filter(obj => obj !== selectedSubject)  
51. this.blankRowArray[i].SelectedSubject[x].IsChecked = false;  
52.   
53. }  
54. }  
55.   
56. }  

In this method we can only check  maximum two values if we select for third value then first value replaces with third and so on.  

Step 6 Now open home.component.html file and add the following code in this file.

1.   <div>  
2.     <button style="margin: 10px;" class="btn btn-primary" (click)="addBlankRow()">Add Blank Row</button>  
3.   </div>  
4.   <div class="col-12 col-md-12">  
5.     <div class="card">  
6.       <div class="card-body">  
7.         <div class="table-responsive cnstr-record">  
8.           <table class="table table-bordered">  
9.             <thead>  
10.             <tr>  
11.               <th width="30">Roll No</th>  
12.               <th width="100">Student Name</th>  
13.               <th width="50">Medium</th>  
14.               <th width="70">Class</th>  
15.               <th width="50">Section</th>  
16.               <th width="80">Books</th>  
17.               <th width="60">Subject</th>  
18.               <th width="50">Delete Row</th>  
19.             </tr>  
20.           </thead>  
21.           <tbody>  
22.             <tr *ngFor="let row of blankRowArray; let i = index">  
23.               <td>  
24.                 <input type="text" class="form-control wp-30" [(ngModel)]="blankRowArray[i].RollNo"  
25.                   [ngModelOptions]="{standalone: true}">  
26.               </td>  
27.               <td>  
28.                 <input type="text" class="form-control wp-30" [(ngModel)]="blankRowArray[i].Name"  
29.                   [ngModelOptions]="{standalone: true}">  
30.               </td>  
31.               <td>  
32.                 <select [(ngModel)]="blankRowArray[i].Medium" [ngModelOptions]="{standalone: true}"  
33.                   class="form-control wp-70">  
34.                   <option [ngValue]="0" disabled selected>--Choose--  
35.                   </option>  
36.                   <option [value]="1">Emglish</option>  
37.                   <option [value]="2">Hindi</option>  
38.                   <option [value]="2">Marathi</option>  
39.                 </select>  
40.               </td>  
41.               <td>  
42.                 <select name="crown" [(ngModel)]="blankRowArray[i].Class" (ngModelChange)="setPonticFlagTrue($event,i)"  
43.                   class="form-control wp-80">  
44.                   <option [ngValue]="0" disabled selected>--Choose--</option>  
45.                   <option value="1">Fifth</option>  
46.                   <option value="2">Sixth</option>  
47.                   <option value="3">Seventh</option>  
48.                   <option value="4">Eight</option>  
49.                   <option value="3">Ninth</option>  
50.                   <option value="4">Tenth</option>  
51.                 </select>  
52.               </td>  
53.               <td>  
54.                 <select [(ngModel)]="blankRowArray[i].Section" (ngModelChange)="setPonticType($event,i)"  
55.                   [ngModelOptions]="{standalone: true}" class="form-control wp-80">  
56.                   <option [ngValue]="0" disabled selected>--Choose--  
57.                   </option>  
58.                   <option value="1">Section A</option>  
59.                   <option value="2">Section B</option>  
60.                   <option value="3">Section C</option>  
61.                   <option value="4">Section D</option>  
62.                   <option value="5">Section E</option>  
63.                 </select>  
64.               </td>  
65.               <td>  
66.                 <input class="form-control wp-70" type="text" autocomplete="off" name="{{blankRowArray[i].Books}}"  
67.                   (click)="openMultiSelectDD(i)" title="{{blankRowArray[i].Books}}"  
68.                   placeholder="{{blankRowArray[i].Books}}">  
69.   
70.                 <div style="width: 329px!important;"  
71.                   *ngIf="hideMultiSelectDropdown[i]==true && hideMultiSelectDropdownAll[i]==true" class="tooltip">  
72.                   <div class="body">  
73.                     <div *ngFor="let bookList of Books;let x =index" class="body">  
74.                       <input name="bookListName" autocomplete="off" type="checkbox"  
75.                         [checked]="this.blankRowArray[i].SelectedBooks[x].IsChecked==true"  
76.                         (change)="booksChecked(bookList, i,x,$event.target.checked)">   
77.                       <label>{{bookList.value}}</label><br>  
78.                     </div>  
79.                   </div>  
80.                 </div>  
81.               </td>  
82.               <td>  
83.                 <input type="text" autocomplete="off" name="{{blankRowArray[i].Subject}}"  
84.                   (click)="openMultiSelectDDForSubject(i)" title="{{blankRowArray[i].Subject}}"  
85.                   placeholder="{{blankRowArray[i].Subject}}" class="form-control wp-70">  
86.                 <div style="width: 162px!important;"  
87.                   *ngIf="hideMultiSelectedSubjectDropdown[i]==true && hideMultiSelectedSubjectDropdownAll[i]==true"  
88.                   #insideElement class="tooltip">  
89.                   <div class="body">  
90.                     <div *ngFor="let subjectList of Subject;let x =index" class="body">  
91.                       <input name="subject" autocomplete="none" type="checkbox"  
92.                         [checked]="this.blankRowArray[i].SelectedSubject[x].IsChecked==true"  
93.                         (change)="onSubjectChecked(subjectList, i,x,$event.target.checked)">   
94.                       <label>{{subjectList.value}}</label><br>  
95.                     </div>  
96.                   </div>  
97.                 </div>  
98.               </td>  
99.               <td align="center">  
100.                          <button (click)="deleteRow(i)" class="btn btn-danger">Delete Row</button>  
101.                        </td>  
102.                      </tr>  
103.                    </tbody>  
104.                  </table>  
105.                </div>  
106.              </div>  
107.            </div>  
108.          </div>  

Step 7 Now open home.component.css file and add the following code in this file
  
1.   .tooltip {  
2.       position: absolute;  
3.       z-index: 3000;  
4.       border: 1px solid #b7b086;  
5.       background-color: white;  
6.       color: #000!important;  
7.       padding: 5px 15px 5px 10px;  
8.       opacity: 1;  
9.       width: 350px;  
10. }  


Step 8 Now open app.module.ts file and add the following code in this file.
1.   import { BrowserModule } from '@angular/platform-browser';  
2.   import { NgModule } from '@angular/core';  
3.   import { FormsModule } from '@angular/forms';  
4.   import { AppComponent } from './app.component';  
5.   import { RouterModule } from '@angular/router';  
6.   import { AppRoutingModule } from './app-routing.module';  
7.   import { HomeComponent } from './home/home.component';  
8.   @NgModule({  
9.     declarations: [  
10.     AppComponent,  
11.     HomeComponent,  
12.   ],  
13.   imports: [  
14.     BrowserModule,  
15.     RouterModule,  
16.     FormsModule,  
17.     AppRoutingModule  
18.   ],  
19.   providers: [  
20.   ],  
21.   bootstrap: [AppComponent]  
22. })  
23. export class AppModule { }  
 Step 9 Now run the project by using 'npm start' or 'ng serve' command.



Click on Add blank row button it create a new row.


Step 10 Now click on subject textbox.




  


  

SummaryIn this article i discussed how we create dymaic row and custom multiselect dropdowns in Angular 8 Application 

Please give your valuable feedback/comments/questions about this article. Please let me know if you liked and understood this article and how I could improve it.