Angular 5 - Disabling Radio Buttons
Asked Answered
P

10

18

I have a radio button group in Angular 5. I want to disable some options, using the [disabled] attribute. However, I am noticing only the first radio button actually gets disabled. See my plunker: http://plnkr.co/edit/JzFmvjUyvhPdTkbYT1YZ?p=preview

Even if I hard code [disabled]="true", it still doesn't disable the second radio button. I don't want to switch to using a <select>, so I am curious if there is another way to get this to work with radio buttons.

Pied answered 21/11, 2017 at 18:17 Comment(4)
are you using template driven forms? reactive forms? no forms at all?Bag
Template-driven.Pied
Just related when calling methods in template... #37877033Komarek
I added a brief explanation and a solution to the problem. I hope that it help.Donatus
D
41

There can be 2 solutions for this :-

1. Using the disabled attribute ([attr.disabled])

One solution to this problem can be using the disabled attribute ([attr.disabled]) instead of the disabled property ([disabled]), but [attr.disabled] works slightly differently, to enable the radio button you need to pass null to [attr.disabled] and any non-null value to disable it. Consider the below example :-

<input type="radio" name="enabled" [attr.disabled]="null" />Enabled1
<input type="radio" name="enabled" [attr.disabled]="null" />Enabled2

<input type="radio" name="disabled" [attr.disabled]="false" />Disabled1
<input type="radio" name="disabled" [attr.disabled]="false" />Disabled2

In this example the set of radio buttons named "enabled" will be enabled since for them [attr.disabled] is set to null, whereas the set of radio buttons named "disabled" will be disabled despite the [attr.disabled] being set to "false" this is because false is a non-null value.

2. Using fieldset tag

Another even better solution for this problem is using the <fieldset> tag for grouping the radio buttons together and then setting the [disabled] property on that <fieldset> tag instead of individual radio buttons. Below is an example for the same :-

<fieldset [disabled]=true>
    <input type="radio" name="test" />yes
    <input type="radio" name="test" />no
</fieldset>
Descendent answered 21/5, 2018 at 19:1 Comment(1)
the fieldset trick is just awesome 👍 I love htmlDub
T
8

Use this : (for reactive form approach)

 <input
    type="radio"
    id="primaryIPV6"
    value="2"
    [attr.disabled]="flagValue ? '' : null"
    formControlName="p_ip_type"
    (change)="optionalFn()">

Set flagValue programmatically from .ts class:

use -> null : false (null would be interpreted as false ) use -> true/'' : true (true or simply blank would be interpreted as true)

Timbuktu answered 31/1, 2019 at 13:55 Comment(2)
This answered worked correctly, seems the proper approach, Thanks ! @abhishek I am still new to reactive, is this the recommended way for reactive forms ?Volution
Yes, indeed. Please upvote my answer if this helped you in your work :)Timbuktu
S
6

It works fine like this [attr.disabled]="isDisabledState === true"

And in the component class you can have isDisabledState: boolean = true

Sidonnie answered 21/11, 2017 at 18:31 Comment(5)
Maybe I am doing something wrong, but that is just setting disabled="true" and disabled="false", which is always interpreted as disabled.Pied
I think what @Sidonnie is getting at is something along the lines like below where you have a property that interprets the true/false condition and then the radio button will be disabled or enabled based on that property. ` <input type="radio" name="answer" value="Yes" [(ngModel)]="name" [disabled]="isDisabled" /> Yes <input type="radio" name="answer" value="No" [(ngModel)]="name" [disabled]="isDisabled" /> No` export class App { name:string; isDisabled: boolean = true; } And then you can add in a function to toggle isDisabled stateArnulfoarny
using [attr.disabled]="<true expression>" instead of [disabled]="<true expression>" worked for me. This also worked in the context of a *ngFor.Dierdre
[attr.disabled]="some_expression" worked for me. Thank you...been banging my head on this one for a bit...Boater
One more note...[attr.disabled]="isReadOnly === true ? true : null" is needed to toggle the disabled of the radio button... isReadOnly is defined in my .ts fileBoater
D
6

One way to deal with the problem is to place the disabled binding on the last radio button in the group. Here is a modified version of your code: http://plnkr.co/edit/v6S5G7Do5NAMKzZvNdcd?p=preview

<input type="radio" name="answer" value="Yes" [(ngModel)]="name" /> Yes
<input type="radio" name="answer" value="No" [(ngModel)]="name" [disabled]="isDisabled()" /> No

