1

A student wants to register one class or more than one class. As the class list is dynamic, I have used ngFor to display in a table format with checkbox at then end to select the class. But, no idea how to get value when a student checkbox to select class.

I have tried to use the select option but that didn't go through well.

<div>
<table align="center" >
  <tr class="heading" >
    <th style="padding: 5px;">Code</th>
    <th style="padding: 5px;">Name</th>
    <th style="padding: 5px;">Capacity</th>
    <th style="padding: 5px;">Remaining</th>
    <th style="padding: 5px;">Location</th>
    <th style="padding: 5px;">Instructor</th>
    <th style="padding: 5px;">Register?</th>
  </tr>
  <tr *ngFor="let item of classItem">
    <td style="border-right-style: dashed;">{{ item.Code }}</td>
    <td>{{ item.Name }}</td>
    <td>{{ item.Capacity }}</td>
    <td>{{ item.Remaining }}</td>
    <td>{{ item.Location }}</td>
    <td>{{ item.Instructor }}</td>
    <td>
      <ion-checkbox style="text-align: center;" (onchange)="checkboxChange()" [(ngModel)]="checkItem"></ion-checkbox>
    </td>

  </tr>
</table>

I expect when student register for any class then, capacity of class will be reduced by one and update to firebase database.

Mr.Shah
  • 61
  • 7
  • Check this out [User does not have permission to access this object . Firebase storage](https://stackoverflow.com/questions/38671444/user-does-not-have-permission-to-access-this-object-firebase-storage-android) – Madara Uchiha Nov 06 '19 at 09:16

3 Answers3

1

Since you have multiple checkboxes, you need an array to keep track of these checkboxes.

Component:

checkboxes = [];

Initialize all checkboxes with false to keep them unchecked at the beginning.

ngOnInit() {
  // This array will be the same length as the iterable object used in *ngFor.
  this.checkboxes = new Array(this.classItem.length).fill(false);
}

Template:

In the template, bind each checkbox to their respective value.

<tr *ngFor="let item of classItem; let i = index">
  ...
  <ion-checkbox style="text-align: center;" (onchange)="checkboxChange(i)"
    [(ngModel)]="checkboxes[i]"></ion-checkbox>
  ...
</tr>

When a checkbox is checked or unchecked, modify available capacity of the class.

checkboxChange(i) {
  if (this.checkboxes[i]) {
    this.capacity++;
  } else {
    this.capacity--;
  }
}
Nikhil
  • 6,493
  • 10
  • 31
  • 68
  • I have capacity variable in another page, how would I link to this page? – Mr.Shah Nov 06 '19 at 08:06
  • @RaviShankarShah - If you have the variable in a parent component, then you can update it by sending the data using event emitters. See this [answer](https://stackoverflow.com/a/57813231/2924577) for more info. If the components are not related, then look at communicating between components using a service. If you are having trouble doing this, ask a new question since it isn't related to this checkbox question. – Nikhil Nov 06 '19 at 13:36
1

Here is my solution to your problem. Firstly I added component ts file with mock data in checkItem array of type ClassDescription with ClassDescription interface. Note that I have used normal html input checkbox instead , I just verified on ionic documentation and it will work same as below reference of Ionic Checkbox

<table align="center" >
  <tr class="heading" >
    <th style="padding: 5px;">Code</th>
    <th style="padding: 5px;">Name</th>
    <th style="padding: 5px;">Capacity</th>
    <th style="padding: 5px;">Remaining</th>
    <th style="padding: 5px;">Location</th>
    <th style="padding: 5px;">Instructor</th>
    <th style="padding: 5px;">Register?</th>
  </tr>
  <tr *ngFor="let item of classItem">
    <td style="border-right-style: dashed;">{{ item.code }}</td>
    <td>{{ item.name }}</td>
    <td>{{ item.capacity }}</td>
    <td>{{ item.remaining }}</td>
    <td>{{ item.location }}</td>
    <td>{{ item.instructor }}</td>
    <td>
      <input type="checkbox"  [(ngModel)]="item.register"  (change)="onChecked(item)" 
[disabled]="(item.remaining === 0) && item.register == !true"> 

      <br>
    </td>


  </tr>

  </table>

My Stackblitz solution is here Stackblitz solution. Next you can add your logic for firebase inside onChecked function.

    import { Component } from '@angular/core';

    interface ClassDescription {
    code : string; 
    name : string ; 
    capacity: string ; 
    remaining : number ; 
    location : string ; 
    instructor : string; 
    register: boolean; 
    }
   @Component({
   selector: 'my-app',
   templateUrl: './app.component.html',
   styleUrls: [ './app.component.css' ]
   })
  export class AppComponent  {

     onChecked(item) {
     if(item.register)
       {
         item.remaining = item.remaining - 1 ;
       }
      else{
          item.remaining = item.remaining + 1 ;
        }  

     }

    classItem: ClassDescription[]= [
   {
      'code' : '101',
      'name' : 'Micro services',
      'capacity': '30',
      'remaining' : 5 ,
      'location' : 'Engineering dept',
      'instructor' : 'Dr. Neha',
      'register': false 
    },
    {
       'code' : '102',
      'name' : 'Computer Science',
      'capacity': '30',
      'remaining' : 0 ,
      'location' : 'Mcarthy hall',
      'instructor' : 'Dr. Rob',
       'register': false 
     },
    {
      'code' : '103',
     'name' : 'Programming fundamental',
      'capacity': '30',
     'remaining' : 5 ,
     'location' : 'Harvard hall',
     'instructor' : 'Dr. Steven',
      'register': false 
     }
     ];


    }
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
0
<table align="center" >
  <tr class="heading" >
    <th style="padding: 5px;">Code</th>
    <th style="padding: 5px;">Name</th>
    <th style="padding: 5px;">Capacity</th>
    <th style="padding: 5px;">Remaining</th>
    <th style="padding: 5px;">Location</th>
    <th style="padding: 5px;">Instructor</th>
    <th style="padding: 5px;">Register?</th>
  </tr>
  <tr *ngFor="let item of classItem;let i = index">
    <td style="border-right-style: dashed;">{{ item.code }}</td>
    <td>{{ item.name }}</td>
    <td>{{ item.capacity }}</td>
    <td>{{ item.remaining }}</td>
    <td>{{ item.location }}</td>
    <td>{{ item.instructor }}</td>
    <td>
      <ion-checkbox style="text-align: center;" (ionChange)="checkboxStateChanged(i)" [checked]="item.checked"></ion-checkbox>
    </td>


  </tr>

  </table>

in your ts :

classSelectedIndexes : number[] = []; //storing the selected item indexes just in case  

checkboxStateChanged(index : number){
 this.item[i].checked= !this.item[i].checked;
 if(this.item[i].checked){
  //do something if true
 }
  else{
  //do something if false
 }
}

It is expected to have a checked property in your classItem all initialized to false

i.e your classItem should be of type :

interface ClassType {
code : string; 
name : string ; 
capacity: string ; 
remaining : number ; 
location : string ; 
instructor : string; 
checked: boolean; 
}
CruelEngine
  • 2,701
  • 4
  • 23
  • 44