Skip to content

Instantly share code, notes, and snippets.

@rjcorwin
Forked from dherges/nested-form.component.ts
Created June 16, 2017 14:50
Show Gist options
  • Save rjcorwin/5d42876fc3f6229d59e66a303e7cf57e to your computer and use it in GitHub Desktop.
Save rjcorwin/5d42876fc3f6229d59e66a303e7cf57e to your computer and use it in GitHub Desktop.
Angular2: reactive, nested form
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
import { AbstractControl, FormArray, FormBuilder, FormControl,
FormGroup, Validators } from '@angular/forms'
@Component({
selector: 'nested-form',
template:
`
<form [formGroup]="myForm" (ngSubmit)="submit()">
<h4>Form</h4>
<hr>
<fieldset formArrayName="items">
<h6>Items</h6>
<div *ngIf="myForm.get('items').hasError('minSum')">
You must buy a total sum of at least {{ myForm.get('items').getError('minSum') }}.
</div>
<div class="form-group row"
*ngFor="let item of myForm.get('items').controls; let i=index"
[formGroup]="item">
<div class="col-sm-6">
<label [attr.for]="'name'+i">Name</label>
<input type="text" class="form-control"
[attr.id]="'name'+i" formControlName="name">
</div>
<div class="col-sm-5">
<label [attr.for]="'quantity'+i">Quantity</label>
<input type="number" class="form-control"
[attr.id]="'quantity'+i" formControlName="quantity">
</div>
<div class="col-sm-1 py-1">
<button type="button" class="btn"
(click)="myForm.get('items').removeAt(i)">-</button>
</div>
</div>
</fieldset>
<div class="form-group row">
<div class="col-sm-2 col-sm-offset-10">
<button type="button" class="btn btn-link"
(click)="myForm.get('items').push(buildItem(''))">Add another item</button>
</div>
</div>
<hr>
<div class="form-group">
<input type="submit" class="form-control"
value="Submit" [disabled]="myForm?.invalid">
</div>
</form>
<h6 class="mt-3">FormGroup Model (<code>myForm.value</code>)</h6>
<div><pre><code>{{ myForm?.value | json }}</code></pre></div>
`
})
export class NestedFormComponent implements OnInit {
myForm: FormGroup;
constructor(
private fb: FormBuilder
) {}
ngOnInit() {
// build the form model
this.myForm = this.fb.group({
items: this.fb.array(
[this.buildItem('aaa'), this.buildItem('')],
ItemsValidator.minQuantitySum(300)
})
}
submit() {
console.log("Reactive Form submitted: ", this.myForm)
}
buildItem(val: string) {
return new FormGroup({
name: new FormControl(val, Validators.required),
quantity: new FormControl(100)
})
}
}
class ItemsValidator {
static minQuantitySum(val: number) {
return (c: AbstractControl) => {
let sum = c.value
.map(item => item.quantity)
.reduce((acc, cur) => acc + cur, 0 );
if (sum < val) {
return { minSum: val }
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment