newbie
newbie

Reputation: 105

Enable/Disable input field in mat-table when checkbox is selected (Angular 8)

I have multiple input fields on a mat table, and I want them to be enabled only when the row's checkbox is selected, or disabled when the row's checkbox is deselected. Currently, when I select one checkbox, it enables all the input fields. When I deselect the checkbox it disables all the input fields. Any help on this is appreciated. Thanks.

Selected checkbox enables all text fields

HTML

                            <form [formGroup]="batchRentalExtensionForm">
<div class="screen-container">
    <div class="card-wrapper">
        <div class="heading-content">{{constant.BATCHRENTALEXTENSION}}</div>
        <mat-divider class="mat-divider-content"></mat-divider>
        <div class="card-content" style="width:55%">
            <div>
                <div fxLayout="row" fxLayoutAlign="space-between none" fxFlex="50">
                    <mat-form-field>
                        <mat-label>{{constant.LOCATION}}</mat-label>
                        <mat-select disableRipple>
                            <mat-option value="1">Home Office</mat-option>
                            <mat-option value="2">Call Center</mat-option>
                        </mat-select>
                    </mat-form-field>
                </div>
                <div fxLayout="row" fxLayoutAlign="space-between none" fxFlex="50">
                    <mat-form-field>
                        <mat-select disableRipple>
                            <mat-option value="1">All</mat-option>
                        </mat-select>
                    </mat-form-field>
                </div>
            </div>
            <div class="mat-elevation-z8 batchRentalExtensionFormTable">
                <div>
                    <table mat-table [dataSource]="dataSource" matSort>
                        <ng-container matColumnDef="select">
                            <th mat-header-cell *matHeaderCellDef>
                                <mat-checkbox (change)="$event ? masterToggle() : null"
                                    [checked]="selection.hasValue() && isAllSelected()"
                                    [indeterminate]="selection.hasValue() && !isAllSelected()">
                                </mat-checkbox>
                            </th>
                            <td mat-cell *matCellDef="let row">
                                <mat-checkbox (click)="$event.stopPropagation()"
                                    (change)="$event ? selection.toggle(row) : null"
                                    [checked]="selection.isSelected(row)">
                                </mat-checkbox>
                            </td>
                        </ng-container>
                        <ng-container matColumnDef="position">
                            <th mat-header-cell *matHeaderCellDef mat-sort-header> Client No. </th>
                            <td mat-cell *matCellDef="let element"> {{element.position}} </td>
                        </ng-container>
                        <ng-container matColumnDef="claimNo">
                            <th mat-header-cell *matHeaderCellDef mat-sort-header> Claim No.</th>
                            <td mat-cell *matCellDef="let element"> {{element.claimNo}} </td>
                        </ng-container>
                        <ng-container matColumnDef="rentersName">
                            <th mat-header-cell *matHeaderCellDef mat-sort-header> Renter's Name </th>
                            <td mat-cell *matCellDef="let element"> {{element.rentersName}} </td>
                        </ng-container>
                        <ng-container matColumnDef="lor">
                            <th mat-header-cell *matHeaderCellDef mat-sort-header> LOR </th>
                            <td mat-cell *matCellDef="let element"> {{element.lor}} </td>
                        </ng-container>
                        <ng-container matColumnDef="state">
                            <th mat-header-cell *matHeaderCellDef mat-sort-header> State </th>
                            <td mat-cell *matCellDef="let element"> {{element.state}} </td>
                        </ng-container>
                        <ng-container matColumnDef="authDate">
                            <th mat-header-cell *matHeaderCellDef mat-sort-header> Auth Date </th>
                            <td mat-cell *matCellDef="let element"> {{element.authDate}} </td>
                        </ng-container>
                        <ng-container matColumnDef="addDays">
                            <th mat-header-cell *matHeaderCellDef> Add Days </th>
                            <td mat-cell *matCellDef="let element"> <input type="number"
                                    [disabled]="isAddDaysEnabled" placeholder="0"> </td>
                        </ng-container>
                        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
                        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
                    </table>
                </div>

                <mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
            </div>
            <div fxLayout="row" style="margin-top:60px">
                <button type="button" class="button btn-secondary btn-sm">{{constant.EXTENDRENTAL}}</button>
            </div>
        </div>
    </div>
</div>

TS

export class BatchRentalExtensionHomeComponent implements OnInit {
    
