4

EDIT

What I want is a group of radio buttons where selecting a radio button selects another radio button; the 'CLICKED' (not selected) radio button never gets selected by attempting to select it (by clicking on it) where its default behavior is that 'CLICKED' radio gets 'SELECTED'. Something like this Angular 2 demo.

But this demo is not exactly what I want because it has delay in selecting another radio.

Here is the demo with jQuery. This has no delay, and clicking on a radio button will NEVER check that radio button. For example, clicking the second radio button never selects the second radio button. To select the second radio button, you need to click the first radio button.


OLD: What I'm trying to do with Angular 2 is that I have 3 radio elements A, B, and C, and 2 of them, A and B can be selected, and when the third one, C, gets selected it should select B. So, C never gets selected visually, or for a blink of moment.

I couldn't make this work. So I thought recreating the problem but simpler would be a good idea, so I'm trying to solve this easier problem. I could make it so that selecting A selects B, selecting B selects C, and selecting C selects A.

A is the first radio button, B is the second, C is the third radio button.

onRadioChange(val) {
 val = val == 2 ? 0 : ++val;
 this.radio_val=val;
}

Here is the plunker demo

However, as you can see in the demo, it only works on the first click. So, clicking on B WILL select C, but clicking on B AGAIN will select B.

I think this is the main issue.

Above demo uses [(ngModel)] but the same goes for [checked].

Here is the demo with checked

However, doing this with setTimeout and [(ngModel)] works

Here is what I want to do but without delays

Is this something to do with Angular2's Lifecycle Hooks?

Please help.

asked Mar 10, 2017 at 1:00
4
  • rephrase your question which is A,B in your demo? Commented Mar 10, 2017 at 1:08
  • @Aravind Hi. None of them is A nor B. It's a new demo where you click on 'A', the first radio button, it selects the second radio button. Selecting second radio button selects third button. And selecting third button selects the first radio. Commented Mar 10, 2017 at 1:14
  • so wat is happening now? Commented Mar 10, 2017 at 1:19
  • @Aravind I provided 3 demos. I want it to work like the last demo. Clicking on a radio button selects another radio button. But the last demo isn't exactly what I wanted. I don't want it to have delay in selecting other radio. Other demos I provided DON'T work because clicking on the same radio button selects the radio button that was selected. Commented Mar 10, 2017 at 1:25

5 Answers 5

3

Click Event: set the model value for radio buttons. Change Event: call click event for that change Event will rewrite the model value.

<input type='radio' name='test' [value]='0' [(ngModel)]='radio_val' (change)='onRadioChange(0) '(click)='onRadioClick(0)'>
<input type='radio' name='test' [value]='1' [(ngModel)]='radio_val' (change)='onRadioChange(1) (click)='onRadioClick(1)'>
<input type='radio' name='test' [value]='2' [(ngModel)]='radio_val' (change)='onRadioChange(2) (click)='onRadioClick(2)'>

UPDATE:

In angular2's lifehook, radionbutton's change event is after click event. Also for what we want, we have to use settimeout to let angular2 rerenfer the view for changes at change event.

plunker demo here.

answered Mar 10, 2017 at 1:33
Sign up to request clarification or add additional context in comments.

6 Comments

Clicking on a radio button first time does it, but second time doesn't, just like my demos....
@user3290525 interesting, the second time dosen't work. the third time it works again. I'll look into it.
Thanks! I'm hoping for a very simple solution like the working demo I provided using jQuery.
@user3290525 I have update my answer. It seems that, in angular2's lifehook, radionbutton's change event is after click event. also we have to use settimeout to let angular2 rerenfer the view for changes at change event.
@user3290525 sorry, I tried, but didn't find any references to this. For me, I find this while trying to solve your quesion. After talking to others, they tell me this is too normal.. you can confirm this on the plunker i linked by add console.log and see.
|
2

I think you have to do it on (click) instead. On (change) can't deal with all cases because no change occurs when clicking on a selected button thus no change event is emitted. I would control which one is [checked] using booleans as well as it proved to be easier. So try,

