Angular: How to make Mat-Slide-Toggle to work as radio button?

Viewed 1912

I have a dynamic form with 1 input field and 1 mat-slide-toggle. What I want is that suppose if the form fetches 4 mat-slide-toggle then if I set any one of the toggles true then the others will automatically be false.

HTML

<h3>Options & Answers</h3>
<div formArrayName="options">
  <ul *ngFor="let o of updateQuestionForm.get('options')['controls']; let i = index;" [formGroupName]="i"
    style="list-style: none;">
    <li style="display: inline-block; margin-right: 10px;">
      <mat-form-field>
        <mat-label>Option</mat-label>
        <input matInput formControlName="optionText">
      </mat-form-field>
    </li>
    <li style="display: inline-block;">
      <mat-label>Answer</mat-label><br>
      <mat-slide-toggle color="primary" formControlName="answer"></mat-slide-toggle>
    </li>
  </ul>
</div>

Current Scenario:

Screenshot

But I want if I click the 2nd option then the 3rd will get false automatically.

This is my example for the same in Stackblitz.

Please help me out.

4 Answers

You can use a change() event callback provided by mat-slide-toggle and the callback method makes sure only one slider is set to true (take a look at this stackBlitz) -

<div formArrayName="options">
    <ul *ngFor="let o of updateQuestionForm.get('options')['controls']; let i = index;" [formGroupName]="i"
        style="list-style: none;">
        <li style="display: inline-block; margin-right: 10px;">
            <input formControlName="option_text" placeholder="Text">
        </li>
        <li style="display: inline-block;">
            <mat-slide-toggle color="primary" formControlName="answer" (change)="toggle(o, i)"> //<--- this event handler
            </mat-slide-toggle>
        </li>
    </ul>
</div>

Then in your component -

toggle(event, i) {
    const formArray = <FormArray>this.updateQuestionForm.controls["options"];
    const len = formArray.length;
    for (let j = 0; j < len; j++) {
      if (event.value && i !== j) {
        formArray.at(j)["controls"]["answer"].setValue(false);
      }
    }
  }

Consider this approach,

  • Capture the event change() and pass the value of the index i
  • Set all answers to false
  • Set the clicked answer true. This approach will ensure that if an answer is selected, then it remains selected unless another answer is selected, just like a radio button
    <div formArrayName="options">
        <ul *ngFor="let o of updateQuestionForm.get('options')['controls']; let i = index;" [formGroupName]="i"
            style="list-style: none;">
            <li style="display: inline-block; margin-right: 10px;">
                <mat-form-field>
                    <mat-label>Option</mat-label>
                    <input matInput formControlName="optionText">
      </mat-form-field>
            </li>
            <li style="display: inline-block;">
                <mat-label>Answer</mat-label><br>
                <mat-slide-toggle (change)='updateAnswer(i)' color="primary" formControlName="answer">
                </mat-slide-toggle>
            </li>
        </ul>
    </div>
updateAnswer(i) {
    const controls = this.updateQuestionForm.get("options")["controls"];
    controls.forEach(control => {
      control.get("answer").setValue(false);
    });
    controls[i].get("answer").setValue(true);
  }

See this stackblitz demo

use the [checked] attribute set FALSE of the third slide depends on the second slide check

for example

  <mat-slide-toggle
      class="example-margin"
      [color]="color"
      [checked]="checked">
    Slide me!
  </mat-slide-toggle>

the checked value set false when second slide checks.

Try this easy solution you can as many as sliders to this.

         <mat-slide-toggle name="type1" [(ngModel)]="type1" (change)='onChange($event, 1)'>Type 1</mat-slide-toggle>
         <mat-slide-toggle name="type2" [(ngModel)]="type2" (change)='onChange($event, 2)'>Type 2</mat-slide-toggle>
        
         public typeRadioValue = 1;
         public type1 = true;
         public type2 = false;
         onChange($event, type)
          {
            this.typeRadioValue = type;
            if (type == 1) {
              if ($event.checked) {
                this.type2 = false;
              } else {
                this.type2 = true;
              }
            } else {
              if ($event.checked) {
                this.type1 = false;
              } else {
                this.type1 = true;
              }
            }
          }
Related