Reputation: 746
I am struggeling to keep a material-menu open when selecting from a checkbox within it. Any suggestions would be appreciated. I've attemted solutions including changing to mat-selection-list, put each element of the menu inside a div that has (clicked)="$event.stopPropagation();$event.preventDefault();", and sending the clicked-event from the checkbox to a helper-method that does the same.
example.component.ts
@Component({
selector: 'example',
templateUrl: 'example.component.html',
styleUrls: ['example.compontent.scss'],
})
export class ExampleComponent implements OnInit {
subscriptions: Subscriptions[] = [];
userSettings: ColumnInfo[] = []; // { columnName: string, isSelected: boolean }
constructor() { }
ngOnInit() {
this.setUserConfiguration(); // prefills userSettings
}
async setUserConfiguration(): Promise<void> {
/* There's code here to pre-fill userSettings, as an example try: */
this.userSettings = ['col1', 'col2', 'col3'].foreach(col => {
return { columnName: col, isSelected: false }
});
}
filterColumn(column: string): boolean {
return this.userSettings.findIndex(col => col.columnName === col) !== -1;
}
toggleColumn(column: ColumnInfo, $event: Event): void {
$event.stopPropagation(); $event.preventDefault();
column.isSelected = !column.isSelected;
}
someOtherFunction($event: Event): void {
console.log($event);
}
public resetUserConfiguration(): void {
this.getDefaultColumnConfiguration().then( // you can use setUserConfiguration for test
res => this.userSettings = res as ColumnInfo[]
);
}
}
<ng-container matColumnDef="context" *ngIf="filterColumn('context')">
<mat-header-cell *matHeaderCellDef style="color: rgb(0, 0, 0, 1);">
<div class="ps-context-menu">
<button mat-icon-button [matMenuTriggerFor]="tablemenu"
test-id="open-tablemenu-btn">
<mat-icon fontIcon="more_vert" aria-hidden="true"></mat-icon>
</button>
<mat-menu #tablemenu="matMenu" class="ps-ctx-no-padding filter-menu">
<button mat-menu-item (click)=someOtherFunction($event) test-id="do-something-else">
This button does something else
</button>
<button mat-menu-item test-id="column-properties-btn
[matMenuTriggerFor]="columnproperties">
Column-properties
</button>
<mat-menu #columnproperties class="ps-ctx-no-padding filter-menu"
test-id="column-properties-menu">
<button mat-menu-item test-id="column-filter-btn [matMenuTriggerFor]="filtermenu">
Column filter
</button>
<mat-menu #filtermenu class="ps-ctx-no-padding filter-menu"
test-id="column-filter-menu">
<div (click)="$event.stopPropagation();$event.preventDefault();"
*ngFor="let column of userSettings">
<mat-checkbox [hidden]="column.columnName==='context'"
[checked]="column.isSelected" (click)="toggleColumn(column, $event)">
{{column.columnName}}
</mat-checkbox>
</div>
</mat-menu>
<button mat-menu-item test-id="column-reset-btn"
(click)="resetUserConfiguration()">
Reset column-selection
</button>
</mat-menu>
</mat-menu>
</div>
</mat-header-cell>
</ng-container>
Upvotes: 0
Views: 323
Reputation: 746
I eventually realized the issue. Each time toggleColumn was called, the DOM which the menu resided upon had to be re-rendered. Therefore the menu "closed".
Setting the menu outside of this DOM solved the issue, there was never a problem using stopPropagation as I first intended.
Upvotes: 1