Uncheck active Angular Material toggle buttons on click

angular toggle switch
mat-button-toggle-group selected value
mat-button toggle is not a known element
angular material button size
angular material icon-button
angular material floating button
mat-slide-toggle change event
angular link button

I need to modify the functionality of the standard Angular Material toggle button component, so that clicking an active button returns the component to a state where no buttons are active. This has two steps:

  • Updating the value of the toggle group
  • Changing the 'checked' parameter of the clicked button to false

I've tried several approaches, e.g.

Template:

<mat-button-toggle-group #group="matButtonToggleGroup">
    <mat-button-toggle #no_btn value="no" (click)="update_toggle(group,no_btn)">No</mat-button-toggle>
    <mat-button-toggle #yes_btn value="yes" (click)="update_toggle(group,yes_btn)">Yes</mat-button-toggle>
</mat-button-toggle-group>

JS:

update_toggle(group,button){
    if(group.value==""){
        group.value = button.value;
    }
    else
    {
        group.value = "";
    }
button.checked=!button.checked;
}

But this doesn't update the 'checked' value of the buttons, I guess because the group value set by update_toggle() is in conflict with the user action of clicking the button.

The only approach which has worked is:

<mat-button-toggle-group #group="matButtonToggleGroup">
    <mat-button-toggle #no_btn value="no" (click)="update_toggle(group,no_btn)" (click)="group.value=='no' ? checked=false : checked=false">No</mat-button-toggle>
    <mat-button-toggle #yes_btn value="yes" (click)="update_toggle(group,yes_btn)" (click)="group.value=='yes' ? checked=false : checked=false">Yes</mat-button-toggle>
</mat-button-toggle-group>

But two click events on a single button feels very hacky, especially as the ternary in the second click is opposite to what it instinctively should be.

Any suggestions for a better approach?

I've tried:

@ViewChildren('no_btn') no_btn: ElementRef;

and then:

this.no_btn['_results'][k]['_inputElement']['nativeElement']['checked']=false;

But the result doesn't seem to be any different from passing the button reference in the function; clicking the button a second time doesn't uncheck it. Disabling does work, so I think my code is correct:

this.no_btn['_results'][k]['_inputElement']['nativeElement']['disabled']=true;

A simple generic solution that doesn't require resorting to events on each button or click events at all, and doesn't require ViewChildren or hard-coding value checks, is to use the button toggle in multiple mode and manage selections through the group change event. The change event gives you all you need so there is no need to access child components directly:

<mat-button-toggle-group multiple (change)="toggleChange($event)">
    <mat-button-toggle value="no">No</mat-button-toggle>
    <mat-button-toggle value="yes">Yes</mat-button-toggle>
</mat-button-toggle-group>

toggleChange(event) {
    let toggle = event.source;
    if (toggle) {
        let group = toggle.buttonToggleGroup;
        if (event.value.some(item => item == toggle.value)) {
            group.value = [toggle.value];
        }
    }
}

Here it is on Stackblitz.

Button toggle, <mat-button-toggle> are on/off toggles with the appearance of a button. These toggles can be configured to behave as either radio-buttons or checkboxes. Here, i will show you two way to make all checkbox checked and unchecked on button click event in angular js. i also give you demo. so you can check also there. we will use ng-model and ng-checked for doing simple check uncheck toggle event. in another example we will use ng-checked and ng-click. So let's see both example.

The solution is to use a click event on the toggle group, not a change event on the group, or click events on the individual buttons.

This is cleaner than having click events on each button and captures every interaction regardless of whether the value of the toggle group would change under normal behaviour, so the function can respond as required to cases where an active button has been clicked again.

$event and a data attribute on each toggle button can be used to identify which button in the group has been clicked, so interactions with non-active buttons are handled as normal.

Template:

<mat-button-toggle-group #group="matButtonToggleGroup" (click)="update_selected($event,group,k)">
    <mat-button-toggle #exclude value="exclude" data-toggle="exclude"><i class="material-icons">remove</i></mat-button-toggle>
    <mat-button-toggle #include value="include" data-toggle="include"><i class="material-icons">add</i></mat-button-toggle>
</mat-button-toggle-group>

JS:

