Search code examples
angularangular4-forms

Assign Angular form controls to a dynamically generated array of objects


I have a fromGroup now I want to generate some input fields dynamically based on database values. Example: I have obj like

{
    type:"text",
    name:"test_name"
    placeholder:"Test"
}

I have created input field like:

<input type="text" name="test_name" placeholder="Test">

So far I have tried,

add dynamic controls to my FormGruop

this.applicationForm.addControl(formFieldObj.name, new FormControl('', Validators.required));

and pushed generated HTML to the template like:

<div [innerHTML]="getDynamicHTML()"></div>

Now the problem is can't add value to any of this dynamically added input fields. How I compile this generated HTML?


Solution

  • As you’ve found, innerHTML content isn't interpolated by Angular. See here, so this approach isn’t going to work.

    If you have an array of objects for each input field you need, you should be able to loop through the array in your HTML using ngFor, which can create the fields you need dynamically.

    RE getting and setting values, if you take the approach above you can add a form control for each field in the array when your component initialises. These can then be assigned to each of the fields in your template as you loop through them, so you can get / set a value for each field.

    Basic concept here - let me know how you get on. In this example I've added the field controls directly to the field data array, but you could create a new variable or use a field group.

    HTML:

    <h2>Input Form:</h2>
    <form>
        <div *ngFor="let field of fieldData">
            <label>{{field.name}}</label> 
            <input [formControl]="field.formControl" [placeholder]="field.placeholder" />
        </div>
    </form>
    <h2>Current Values:</h2>
    <div *ngFor="let field of fieldData">
        <label>{{field.name}} value: </label> 
        <span>{{field.formControl.value}}</span>
    </div>
    

    TS:

    fieldData = [{
        type:"text",
        name:"test_name_1",
        placeholder:"Test 1 Placeholder"
    },
    {
        type:"text",
        name:"test_name_2",
        placeholder:"Test 2 Placeholder"
    }]
    
    constructor(){
        for (let i = 0; i < this.fieldData.length; i++) { 
            this.fieldData[i]['formControl'] = new FormControl('');
        }
    }