如何在选择多个 mat-checkbox 时激活按钮并仅在未选择任何内容时停用按钮? (Angular material)
How to activate a button when selecting several mat-checkbox and deactivate it only when nothing is selected? (Angular material)
我正在使用 Angular Material 制作 table。在 table 中,我有数据,这些数据是从我在 JAVA 中创建的数据库中添加的。根据数据库中的行数(数据)创建复选框。这个想法是必须禁用将此数据发送到另一个 table 的按钮,并且它 必须仅启用 当至少有 1 个活动复选框时,如果没有活动复选框按钮必须被禁用。
问题是,当我取消选择 1 个复选框时,无论其他复选框是否处于活动状态,按钮都会被禁用。
HTML
<button mat-raised-button [disabled]="buttonDisable" (click)="procesarClic()">Enviar</button>
<ng-container matColumnDef="seleccionVarios">
<mat-header-cell *matHeaderCellDef><label class="tituloTabla-verdoso text-center"> CHECKBOX </label></mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-checkbox #checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(element) : null; changeCheck($event)"
[checked]="selection.isSelected(element)">
</mat-checkbox>
</mat-cell>
</ng-container>
TypeScript
export class PaginaPrincipal implements OnInit {
buttonDisable: boolean = true;
changeCheck(event){
this.buttonDisable = !event.checked;
}
如果您想要 Angular 为您制作它,您只需要一个 FormArray 和一个自定义验证器。
如果你定义
checked:FormArray
当您创建数据源 (*) 时,例如在 ngOnInit
ngOnInit() {
this.dataSource = ELEMENT_DATA;
this.checked = new FormArray(
this.dataSource.map((x) => new FormControl()),
this.someChecked()
);
}
你需要两个辅助功能:
//A custom Validator
someChecked() {
return (form: AbstractControl) => {
return form.value.find((x) => x)
? null
: { error: 'almost one must be select' };
};
}
//and an auxiliar "getter"
checkedAt(index:number){
return this.checked.at(index) as FormControl
}
您可以使用像
这样的单元格
<ng-container matColumnDef="seleccionVarios">
<th mat-header-cell *matHeaderCellDef>...</th>
<td mat-cell *matCellDef="let element;let i=index">
<mat-checkbox [formControl]="checkedAt(i)"> </mat-checkbox>
</td>
</ng-container>
还有你的按钮:
<button mat-button (click)="submit()" [disabled]="checked.errors">
submit
</button>
还有..瞧!此外,您可以获得像
这样的“选定”元素
submit()
{
const selected=this.dataSource.filter((_,index)=>this.checked.value[index])
console.log(selected)
}
(*)小心,在示例中数据源是一个数组,如果您使用 MatTableDataSource 则需要迭代 datasource.data
this.dataSource=new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
this.checked = new FormArray(
this.dataSource.data.map((x) => new FormControl()),
this.someChecked()
);
//and in submit
const selected=this.dataSource.data.filter(
(_,index)=>this.checked.value[index])
我发现此解决方案存在问题,当更改页面(使用分页器)以查看其他行时,复选框不会更改,它们仍然处于活动状态并且位于它们所在的相同位置被点击。如果它从另一页的其他行获取信息,但如果我有 16 行并且我想 select 所有这些,我将无法做到。分页器有 10 行,其他 6 行在分页器的另一页上,我不能 select 的是那些行,因为在更改分页器时它们已经 selected.
HTML:
<button mat-raised-button [disabled]="comprobarFilas()" (click)="procesarClic()">Solicitar</button>
<ng-container matColumnDef="seleccionVarios">
<mat-header-cell *matHeaderCellDef><label class="tituloTabla-verdoso text-center"> CHECKBOX </label></mat-header-cell>
<mat-cell *matCellDef="let element; let i=index">
<mat-checkbox #checkbox ((click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(element) : null;"
[checked]="selection.isSelected(element)"
[formControl]="checkedAt(i)">
</mat-checkbox>
</mat-cell>
</ng-container>
TS:
ngOnInit() {
this.dataSource = ELEMENT_DATA;
this.checked = new FormArray (
this.dataSourceSolicitudNew.data.map((x) => new FormControl()),
this.someChecked()
);
}
someChecked() {
return (form: AbstractControl) => {
return form.value.find((x) => x)
? null
: { error: 'almost one must be select' };
};
}
checkedAt(index: number) {
return this.checked.at(index) as FormControl;
}
comprobarFilas() {
if(this.checked == null) {
return false;
}
else {
return this.checked.errors;
}
}
procesarClic() {
const request = this.selection.selected
const newTable = this.dialog.open(SolicitudNewDialog, {
width: '400px',
disableClose: true,
data: { datosItem:request }
});
}
“procesarClic()”函数打开一个对话框弹出窗口,我必须在其中显示我 selected 的项目列表。 感谢您的帮助!
我正在使用 Angular Material 制作 table。在 table 中,我有数据,这些数据是从我在 JAVA 中创建的数据库中添加的。根据数据库中的行数(数据)创建复选框。这个想法是必须禁用将此数据发送到另一个 table 的按钮,并且它 必须仅启用 当至少有 1 个活动复选框时,如果没有活动复选框按钮必须被禁用。
问题是,当我取消选择 1 个复选框时,无论其他复选框是否处于活动状态,按钮都会被禁用。
HTML
<button mat-raised-button [disabled]="buttonDisable" (click)="procesarClic()">Enviar</button>
<ng-container matColumnDef="seleccionVarios">
<mat-header-cell *matHeaderCellDef><label class="tituloTabla-verdoso text-center"> CHECKBOX </label></mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-checkbox #checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(element) : null; changeCheck($event)"
[checked]="selection.isSelected(element)">
</mat-checkbox>
</mat-cell>
</ng-container>
TypeScript
export class PaginaPrincipal implements OnInit {
buttonDisable: boolean = true;
changeCheck(event){
this.buttonDisable = !event.checked;
}
如果您想要 Angular 为您制作它,您只需要一个 FormArray 和一个自定义验证器。
如果你定义
checked:FormArray
当您创建数据源 (*) 时,例如在 ngOnInit
ngOnInit() {
this.dataSource = ELEMENT_DATA;
this.checked = new FormArray(
this.dataSource.map((x) => new FormControl()),
this.someChecked()
);
}
你需要两个辅助功能:
//A custom Validator
someChecked() {
return (form: AbstractControl) => {
return form.value.find((x) => x)
? null
: { error: 'almost one must be select' };
};
}
//and an auxiliar "getter"
checkedAt(index:number){
return this.checked.at(index) as FormControl
}
您可以使用像
这样的单元格<ng-container matColumnDef="seleccionVarios">
<th mat-header-cell *matHeaderCellDef>...</th>
<td mat-cell *matCellDef="let element;let i=index">
<mat-checkbox [formControl]="checkedAt(i)"> </mat-checkbox>
</td>
</ng-container>
还有你的按钮:
<button mat-button (click)="submit()" [disabled]="checked.errors">
submit
</button>
还有..瞧!此外,您可以获得像
这样的“选定”元素submit()
{
const selected=this.dataSource.filter((_,index)=>this.checked.value[index])
console.log(selected)
}
(*)小心,在示例中数据源是一个数组,如果您使用 MatTableDataSource 则需要迭代 datasource.data
this.dataSource=new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
this.checked = new FormArray(
this.dataSource.data.map((x) => new FormControl()),
this.someChecked()
);
//and in submit
const selected=this.dataSource.data.filter(
(_,index)=>this.checked.value[index])
我发现此解决方案存在问题,当更改页面(使用分页器)以查看其他行时,复选框不会更改,它们仍然处于活动状态并且位于它们所在的相同位置被点击。如果它从另一页的其他行获取信息,但如果我有 16 行并且我想 select 所有这些,我将无法做到。分页器有 10 行,其他 6 行在分页器的另一页上,我不能 select 的是那些行,因为在更改分页器时它们已经 selected.
HTML:
<button mat-raised-button [disabled]="comprobarFilas()" (click)="procesarClic()">Solicitar</button>
<ng-container matColumnDef="seleccionVarios">
<mat-header-cell *matHeaderCellDef><label class="tituloTabla-verdoso text-center"> CHECKBOX </label></mat-header-cell>
<mat-cell *matCellDef="let element; let i=index">
<mat-checkbox #checkbox ((click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(element) : null;"
[checked]="selection.isSelected(element)"
[formControl]="checkedAt(i)">
</mat-checkbox>
</mat-cell>
</ng-container>
TS:
ngOnInit() {
this.dataSource = ELEMENT_DATA;
this.checked = new FormArray (
this.dataSourceSolicitudNew.data.map((x) => new FormControl()),
this.someChecked()
);
}
someChecked() {
return (form: AbstractControl) => {
return form.value.find((x) => x)
? null
: { error: 'almost one must be select' };
};
}
checkedAt(index: number) {
return this.checked.at(index) as FormControl;
}
comprobarFilas() {
if(this.checked == null) {
return false;
}
else {
return this.checked.errors;
}
}
procesarClic() {
const request = this.selection.selected
const newTable = this.dialog.open(SolicitudNewDialog, {
width: '400px',
disableClose: true,
data: { datosItem:request }
});
}
“procesarClic()”函数打开一个对话框弹出窗口,我必须在其中显示我 selected 的项目列表。 感谢您的帮助!