@ViewChildren('exclude') exclude: ElementRef;
@ViewChildren('include') include: ElementRef;  

...

update_selected(event, group, index){
    if(group.value=='exclude' && event['srcElement']['offsetParent']['dataset']['toggle']=='exclude')
        {
            this.exclude['_results'][index].checked=false;
            group.value="";
            return;  
        }

        if(group.value=='include' && event['srcElement']['offsetParent']['dataset']['toggle']=='include')
        {
            this.include['_results'][index].checked=false;
            group.value="";
            return;
        }

        // Group was unselected before click, or non-active toggle button was clicked

}

Angular Material Button Toggle, You might notice that we still have the ripple effect when we click on the button, to disable it add the disableRipple attribute to the button toggle element. It is also  This article will provide example of how to call component function on button click event in angular 9/8 application. i want to show you angular 9/8 button click event and call a function example. it's very simple example of click event call function angular 9/8.

According to source code (^6.4.1) the change event (of MatButtonToggle) fires at the mouse click always:

https://github.com/angular/material2/blob/6.4.7/src/lib/button-toggle/button-toggle.ts#L461

We can subscribe to all toggle buttons (or only those buttons that we want to make uncheked):

<mat-button-toggle-group #group="matButtonToggleGroup">
    <mat-button-toggle value="no" (change)="onChange($event, group)">No</mat-button-toggle>
    <mat-button-toggle value="yes" (change)="onChange($event, group)">Yes</mat-button-toggle>
</mat-button-toggle-group>

And we can add a simple handler for these events and a field that stores the state:

private _activeValue = "";

onChange(event, group) {
  if (this._activeValue === event.value) {
    // make unchecked
    group.value = "";
    this._activeValue = "";
  } else {
    this._activeValue = event.value;
  }
}

This example is on Stackblitz

Another implementation:

We can bind the value.

<mat-button-toggle-group [value]="_activeValue">
    <mat-button-toggle value="no" (change)="onChange($event)">No</mat-button-toggle>
    <mat-button-toggle value="yes" (change)="onChange($event)">Yes</mat-button-toggle>
</mat-button-toggle-group>

public _activeValue = "";
onChange(event, group) {
   if (this._activeValue === event.value) {
       // make unchecked
       this._activeValue = "";
    } else {
       this._activeValue = event.value;
    }
 }

Angular Material 7 - Toggle Button, is on, it gives true value otherwise false value. Material Design components for Angular. Sprint from Zero to App. Hit the ground running with comprehensive, modern UI components that work across the web, mobile, and desktop. Fast and Consistent. Finely tuned performance, because every millisecond counts. Fully tested across modern browsers. Themeable, for when you need to stay on brand or

Angular Material Slide Toggle, In this post we are going to create an Angular App to use Button toggle groups from Angular material. We are going to do data binding of these  The checked state for these buttons is only updated via click event on the button. If you use another method to update the input—e.g., with <input type="reset"> or by manually applying the input’s checked property—you’ll need to toggle .active on the <label> manually.

Angular Material Toggle Buttons Group with Binding – Alternate Stack, mat-checkbox selector is an angular material checkbox component, it works like input If its true in <mat-checkbox> then checkbox is unchecked and vice versa Whenever we select radio button, corresponding value will be  In this example, i will help to get checked radio button value in angular js app. we can get selected radio button value in controller of angular. Here we will create simple example. we will create simple for and submit button.

Checkbox Implementation In Angular Using Mat-Checkbox(Material , Default unchecked --> <div class="custom-control custom-radio"> <input type="​radio" class="custom-control-input" id="defaultUnchecked"  This page will walk through Angular radio button and checkbox example. We will provide demo using template-driven form and reactive form. Using both type of form we will see how to create radio button and checkbox, fetch values and set them checked and validate them.

Comments
  • why not use @ViewChild()'s to get the instance of the checkbox and change it that way?
  • Have tried this - will update question.
  • Wouldn't that change the value of the button itself, rather than whether or not it's checked? Or do you mean the value of the group, rather than the individual button?
  • Great solution - thanks @gtranter. If anyone finds this is not working, you may need to update Angular Material, in my case from 5.2.2 to 6.4.1.