0

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>
5
  • Looks like $event is missing in mat-checkbox (click)="toggleColumn(column)". Should be (click)="toggleColumn(column, $event)". Please check if this solves your problem. I think also that $event.stopPropagation(); should be enough. Commented Dec 12, 2022 at 15:33
  • That was an oopsie on my part. I couldn't simply copy-paste as most of the html is in another language so it wouldn't be understandable, and contains a lot of irrelevant things to this issue. Unfortunately even though the $event is passed along to the toggle-function, it does not help. I've tried both with only stopPropagation, and with preventDefault Commented Dec 12, 2022 at 15:35
  • Can you create a Stackblitz example? Commented Dec 12, 2022 at 15:40
  • @Rajat That's odd, I tried replicating with on stackblitz, but to my surprise everything is working as expected there: stackblitz.com/edit/… -- I will have to revise module-versions. Commented Dec 12, 2022 at 16:41
  • @RoyM, yeah that's weird. Perhaps try making your local and Stackblitz code same until both work fine or both break to see what may be the issue Commented Dec 13, 2022 at 11:27

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.