prabhat gundepalli
prabhat gundepalli

Reputation: 967

Change or click event of mat-button-toggle

I have a mat-button-toggle-group which has 5 mat-button-toggle. I need to fire an event on the click or on the change of the val, although I prefer it be a click event.

The documentation provided here shows there is no click event, but there is a change event.

I have tried the change event too (as shown below) , but the event is not getting triggered.

 <mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="rowAction">
  <mat-button-toggle value="raw_swift_msg" (change)="onValChange(value)" matTooltip="View Message">
    <i class="fa fa-eye" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
  <mat-button-toggle value="message_comment" matTooltip="Message Comment">
    <i class="fa fa-comments" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
  <mat-button-toggle value="link_trade" hasAccess id="LinkMessagePopup" matTooltip="Link Message">
    <i class="fa fa-link" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
  <mat-button-toggle value="audit_trail" matTooltip="View Audit">
    <i class="fa fa-history" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
   <mat-button-toggle hasAccess id="MessagePopup" value="move_message" matTooltip="Move message">
    <i class="fa fa-exchange" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle> 
  <mat-button-toggle value="log" matTooltip="View log">
    <i class="fa fa-book" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
</mat-button-toggle-group>

In My .ts file

import {MatButtonToggleModule} from '@angular/material/button-toggle';

onValChange(val: string) {
 this.selectedVal = val;
}   

How to trigger the above change function?

Upvotes: 15

Views: 71875

Answers (3)

Rachit
Rachit

Reputation: 3235

An easier solution to get a change event on the entire mat-button-toggle-group is to set a change event on the group, instead of each toggle button.

<mat-button-toggle-group (change)="onValChange($event.value)">
    <mat-button-toggle value="bold">Bold</mat-button-toggle>
    <mat-button-toggle value="italic">Italic</mat-button-toggle>
    <mat-button-toggle value="underline">Underline</mat-button-toggle>
</mat-button-toggle-group>

Now you can listen to the event in your component:

onValChange(value) {
    console.log(value);
}

Worked for me.

Upvotes: 16

Michelle Norris
Michelle Norris

Reputation: 594

Tangentially related, for anyone using fastclick to remove the 300ms delay on mobile webviews, here is what I needed to do to get the <mat-button-toggle-group>'s change event to fire.

Explanation: It appears that in a desktop browser, the mat-button-toggle's toggleIt handler (leading to the group's change dispatcher) is listening to the button's click event, but in a mobile webview, the toggleIt handler is listening to the button's touchend event directly. Certain mobile webviews have a built-in listener on all touchend events which waits 300ms to see if the mobile user is single or double clicking, then dispatches the proper click or dblclick event. Fastclick interferes with that by also listening for touchend events which it intercepts so that the slow webview touchendHandler is never called, and dispatches an immediate single-click event itself. However in our case, the intercepted touchend event also won't call toggleIt. So we turn off the interception, which won't hurt the time it takes for toggleIt to get called (our UX), since the webview only delays the clickHandlers, not the mat-button-toggle's direct touchendHandler.

in main.ts

import * as FastClick from 'fastclick';
FastClick['attach'](document.body); // tslint:disable-line:no-string-literal

in myComponent.ts

public ngAfterViewInit(): void {
  const collection = document.getElementsByClassName('mat-button-toggle-label-content');
  Array.from(collection).forEach((eachHandlingElement: Element) => {
    eachHandlingElement.classList.add('needsclick'); // deeper element
  });
}

in myComponent.html

<mat-button-toggle-group [(ngModel)]="mySelectedTabIndex" (change)="applyMySearch()">
  <mat-button-toggle *ngFor="let eachTabTitle of myTabTitles; let eachTabIndex = index" [value]="eachTabIndex"
    [class.my-highlight]="eachTabIndex === mySelectedTabIndex" [disabled]="wantDisabled(eachTabIndex)">
    {{ eachTabTitle }}
  </mat-button-toggle>
</mat-button-toggle-group>

in myComponent.css

mat-button-toggle {
  flex-grow: 1; /* widen visible area */
}
mat-button-toggle ::ng-deep .mat-button-toggle-label-content {
  width: stretch; /* widen clickable area */
}
mat-button-toggle-group  {
  width: 100%;
}
.my-highlight {
  color: red;
}

Upvotes: 2

Lia
Lia

Reputation: 11982

it should be :

html:

 <mat-button-toggle-group #group="matButtonToggleGroup">
  <mat-button-toggle value="raw_swift_msg" (change)="onValChange($event.value)" matTooltip="View Message">
    <i class="fa fa-eye" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
  <mat-button-toggle (change)="onValChange($event.value)" value="message_comment" matTooltip="Message Comment" >
    <i class="fa fa-comments" style="color:#455A64" aria-hidden="true"></i>
  </mat-button-toggle>
</mat-button-toggle-group>

component:

onValChange(value){
     console.log(value)
}

check this working stackblitz

Upvotes: 25

Related Questions