MikeS
MikeS

Reputation: 1078

Angular2 Custom radio buttons dont work

I have created custom radio buttons component and need to pass the value to parent form. But I got the error message: Cannot find control with unspecified name attribute.

Parent template:

<form #f="ngForm">
  <radio name="radioParent" [data]="data" ngDefaultControl [(ngModel)]="dataOut"></radio>
</form>

Child component:

import {
  Component, Input, forwardRef, ElementRef, Renderer
} from '@angular/core';
import {
  FormControl,
  NG_VALUE_ACCESSOR, NG_VALIDATORS, ControlValueAccessor
} from '@angular/forms';


@Component({
    selector: 'radio',
    template: `
    <ul>
      <li *ngFor="let item of data">
        <label>
          <input type="radio" name="radio1"
            [value]="item.id"
            [formControl]="childControl"
            (input)="fn($event.target.value)"
            >
          <p>{{ item.title }}</p>
        </label>
      </li>
    </ul>
    `,
    providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyChild),
      multi: true
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => MyChild),
      multi: true
    }
  ]
})

export class MyChild  implements ControlValueAccessor {
  @Input() data: any;
  out: any;


  fn: (value:any) => void;

  validateFn: any = () => {};

  constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}

  writeValue(value: any): void {
    this._renderer.setElementProperty(this._elementRef, 'checked', value == this._elementRef.nativeElement.value);
  }
  registerOnChange(fn: (value: any) => void) {
    this.onChange = fn;
  }
  registerOnTouched() {}

}

And in the plunker: https://plnkr.co/edit/hkk0CANKWRmys9R4gZg1?p=preview

Upvotes: 1

Views: 2233

Answers (1)

slaesh
slaesh

Reputation: 16917

Changed a few things:

  • use item.value instead of item.id
  • removed [formControl]="childControl", there is no property childControl in your component !!
  • use (click) instead of (input)
  • removed provide: NG_VALIDATORS, it causes errors! you need to set it up correctly, dont copy paste from provide: NG_VALUE_ACCESSOR

working demo: https://plnkr.co/edit/iYQF2Z6MVh0aeMz1nGLG?p=preview

@Component({
    selector: 'radio',
    template: `
    <ul>
      <li *ngFor="let item of data">
        <label>

          <!-- [formControl]="childControl" causes errors.. there is no property called 'childControl' in this component.. -->
          <!-- [value]="item.value" instead of [value]="item.id" !! -->

          <input type="radio" name="radio1"
            [value]="item.value"

            (click)="onChange($event.target.value)">

          <!-- use (click) instead of (input) -->

          <span>{{ item.title }}</span>
        </label>
      </li>
    </ul>
    `,
    providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyChild),
      multi: true
    }
    /*, causes errors !!
    {
      provide: NG_VALIDATORS,
      //useExisting: forwardRef(() => MyChild), => not right !! do not just copy and paste stuff around .. !
      // should be something like this:
      useValue: validateEmail, // <-- your validation function !
      // see this article: https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html
      multi: true
    }
    */
  ]
})

Upvotes: 1

Related Questions