(click)='onRadioChange(...)' rather than (change) and add [checked]='checked[...]' with necessary code to bind the buttons to a checked:boolean[];.

Working Plunkr : I take the liberty of making a change every click

answered Mar 10, 2017 at 3:14

Comments

1

This should work for you:

onRadioChange(val) {
 this.radio_val = (this.radio_val+1) %3;
}

And instead of using the change event, hook into the click event.

Demo

answered Mar 10, 2017 at 3:42

5 Comments

Pretty sure they don't want the one that is clicked to not be selected.
Can you rephrase that... that's a double negative
Whoops, should be: Pretty sure they don't want the one that is clicked to be selected. Not sure if that's what they actually want anymore.
I understand now:) I think that's what I did... when you click a radio button, its not selected - it selects the one next to it.
:) try clicking the first one three times...I tried and gave up and made checked bound to a boolean.
0

I'm referring to this Angular 2 documentation: Lifecycle Hooks

According to the documentation,

Angular's unidirectional data flow rule forbids updates to the view after it has been composed. Both of these hooks fire after the component's view has been composed.

Then

// Wait a tick because the component's view has already been checked
this.logger.tick_then(() => this.comment = c);

So this demo sets milliseconds parameter to 0. But does not skip setting the radio button as 'checked' like this jQuery demo does.

answered Mar 10, 2017 at 3:02

6 Comments

I guess I'm confused, your jquery example allows an already selected radio button to remain selected but you say the clicked one should never be selected. Is my answer what you're trying to do?
@ChiefTwoPencils My mistake if it's confusing. I'll rephrase to something like this: 'in the jQuery demo, clicking on the, for example, second radio button will never select the second radio button.' So, in my jQuery example, when you select the second radio button, no matter how many times it's clicked, the third radio buttons stays selected. To select the second radio button, you select the first radio button. But the problem I had was that on clicking the second radio button, it selects the third button. On clicking the second radio button again, it selects the second radio button.
I think you can get mine to work for you by altering it a bit. Mine will switch between the two unclicked ones while you want it to stay on one. If you have trouble I might have time later to edit it.
@ChiefTwoPencils I think I found a solution to it by reading the 'Lifecycle hook' article? in the Angular 2 guide. By using setTimeout function with '0' as second parameter. Setting the second parameter of the setTimeout of the first demo seems to do the job. It doesn't work exactly as jQuery does because there is a blink of moment where the clicked radio gets selected while in jQuery, you don't even see the black dot indicating the radio got selected on the clicked radio.
I think that's true for your approach but attribute binding is handled differently. I guess I made some edits to the plunkr in my answer but it's now correct again. Please give it a try. It does what you want (and a little more) without any delay or setTimeout.
|
0
 // html
 <ion-card *ngFor="let val of addressList;">
 <ion-card-content (click)='onSelectionChange(val)'>
 <ion-row>
 <ion-col size="2">
 <input type="checkbox" class="selectBox" [checked]="val._id === selectedEntry._id" [value]="val._id" (change)='onSelectionChange(val)' >
 </ion-col>
 <ion-col size="8">
 {{val.area}} ,{{val.city}}<br>
 {{val.nearBy}}<br>
 {{val.city}} , {{val.state}} ,{{val.pincode}},
 {{val.country}}
 </ion-col>
 </ion-row>
 </ion-card-content>
 </ion-card>
 // component
 public addressList: any;
 public selectedEntry: any = {
 _id: ""
 }
 ngOnInit() {
 this.getAddress();
 }
 getAddress() {
 this._ProductService.getAddress(localStorage.getItem('userId')).subscribe((data: any) => {
 this.addressList = data;
 console.log(this.addressList)
 });
 }
 onSelectionChange(entry) {
 this.selectedEntry = Object.assign({}, this.selectedEntry, entry);
 console.log(this.selectedEntry, "select")
 }
answered Mar 22, 2020 at 17:51

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.