@formio/nextgen-angular
v0.1.1
Published
Angular wrapper for @formio/nextgen — a thin, embed-style renderer + builder
Readme
@formio/nextgen-angular
A thin, embed-style Angular wrapper around @formio/nextgen.
The renderer owns rendering, validation, and submission; this package owns only the
Angular surface (a component, its inputs/outputs, and lifecycle teardown). There is no
alerts layer, loader, HTTP service, or submit orchestration baked into the wrapper — those
live in the renderer. Anything not surfaced as an @Output() is reachable through the
live instance.
Install
npm install @formio/nextgen-angular @formio/nextgen@angular/core and @angular/common (v16+) are peer dependencies.
Render a form
Standalone (Angular 16+):
import { Component } from "@angular/core";
import { FormioFormComponent } from "@formio/nextgen-angular";
@Component({
standalone: true,
imports: [FormioFormComponent],
template: `
<formio
[src]="'https://example.form.io/myform'"
(submitDone)="onDone($event)"
></formio>
`,
})
export class MyPage {
onDone(e: { submission: unknown }) {
/* ... */
}
}Or with a JSON definition and a submission:
<formio
[form]="definition"
[submission]="submission"
(change)="onChange($event)"
></formio>NgModule apps can import FormioModule instead of the standalone component.
Inputs
| Input | Type | Notes |
| --------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| form | FormDefinition | A JSON form definition. |
| src | string | A form URL. Loads the form and is the submit endpoint. Wins over form. |
| submission | Submission | Initial submission; later changes are pushed via instance.submission. |
| options | WebformOptionsInput | Passed straight through to createForm. |
| renderOptions | WebformOptionsInput | The name classic @formio/angular uses for the same thing. Merged after options, so it wins on conflict. Provided so templates written against classic bind unchanged. |
| hideLoading | boolean | Accepted and ignored. Classic shows a spinner while a [src] form loads; this wrapper leaves the element empty until createForm resolves, so there is nothing to hide. Present only so a shared template can keep the binding classic needs. |
Outputs
ready (instance, on first render), settled (instance, once async loads — URL selects,
nested-form schemas — have resolved), change, submit, submitDone, customEvent (a Button or
DataSource event action; note event is absent when the emitter isn't a user gesture), error
(load failures and submitError) — a curated set of conveniences for the common cases.
They are not the full event surface. Nextgen's event model is open: built-in components
emit more than these (nextPage, fileUploadingStart, rowAdd, …), and any
custom component can this.emit("anyName", payload). Angular @Output()s are static, so they
can never cover that open set. The complete, extensible surface is instance.on(name, handler)
— subscribe to any event by name, including events your own components define:
<formio (ready)="wire($event)"></formio>
wire(form: WebformRootInstance) {
form.on("nextPage", (e) => /* ... */);
form.on("fileUploadingStart", (file) => /* ... */);
form.on("myCustomComponentEvent", (payload) => /* ... */); // your component's own event
}Build a form
<form-builder
[form]="definition"
(change)="save($event.form)"
(saveComponent)="onSave($event)"
></form-builder>Outputs: ready, error, change ({ form }, on any structural edit), and the granular
events addComponent, removeComponent, moveComponent, saveComponent, editComponent,
updateComponent, cancelComponent.
Change detection
The wrapper injects ChangeDetectorRef and calls markForCheck() after each emit, so a
consumer's (change)/(submit) handler that mutates component state refreshes the view —
in both classic zone.js apps and zoneless apps (provideZonelessChangeDetection()).
Migrating from the classic
@formio/angular? That package re-entered the Angular zone (ngZone.run) around each event and layered a large bespoke API (alerts, loader,FormioService,refresh/successemitters,hideComponents, …). This wrapper keeps only the thin surface above; features that lived inFormioBaseComponentare either provided by the renderer or intentionally out of scope. It does not apply classic'srunOutsideAngularCD-storm tuning — if you see excessive change detection, wrap your own handlers inNgZone.runOutsideAngular.
