angular - 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;
}
}
解决方案
首先,您需要定义一个索引,以便您知道每一行的索引:
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
需要是:
<tr mat-row *matRowDef="let row; columns: displayedColumns; let i = index"></tr>
[disabled]="isAddDaysEnabled"
正在使用一个奇异变量,因此每次触发复选框时都会更新这个变量。每行都使用相同的变量,这就是为什么每行上的输入都被禁用或启用的原因。你想使用基于行索引的数组,所以像这样:
<input type="number" [disabled]="isAddDaysEnabled[i]" placeholder="0">
所以现在我们有一个数组,可以根据行索引定位数组中的特定位置,以确定是否应该启用或禁用此行输入。
然后,您需要将该 TS 中的变量转换为数组。当您切换复选框时,您在 TS 中调用的方法需要根据单击的行索引设置值。看起来您正在为此使用它:
this.selection.changed.subscribe(item => { this.isAddDaysEnabled = this.selection.selected.length == 0; })
如果item
有行索引,你可以使用它。否则,您必须将 HTML 中的行索引传递到方法/订阅中。所以你想基本上做这样的事情:
this.isAddDaysEnabled[i] = this.selection.selected.length == 0;
希望这会为您指明正确的方向!
推荐阅读
- asp.net - 使用asp.net重定向到包含下拉列表选定项目上的pdf文件的文件夹
- python-3.x - 如何在 2x2 网格中将多张图片(相同大小)与 PIL 组合?
- reactjs - 如何更改子组件按钮的图像并从父组件导航
- sockets - 发送客户端证书如何不将客户端暴露给模拟
- java - 如何在每种方法中使用我的对象数组?
- python - TensorFlow 中的张量如何不可变?
- animation - 情节元素“下降”以产生新情节的动画(分布/直方图)
- excel - 用于搜索重复值的 Excel 公式
- laravel - Laravel 字符串外键格式错误
- python - fontManager = 尝试在 python 中运行 Matplotlib 时出错