Angular 2 - how to bind to a "dynamic" form field
Solution 1
You can reference the object using square brackets notation, like this:
<input *ngIf="element.type == 'TEXT_INPUT'" type="text"
[(ngModel)]="model[element.systemName]" />
Solution 2
There's an official documentation page about exactly this:
In it they build a questionnaire / survey form where the list of questions and their types (text, select, radio, etc) are stores in dynamic object (to simulate coming from DB).
The idea is:
-
ngFor
for list of questions - Each question is the same component
- The question component has ang
ngSwitch
that chooses which form control to use
See the live example and source code.
Julius
Updated on June 15, 2022Comments
-
Julius almost 2 years
I am building a form generator with Angular 2. The form fields are defined in a datastore somewhere and rendered as a form at runtime by my Angular 2 template. I am trying to setup form binding for the dynamic form, but haven't succeeded so far.
The first approach I took is below. An input element is rendered conditionally if the current form element ('element') if of type TEXT_INPUT. There is a model class ('model') defined in the backing component and I would like the input form element to bind to model.{{element.systemName}}.
<input *ngIf="element.type == 'TEXT_INPUT'" type="text" [(ngModel)]="model.{{element.systemName}}" class="field-long" placeholder="{{element.label}}" name="{{element.systemName}}" />
This approach doesn't work. {{}} is not allowed as a value to ngModel.
My second approach didn't work either, because "this" doesn't exist.
<input (keyup)="updateModel(this)" (blur)="updateModel(this)" *ngIf="element.type == 'TEXT_INPUT'" type="text" class="field-long" placeholder="{{element.label}}" name="{{element.systemName}}"/>
Is there some way I can refer to the current form element and send that to the backing component like updateModel(ref.to.current.form.element)?
It seems that placing #myElementName on the element would create a reference, which would allow me to call updateModel(myElementName). But there again I run into the problem that I need a dynamic name like this #{{element.systemName}}.
I am completely new to Angular 2, so I am hoping I am overlooking something obvious here.
Thanks.
-
Julius over 7 yearsThis is not allowed: Parser Error: Unexpected token [, expected identifier or keyword at column 7 in [model.[element.systemName]] in DynamicFormComponent@16:65 (" </select>
-
Julius over 7 yearsThat is pretty interesting. Thanks. It the example they JSON.stringify the whole form on submitting to see what is in the form. That seems a good approach as well.
-
Meligy over 6 yearsThanks. Looks like they changed the format of the URL. It's reachable via clicking "live sample" in the first link. I also updated the 2nd link to match the current URL.
-
Meligy over 6 yearsIf that was the reason for the downvote, please check the current version of the answer. Cheers.