      batchRentalExtensionForm: FormGroup;
      @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
      batchRentalExtensionTable: batchRentalExtensionObj[] = [
        { position: '1', claimNo: '4234234', rentersName: 'fsgdfg', lor: '21', state: 'CA', authDate: '01/19/2021', addDays: '0' },
        { position: '2', claimNo: '3242344', rentersName: 'uiyui', lor: '21', state: 'CA', authDate: '01/19/2021', addDays: '0' }, 
        { position: '3', claimNo: '67567567', rentersName: 'tyrtryt', lor: '21', state: 'CA', authDate: '01/19/2021', addDays: '0' },
        { position: '4', claimNo: '234234', rentersName: 'fhfghfgh', lor: '21', state: 'CA', authDate: '01/19/2021', addDays: '0' },
        { position: '5', claimNo: '5675676', rentersName: 'erwerwer', lor: '21', state: 'CA', authDate: '01/19/2021', addDays: '0' },
    
    
    
      ];
      selection = new SelectionModel<batchRentalExtensionObj>(true, []);
      dataSource = new MatTableDataSource<batchRentalExtensionObj>(this.batchRentalExtensionTable);
      displayedColumns: string[] = ['select', 'position', 'claimNo', 'rentersName', 'lor', 'state', 'authDate', 'addDays'];
      isAddDaysEnabled: boolean = true;
    
      @ViewChild(MatSort, { static: false }) sort: MatSort;
    
      constructor(public commonService: CommonService, private fb: FormBuilder, public constant: Constants,) {
        this.selection.changed.subscribe(item => {
          this.isAddDaysEnabled = this.selection.selected.length == 0;
          })
       }
    
    
      ngOnInit() {
        this.initBatchRentalExtensionForm();
      }
    
      ngAfterViewInit() {
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
    
      }
    
      initBatchRentalExtensionForm() {
        this.batchRentalExtensionForm = this.fb.group({})
      }
      masterToggle() {
    
        if (this.isAllSelected()) {
          this.selection.clear()
          this.isAddDaysEnabled = true;
        } else {
          this.dataSource.data.forEach(row => this.selection.select(row));
          this.isAddDaysEnabled = false;
        }
    
      }
      isAllSelected() {
        const numSelected = this.selection.selected.length;
        const numRows = this.dataSource.data.length;
        return numSelected === numRows;
      }
    
    }

Upvotes: 0

Views: 3493

Answers (2)

newbie
newbie

Reputation: 105

Thanks for the replies.

I found a solution. I just used element to disable each row like this <td mat-cell *matCellDef="let element"> <input type="number" [disabled]="!element.isAddDaysEnabled" placeholder="0"> </td> and created a function to pass an event oclick of each row and called edit($event,row)

                                 <mat-checkbox (click)="$event.stopPropagation();edit($event,row)"
                                        (change)="$event ? selection.toggle(row) : null; "
                                        [checked]="selection.isSelected(row)">
                                    </mat-checkbox>

Here is the function

edit(event, element) {
    element.isAddDaysEnabled = !element.isAddDaysEnabled;
  }

isAddDaysEnabled is set to true in the beginning since I wanted the input fields to be disabled.

Upvotes: 1

Jonathan Irvin
Jonathan Irvin

Reputation: 1072

First you need to define an index so you know the index of each row:

<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

needs to be: <tr mat-row *matRowDef="let row; columns: displayedColumns; let i = index"></tr>

[disabled]="isAddDaysEnabled" is using one singular variable so this one variable gets updated each time a checkbox is triggered. Every row is using this same variable which is why the input on every row gets disabled or enabled. You want to use an array based off the index of the row instead, so something like this:

<input type="number" [disabled]="isAddDaysEnabled[i]" placeholder="0">

So now we have an array and can target the specific position in the array based on the row index to figure out whether this row input should be enabled or disabled.

You then need to convert that variable in your TS to be an array. When you go to toggle the checkbox, the method that you call in your TS needs to set the value based on the clicked row index. It looks like you are using this for that: this.selection.changed.subscribe(item => { this.isAddDaysEnabled = this.selection.selected.length == 0; })

If item has the row index, great you can use that. Otherwise, you'll have to pass in the row index from the HTML into the method/subscription. So you want to essentially do something like this:

this.isAddDaysEnabled[i] = this.selection.selected.length == 0;

Hope that points you in the right direction!

Upvotes: 2

Related Questions