Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic key / value form reactive angular 5

I've searched for a long time and I didn't find what I want to do. I would like to add dynamic key/value with angular 5 and reactive form.

When I click on a button "add parameter", 2 inputs appear dynamically. One for key, the other for the value.

And when I submit my form, I would like to get this :

{ settings : { key1: value1, key2: value2... } }

Here what I've done :

my component :

        constructor(
        protected fb: FormBuilder,

    ) {

        // form init
        this.testForm = fb.group({
            'name': fb.control('', [Validators.required]),
            'desc': fb.control('', [Validators.required]),
            'config': fb.array([])
        });
    }
    
    
    ...

getControls(frmGrp: FormGroup, key: string) {
    return (<FormArray>frmGrp.controls[key]).controls;
}
    
 
    addConfigBlock() {

        let settingBlock = this.testForm.get('setting') as FormArray;

        settingBlock.push(this.fb.group({key: '', value: ''}));


    }

template.html

                <div fxLayout="column" fxflex="100%" class="form-standard">
                    <div formArrayName="config" *ngFor="let setting of getControls(testForm, 'config'); let i = index;">
                        <div [formGroupName]="i" fxLayout="column" fxFlex="100%"> 
                            <mat-form-field class="form-input"> 
                                <input matInput formControlName="key" name="key" maxlength="255"
                                placeholder="Key" required> 
                            </mat-form-field>
                            <mat-form-field class="form-input"> 
                                <input matInput formControlName="value" name="value" maxlength="255"
                                    placeholder="Value" required> 

                            </mat-form-field>
                        </div>
                    </div>
                </div>
                <mat-card-content class="mat-card-content">
                    <div fxLayout="row" fxLayoutAlign="start stretch" class="form-standard">
                        <div fxFlex.gt-md="100" fxFlex.xs="100">
                            <div fxLayoutAlign="space-around stretch">
                                <button type="button" mat-raised-button color="primary" (click)="addSetting()">Add setting</button>
                            </div>
                        </div>
                    </div>
                </mat-card-content>

I don't know what is the best way to achieve this. Thank you very much :)

like image 505
Joe Allen Avatar asked Feb 14 '26 02:02

Joe Allen


1 Answers

The way I see it, is to make use of a variable in the component that keeps track of the index, on each add, increment the variable. Then use that value in the naming of the form control, so something like...

i = 0;

addConfigBlock() {
  let settingBlock = this.testForm.get('config') as FormArray;
  settingBlock.push(this.fb.group({['key'+this.i] : '', ['value'+this.i]: '' }));
  this.i++;
}

and in the template you mark the formcontrols with

formControlName="key{{i}}"
formControlName="value{{i}}"

where i is the index in your iteration.

Here's a

StackBlitz

like image 108
AT82 Avatar answered Feb 16 '26 14:02

AT82