Formly Playground is a project with list of Angular Formly exercises. Every next exercise add new feature to the previous one.
The purpose of the project is to build applications form using Angular Formly, which could support requests to Concierge.
Why Angular Formly? From the fist moment it's clear that the form will contain many options and questions. On the main Formly page you can read "The formly-form
Component and the FormlyConfig
service are very powerful and bring unmatched maintainability to your applications forms", so why not check if it's true.
Application setup
- generate application with Angular CLI
- install Ngx Formly
- use one of UI library in our project, in this project Material2 was used
- to app.module.ts import the FormlyModule and UI (pre-defined types/templates)
- check if app works - run
ng serve
dev server and navigate tohttp://localhost:4200/
home component
was created as navigation page to each exerciseangular-material.imports.ts
module was added to collect all Angular Material imports in one shared module- to import all exercises components with a single statement
index.ts
file was created - in
app.component.html
file, fixed app-header was added
Request to Concierge should be divided into sections:
- Order Identification
- Shoppings
- Additional Comments
- Statements
Component Card should be used as section layout. Add Order Identification card.
- generate component
exercise-one
- read documentation custom-formly-wrapper
- in
shared\custom-wrappers
folder create componentcard-wrapper
- in
app.module.ts
register new custom wrapper as a wrapper - in component
exercise-one
create "Order Identification" Card usingcard-wrapper
- check if app works
- in file
app-routing.module.ts
route to component was added - to import all custom wrappers with a single statement
index.ts
file was created
Below you can find screen of component after adding some custom style.
Add other sections and add questions to each section. In section Shopping user should be able to add and remove shopping items.
- generate component
exercise-two
- copy code from component
exercise-one
- add: Shoppings, Additional Comments, Statements sections - use
card-wrapper
created in exercise one - read documentation ui material guide
- in
shared\model
folder add ts files with model - in
shared\services
folder addrequest.service.ts
withsaveRequest
method to simulate connection to api - in
shared\services
folder adddict.service.ts
withgetDictionaryItems
method to simulate connection to api - add some fields to each section in component
exercies-two
(use different types of fields) - read documentation repeating-section
- in
shared\custom-types
folder create componentrepeat-section
- in
app.module.ts
register newrepeat-section
as a type - in component
exercies-two
in section Shoppings userepeat-section
- check if app works
- in file
app-routing.module.ts
route to component was added - to import all custom types with a single statement
index.ts
file was created
Below you can find screen of component after adding some questions and custom style
Add validation to fields, use global and custom validations
- generate component
exercise-three
- copy code from component
exercise-two
- read documentation built-in validations
- add global validations to
app.module.ts
- in component ts file add some custom validations
In this project
- in file
app-routing.module.ts
route to component was added - in exercise seven approach to global validation was changed - go to exercise seven to see it
- in field
cardId
async validator was used - in field
email
validation message to attribute pattern was added
Add new section Services (use repeat-section
). Section Services should be visible when order type = SERVICES. Section Shoppings should be visible when order type = SHOPPINGS.
Change order type
field in custom type filed. Replace "boring" select by "fanyc" radio buttons images.
- generate component
exercise-four
- copy code from component
exercise-three
- in
shared\model
folder add ts files with model - add: Services sections - use
card-wrapper
created in exercise one - in section Services use
repeat-section
created in exercise two - in
shared\custom-types
folder create componentimg-radio-type
- in
app.module.ts
register newimg-radio-type
as a type - in component
exercies-four
replace type in filedorderType
by a new created type - check if app works
- in file
app-routing.module.ts
route to component was added - in section Shoppings and Services Flex - Layout was used
Below you can find screen of component after adding new section, custom radio btn and custom styles
Request form is to long to one screen, change form layout to stepper.
- generate component
exercise-five
- copy code from component
exercise-four
- read documentation multi-step-form
- remember to import
MatStepperModule
from@angular/material/stepper
- in component
exercies-five
add multi-step-form (you have to make changes in html and ts files) - check if app works
- in file
app-routing.module.ts
route to component was added
Below you can find screen of component with stepper and custom styles
Add translation module to project, and use it in request form.
- install ngx-translate
- read documentation i18n
- in
scr\assets\translations
folder add json files with translations (in this project there are to files en.json and pl.json) - in
shared\services\i18n
folder addtranslation-loader.service.ts
withloadTranslations
method to load translations files - in
shared\services\i18n
folder addlanguage.service.ts
withgetCurrentLanguage
method to set up selected language - in this project
translationLoader
is initialized inhome component
- in component
exercise-six
injectTranslateService
and now it is possible to use translation service, useinstant
method to load translations e.g.label: this.translate.instant('RequestToConcierge.orderIdentification')
- add new method
getDictionaryItemsWithTranslations
indict.service.ts
(service was added in ex two) - in component
exercise-six
in fieldorderTypes
load dictionary items with translations - check if app works
- in file
app-routing.module.ts
route to component was added validations.loader
was added in exercise seven
Below you can find screen of component with translations in action
Add translation to global validation. Component ts file is to long and e.g code to Price range fields repeats itself, refactor code.
- to load global validation you need to use FormlyConfig service by calling addValidatorMessage
- in
shared\services
folder addvalidations.loader.ts
withinit
method - in this project
validationsLoader
is initialized inhome component
- in model
PriceRange.ts
addformField
method, type ofFormlyFieldConfig[]
it should return fields config (the same as in component ts) e.g
formField(translations: TranslateService): FormlyFieldConfig[] {
return [
{
className: 'flex-2',
key: 'from',
type: 'input',
templateOptions: {
type: 'number',
label: translations.instant('RequestToConcierge.priceRangeForm'),
min: 1,
max: 999999,
required: true
},
},
{
className: 'flex-2',
key: 'to',
type: 'input',
templateOptions: {
type: 'number',
label: translations.instant('RequestToConcierge.priceRangeTo'),
min: 1,
max: 999999,
required: true,
},
}
];
}
- similar
formField
methods were created inService.ts
andShopping.ts
- new methods can be now use in other components eg.
fieldArray: {
fieldGroup: this.shoppingModel.formField(this.translate)
},
- check if app works
This project was generated with Angular CLI version 7.3.8.
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The app will automatically reload if you change any of the source files.
Run ng generate component component-name
to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module
.
Run ng build
to build the project. The build artifacts will be stored in the dist/
directory. Use the --prod
flag for a production build.