I have a custom element :
<div formControlName="surveyType">
<div *ngFor="let type of surveyTypes"
(click)="onSelectType(type)"
[class.selected]="type === selectedType">
<md-icon>{{ type.icon }}</md-icon>
<span>{{ type.description }}</span>
</div>
</div>
When I try to add the formControlName, I get an error message:
ERROR Error: No value accessor for form control with name: 'surveyType'
I tried to add ngDefaultControl
without success.
It seems it's because there is no input/select... and I dont know what to do.
I would like to bind my click to this formControl in order that when someone clicks on the entire card that would push my 'type' into the formControl. Is it possible?
You can use formControlName
only on directives which implement ControlValueAccessor
.
So, in order to do what you want, you have to create a component which implements ControlValueAccessor
, which means implementing the following three functions:
writeValue
(tells Angular how to write value from model into view)registerOnChange
(registers a handler function that is called when the view changes)registerOnTouched
(registers a handler to be called when the component receives a touch event, useful for knowing if the component has been focused).Then, you have to tell Angular that this directive is a ControlValueAccessor
(interface is not gonna cut it since it is stripped from the code when TypeScript is compiled to JavaScript). You do this by registering a provider.
The provider should provide NG_VALUE_ACCESSOR
and use an existing value. You'll also need a forwardRef
here. Note that NG_VALUE_ACCESSOR
should be a multi provider.
For example, if your custom directive is named MyControlComponent, you should add something along the following lines inside the object passed to @Component
decorator:
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => MyControlComponent),
}
]
Your component is ready to be used. With template-driven forms, ngModel
binding will now work properly.
With reactive forms, you can now properly use formControlName
and the form control will behave as expected.