I have a little prob with my form.
I did 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>
I try to add the formControlName but angular dont want to know anything and just saying :
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... but i dont know what to do.
I would like to bind my click to this formControl in order that when someone click on the entire card that push my 'type' into the formControl. Is it possible?
You can use formControlName
only on directives which implement ControlValueAccessor
.
Implement the interface
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).
Register a provider
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),
}
]
Usage
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.
Resources
- Custom Form Controls in Angular by Thoughtram
- Angular Custom Form Controls with Reactive Forms and NgMode by Cory Rylan
I think you should use formControlName="surveyType"
on an input
and not on a div