ngx-fluent-form
Building dynamic form in Angular with Fluent API.
Features
- Support using Fluent API and JSON.
- Type-safe form configuration.
- Built on top of Angular Reactive Forms.
- Form controls and grid layout based on
ng-zorro-antd
.
Prerequisites
- Angular >= 13.0.0
- ng-zorro-antd >= 13.0.0
Install
npm i ngx-fluent-form
Docs
- For the full API definition, please visit here.
- Online examples, and sample code.
Usage
Import the FluentFormModule
into your module:
import { FluentFormModule } from 'ngx-fluent-form';
@NgModule({
imports: [
FluentFormModule
]
})
export class YourModule { }
Build the form using the Fluent API:
import { date, form, number, text } from 'ngx-fluent-form';
@Component({
template: `
`
})
export class Component {
schema = form(
text('text').label('label').placeholder('placeholder').span(6),
number('number').label('label').placeholder('placeholder').span(3).max(100),
date('date').label('label').placeholder('placeholder').span(6)
);
model = {
text: 'fluent-form',
number: 10,
date: Date.now()
};
}
You can use JSON to build the form:
import { AnyControlOptions } from 'ngx-fluent-form';
@Component(...)
export class Component {
schema: AnyControlOptions[] = [
{ type: 'text', name: 'text', label: 'label', span: 6 }
];
}
You can also mix Fluent API and JSON:
import { AnyControlOptions, number } from 'ngx-fluent-form';
@Component(...)
export class Component {
schema: AnyControlOptions[] = [
{ type: 'text', name: 'text', label: 'label', span: 6 },
number('number').label('label').placeholder('placeholder').span(3).build(),
];
}
For nested forms, you can use the embed
control (supports infinite nesting):
import { date, form, number, text, embed, switcher } from 'ngx-fluent-form';
@Component(...)
export class Component {
schema = form(
text('text').label('label').placeholder('placeholder').span(6),
number('number').label('label').placeholder('placeholder').span(3).max(100),
embed('detail').label('detail').span(24).schema(form(
date('date').label('label').placeholder('placeholder').span(6),
switcher('switch').label('label').span(2),
))
);
model = {
text: 'fluent-form',
number: 10,
detail: {
date: Date.now(),
switch: true
}
};
}
For values that require bidirectional mapping, the mapper
option can be used. For example, the date control expects and will output a Date
object, and we expect a date string from the date control output:
import { date, form } from 'ngx-fluent-form';
@Component(...)
export class Component {
schema = form(
date('date').label('label').placeholder('placeholder').span(6).mapper({
input: (o: string) => new Date(o),
output: (o: Date) => [o.getFullYear(), o.getMonth() + 1, o.getDate()].join('-')
})
);
model = {
date: '2022-2-22'
};
}
For range selection controls, such as the range
control, it will output an array of two elements, and we expect to map the two elements of the array to two properties:
import { form, range } from 'ngx-fluent-form';
@Component(...)
export class Component {
schema = form(
range(['start', 'end']).label('label').span(6),
);
model = {
start: null,
end: null
};
}
For additional property binding or event listening, the property
and listener
options can be used:
import { form, time } from 'ngx-fluent-form';
@Component(...)
export class Component {
schema = form(
time('time').label('label').span(6).property({
nzNowText: 'Now'
}).listener({
nzOpenChange: (event, options) => console.log(event, options)
}),
);
}