-
Notifications
You must be signed in to change notification settings - Fork 556
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): add preset module to enable form config re-use (#3256)
fix #3208
- Loading branch information
Showing
19 changed files
with
502 additions
and
27,200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ module.exports = { | |
'core', | ||
'testing', | ||
'select', | ||
'preset', | ||
'schematics', | ||
'json-schema', | ||
'material', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<form [formGroup]="form"> | ||
<formly-form [model]="model" [fields]="fields" [options]="options" [form]="form"></formly-form> | ||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { Component } from '@angular/core'; | ||
import { FormGroup } from '@angular/forms'; | ||
import { FormlyFormOptions, FormlyFieldConfig } from '@ngx-formly/core'; | ||
|
||
@Component({ | ||
selector: 'formly-app-example', | ||
templateUrl: './app.component.html', | ||
}) | ||
export class AppComponent { | ||
form = new FormGroup({}); | ||
model: any = {}; | ||
options: FormlyFormOptions = {}; | ||
|
||
fields: FormlyFieldConfig[] = [ | ||
{ | ||
type: '#salutation', | ||
}, | ||
{ | ||
type: '#firstName', | ||
}, | ||
{ | ||
type: '#lastName', | ||
props: { | ||
label: 'Last Name!!!!', | ||
required: true, | ||
}, | ||
}, | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { ReactiveFormsModule } from '@angular/forms'; | ||
import { FormlyModule, FORMLY_CONFIG } from '@ngx-formly/core'; | ||
import { FormlyBootstrapModule } from '@ngx-formly/bootstrap'; | ||
import { MatTabsModule } from '@angular/material/tabs'; | ||
|
||
import { AppComponent } from './app.component'; | ||
import { FormlyPresetModule } from 'src/core/preset/src/preset.module'; | ||
import { registerSalutationPreset, SALUTATION_OPTIONS } from './salutation.preset'; | ||
|
||
@NgModule({ | ||
imports: [ | ||
CommonModule, | ||
ReactiveFormsModule, | ||
MatTabsModule, | ||
FormlyBootstrapModule, | ||
FormlyPresetModule, | ||
FormlyModule.forRoot({ | ||
presets: [ | ||
{ | ||
name: 'firstName', | ||
config: { | ||
key: 'firstName', | ||
type: 'input', | ||
props: { | ||
label: 'First Name', | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: 'lastName', | ||
config: { | ||
key: 'lastName', | ||
type: 'input', | ||
props: { | ||
label: 'Last Name', | ||
}, | ||
}, | ||
}, | ||
], | ||
}), | ||
], | ||
declarations: [AppComponent], | ||
providers: [ | ||
{ | ||
provide: SALUTATION_OPTIONS, | ||
useValue: ['Mr.', 'Ms.', 'Dr.', 'Dude'], | ||
}, | ||
{ | ||
provide: FORMLY_CONFIG, | ||
useFactory: registerSalutationPreset, | ||
deps: [SALUTATION_OPTIONS], | ||
multi: true, | ||
}, | ||
], | ||
}) | ||
export class AppModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { RouterModule } from '@angular/router'; | ||
import { SharedModule, ExamplesRouterViewerComponent } from '../../../shared'; | ||
import { AppModule } from './app.module'; | ||
import { AppComponent } from './app.component'; | ||
|
||
@NgModule({ | ||
imports: [ | ||
SharedModule, | ||
AppModule, | ||
RouterModule.forChild([ | ||
{ | ||
path: '', | ||
component: ExamplesRouterViewerComponent, | ||
data: { | ||
examples: [ | ||
{ | ||
title: 'Field Presets', | ||
description: ` | ||
This example demonstrates how to use the <code>preset</code> feature. | ||
The displayed fields are all standard fields that are defined locally and then re-used in the form. | ||
Check out the salutation field to get an idea of how to create smart, self-configuring presets with dependencies. | ||
`, | ||
component: AppComponent, | ||
files: [ | ||
{ | ||
file: 'app.component.html', | ||
content: require('!!highlight-loader?raw=true&lang=html!./app.component.html'), | ||
filecontent: require('!!raw-loader!./app.component.html'), | ||
}, | ||
{ | ||
file: 'app.component.ts', | ||
content: require('!!highlight-loader?raw=true&lang=typescript!./app.component.ts'), | ||
filecontent: require('!!raw-loader!./app.component.ts'), | ||
}, | ||
{ | ||
file: 'app.module.ts', | ||
content: require('!!highlight-loader?raw=true&lang=typescript!./app.module.ts'), | ||
filecontent: require('!!raw-loader!./app.module.ts'), | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
}, | ||
]), | ||
], | ||
}) | ||
export class ConfigModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Inject, Injectable, InjectionToken } from '@angular/core'; | ||
import { ConfigOption, FormlyFieldConfig } from '@ngx-formly/core'; | ||
|
||
export const SALUTATION_OPTIONS = new InjectionToken<string[]>('SALUTATION_OPTIONS'); | ||
|
||
@Injectable() | ||
export class SalutationPresetProvider { | ||
constructor(@Inject(SALUTATION_OPTIONS) private salutationOptions: string[]) {} | ||
getConfiguration(): FormlyFieldConfig { | ||
return { | ||
key: 'salutation', | ||
type: 'select', | ||
props: { | ||
label: 'Salutation', | ||
placeholder: 'Please Select', | ||
options: this.salutationOptions.map((salutation) => ({ label: salutation, value: salutation })), | ||
}, | ||
}; | ||
} | ||
} | ||
|
||
export function registerSalutationPreset(salutationOptions: string[]): ConfigOption { | ||
return { | ||
presets: [ | ||
{ | ||
name: 'salutation', | ||
config: new SalutationPresetProvider(salutationOptions), | ||
}, | ||
], | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Formly Field Presets | ||
With formly templates, wrappers and extensions, it's easy to reuse form logic throughout your app. However, in larger projects, you will often find yourself defining the same things over and over; think of common form fields like email, name or password fields which should be the same throughout your app. | ||
|
||
The `@ngx-formly/core/preset` enables you to define reusable `FormlyFieldConfig`s centrally. | ||
|
||
## Defining a Preset | ||
To define a preset, two steps are necessary: | ||
- Importing the `FormlyPresetModule` | ||
- Providing presets to `FormlyConfig` | ||
|
||
Have a look at the following example which defines a simple `firstName` preset: | ||
|
||
```typescript | ||
@NgModule({ | ||
imports: [ | ||
... | ||
FormlyPresetModule, | ||
FormlyModule.forRoot({ | ||
presets: [ | ||
{ | ||
name: 'firstName', | ||
config: { | ||
key: 'firstName', | ||
type: 'input', | ||
props: { | ||
label: 'First Name', | ||
}, | ||
}, | ||
}, | ||
], | ||
}), | ||
], | ||
}) | ||
export class AppModule {} | ||
|
||
``` | ||
|
||
It is also possible to define more complex presets by using a `FormlyFieldConfigPresetProvider` (which contains only a single `getConfiguration` method). This enables presets that contain dependencies and can be self-configuring. | ||
Refer to [Example: Presets](https://formly.dev/examples/other/presets) to see this behavior in action. | ||
|
||
## Using Presets | ||
After you have defined a preset, it's very easy to use them in your forms. Presets are accessed using so-called *pseudo-types*, which are prefixed with a single `#`: | ||
|
||
```typescript | ||
fieldConfig = [ | ||
... | ||
{ | ||
type: '#firstName' | ||
} | ||
] | ||
``` | ||
|
||
This will substitute all properties with those defined in the preset. | ||
|
||
To reuse fields while overriding only certain properties, simply specify those properties: | ||
|
||
```typescript | ||
fieldConfig = [ | ||
... | ||
{ | ||
type: '#firstName' | ||
props: { | ||
label: 'alternative label' | ||
} | ||
} | ||
] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.