There is a bug and a design problem in disabling (using [disabled]) Angular template driven radio buttons.

I fixed the bug in this pull request: https://github.com/angular/angular/pull/20310

The design problem is that we put the [disabled] binding on a single radio button, but it's all the group that is affected by the data binding. Here is a modified version of your code that illustrate the problem: http://plnkr.co/edit/3yRCSPsdjXqhUuU9QEnc?p=preview

Donatus answered 21/11, 2017 at 21:19 Comment(2)
There's nothing to prevent someone from putting a separate disabled condition on each radio button and you should be able to disable some options and not others. In my real-world scenario, I have radio buttons for Approve and Reject and in some cases one or the other should be disabled, maybe both. That said, I understand the challenge for a JavaScript library to uniquely identify radio buttons with the same name.Pied
So in your case [disabled] will not work (here an example plnkr.co/edit/3yRCSPsdjXqhUuU9QEnc?p=preview). The solution is to use [attr.disabled].Donatus
P
1

I ended up cheating. Instead of using the same name for both radio buttons, I gave each radio button a unique name and bound them to the same backing field. http://plnkr.co/edit/zNbODcAqZMgjXfluxhW6?p=preview

@Component({
  selector: 'my-app',
  template: `
    <form>
      Hello {{name}}!!!
      <input type="radio" name="answer1" value="Yes" [(ngModel)]="name" [disabled]="isDisabled1()" /> Yes
      <input type="radio" name="answer2" value="No" [(ngModel)]="name"  [disabled]="isDisabled2()" /> No
    </form>
  `,
})
export class App {
  name:string;
  isDisabled1(): boolean {
    return false;
  },
  isDisabled2(): boolean {
    return false;
  }
}

Since they are both bound to the same backing field, they end up being mutually exclusive, behaving the way radio buttons should. It also allows them to be independently disabled.

In my real-world scenario, I actually only did one-way binding with (click) events to set the bound value, but it's the same trick.

Pied answered 22/11, 2017 at 12:24 Comment(1)
If you later add validators on your radio buttons you will have problems because there are two FormControl. For example you will not be able to check if a value is selected.Donatus
F
1

I was working with ionic and the following works for me.

<ion-radio class="fix-radio_button" *ngIf="!IsSuspended" color="default" [disabled]="q.QuestionOptionId==q.AnswerId" [checked]="q.QuestionOptionId==q.AnswerId"></ion-radio>
Farmann answered 25/3, 2019 at 6:42 Comment(0)
A
0

Considering DrNio answer you should use attr.disabled and set value as [value]="'Yes'". This is because assigning as "Yes" makes angular to evaluate it as an expression instead of just a value.So your input element would be :

<input type="radio" name="answer" [value]="'Yes'" [(ngModel)]="name"   [attr.disabled]="isDisabled()"  />
Atlantes answered 21/11, 2017 at 19:15 Comment(1)
have you checked his plunker url ? with the same function call one radio button is disabled and the other one not (on init of the app - without clicking anywhere)Sidonnie
G
0

Here is your updated running code and punker..

Update Plunker

@Component({
  selector: 'my-app',
  template: `
    <form>
      Hello {{name}}!!!
      <input type="checkbox" name="dus" [(ngModel)]="isDisabled">
      <input type="radio" name="answer" value="Yes" [(ngModel)]="name" [disabled]="isDisabled" /> Yes
      <input type="radio" name="answer" value="NO" [(ngModel)]="name"  [disabled]="isDisabled" /> No
    </form>
  `,
})
export class App {
  name = 'Yes';;
  isDisabled = true;
}
Galata answered 21/11, 2017 at 21:1 Comment(1)
isDisabled:true; should be isDisabled=true;Donatus
M
0

If you want to disable a specific radio button of angular material which is in a loop, you can do this based on specific condition. This can be done like this, using the disabled attribute of the radio group:

In HTML:

<mat-radio-group>
    <mat-radio-button value="1" 
        [disabled]="name === 'welcome' ? false : true" 
        *ngFor="let name of names;">
        {{ name }}
    </mat-radio-button>
</mat-radio-group>

In .ts file:

public names = [
    'welcome',
    'computer',
    'keyboard'
]
Mikkel answered 3/1, 2023 at 8:47 Comment(0)
M
0

[attr.disabled]

it basically works on two basis

  1. When we use [attr.disabled]="null", in this case, it will enable radio
  2. When we use [attr.disabled]="true", in this case it will disable radio
Mateo answered 30/3, 2023 at 4:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.