Vicoders Reactive Form
Introduce
- Reactive-Form was built on Angular Reactive Form
- Reactive-Form helps us to build a form with many types of fields faster
Install
- Step 1: Download package form npm
yarn add @vicoders/reactive-form
or
npm install @vicoders/reactive-form
- Step2: Import module (app.module.ts)
;; @ {}
- Step 3: Import style & script (angular.json)
... "styles": ... "node_modules/primeng/resources/themes/nova-light/theme.css" "node_modules/primeng/resources/primeng.min.css" "node_modules/primeicons/primeicons.css" "node_modules/select2/dist/css/select2.min.css" ... "scripts": "node_modules/jquery/dist/jquery.js" "node_modules/select2/dist/js/select2.min.js" ... ...
Use
- Declare an array of selections (app.component.ts)
;...public inputs: any; { let inputs: InputBase<any> = key: 'textbox' label: 'TextBox' classes: 'col-12' group_classes: 'col-12' group: 1 ; thisinputs = inputs; }...
- Show Reactive Form (app.component.html)
......
- Use Reset Form Button (app.component.html)
... ......
- Use CustomSubmit & CustomButton (app.component.html)
... ......
- Get form value (app.component.ts)
... { if formvalid console; } { if formvalid console; } { this;} {}...
Selections
- Each Selection will have its own options, but all of them have default options:
Option | Type | Desciption | Defalut Value |
---|---|---|---|
label | string | label of selector (label: 'label' ) |
' ' |
key | string | key of selector (key: 'key' ) |
' ' |
value | any | value of selector | null |
classes | array | A array of strings, use to add class for selector (classes: ['col-6'] ) |
[ ] |
group | integer | Any selectors that have the same group will be in the same group | null |
group_classes | array | Any class of group (group) | null |
validators | array (ValidatorFn) | A array of object (validators: [ { label: VALIDATOR_REQUIRED, validator: Validators.required, message: 'This field is required' }] ) |
[ ] |
TextBox
Option | Type | Desciption | Defalut Value |
---|---|---|---|
type | string | 'password', 'number', ... | none |
disabled | boolean | false |
- Result data Type: String (example:
'This is my textBox'
)
CheckBox
- Result data Type: Boolean (example:
true || false
)
Radio
Option | Type | Desciption | Defalut Value |
---|---|---|---|
options | object | example: [{ value: 1, label: 'label' }] |
[ ] |
content | html | example: `` | null |
- Result data Type: Value of Object was choosed:
1
Dropdown
Option | Type | Desciption | Defalut Value |
---|---|---|---|
options | object | example: [{ value: 1, label: 'label' }] |
[ ] |
disabled | boolean | false |
- Result data Type: Object (example:
{ label: 'label', value: 1 }
)
DateTimePicker
Option | Type | Desciption | Defalut Value |
---|---|---|---|
showIcon | Boolean | true : display icon, false : undisplay icon |
false |
monthNavigator | Boolean | true : display month navigator, false : undisplay month navigator |
false |
yearNavigator | Boolean | true : display year navigator, false : undisplay year navigator |
false |
yearRange | String | example: '1995:2050' |
'1995:2050' |
showTime | Boolean | true : display time, false : undisplay time |
false |
timeOnly | Boolean | true : display only time, false : undisplay time |
false |
dateFormat | String | example" 'dd/mm/yy' |
'dd/mm/yy' |
disabled | boolean | false |
|
minDate | Date | new Date('month/date/year') // 11/05/2018 |
null |
maxDate | Date | new Date('month/date/year') // 11/10/2018 |
null |
- Result data Type: Date
Dropzone
Option | Type | Desciption | Defalut Value |
---|---|---|---|
message | String | Description of selector | ' ' |
upload_path | String | Name of folder save your file | 'folder' |
acceptedFiles | String | type of files accept upload ('image/*' ) |
* |
maxFilesize | number | Maximum size file upload | 50 |
maxFiles | number | Maximun number of file upload | 0 |
showPreview | Boolean | Display preview content of upload | false |
url | String | Url upload file, example: /api/v1/upload |
' ' |
| paramName | String | Name of param upload file | 'file' |
| resultTransformer | Function | Each Api upload will have a different result structure so you must customize it to push on dropzone, (example: resultTransformer: result => result.data[0].full_path
- data: result of api upload))) |
ListCheckBox
Option | Type | Desciption | Defalut Value |
---|---|---|---|
options | object | example: [{ value: 1, label: 'label' }] |
[ ] |
disable | boolean | false |
- Result data Type: Array value of options (example:
['1', '2']
)
PhoneCode
- Result data Type: Object of phone code & phone number
- Example:
{
code: '+84',
value: '123456789',
alpha2Code: 'VN'
}
Select2
Option | Type | Desciption | Defalut Value |
---|---|---|---|
options | object | example: [{ value: 1, label: 'label' }] |
[ ] |
tags | Boolean | Added a value not in options | false |
placeholder | String | placeholder of select2 | ' ' |
isSelectAll | Boolean | show select all & clear All ? | false |
selectBtnText | string | label of select all btn | 'Select All' |
clearBtnText | Boolean | label of clear all btn | 'Clear All' |
- Result data Type: Array value of options was selected
- Example:
['1', '2']
- Set default value: Each option want set default, need add
selected: true
for this.
{
value: 1,
label: 'label'
selected: true
}
TexBoxMask
Option | Type | Desciption | Defalut Value |
---|---|---|---|
mask | Array | Array of Regex. (example: Mask Date [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/] ) |
[ ] |
valueWithCharacter | Boolean | Get value with Character or none | false |
placeholder | String | Placeholder | ' ' |
guide | Boolean | Show mask when enter Charactor or none | false |
- Result data Type: String with mask or none
- Example:
"07/10/1995"
"07101995"
TinyMce
Option | Type | Desciption | Defalut Value |
---|---|---|---|
height | String | Height of selector | '300' |
plugins | String | Name of plugins you want add to selector. (example: 'print,bold,thin...' ) |
' ' |
UploadFile
Option | Type | Desciption | Defalut Value |
---|---|---|---|
id | number | Id of input control UploadFile | 1 |
uploadPath | String | Name of folder save your file | ' ' |
accept | String | type of files accept upload ('png|jpg|jpeg' ) |
* |
allowMaxSize | number | Maximum size file upload | 2 |
multiple | boolean | true or false |
false |
apiUpload | String | Url upload file, example: /api/v1/upload |
' ' |
paramName | String | Name of param upload file | 'files' |
resultTransformer | Function | Each Api upload will have a different result structure so you must customize it to push on dropzone, (example: resultTransformer: result => result.data[0].full_path - data: result of api upload))) |
TextArea
Option | Type | Desciption | Defalut Value |
---|---|---|---|
rows | Number | Number lines of textarea | 10 |
Province
- 63 provinces & cities of Vietnam
- Result data Type: String (example:
'Thành phố Hà Nội'
)
SelectionByApi
Option | Type | Desciption | Defalut Value |
---|---|---|---|
apiUpload | String | Api used to search or filter 'api/v1/admin/users?search=' |
null |
resultTransformer | Function | Each Api upload will have a different result structure so you must customize it to push on SelectionByApi, (example: resultTransformer: result => result.data - data: result of api upload))) |
|
fieldName | Function | return label by data object | "" |
multiple | boolean | true or false |
false |
lengthToSearch | Number | lenght of character start to filter | 3 |
Block
- Print [HTML] in Form
Option | Type | Desciption | Defalut Value |
---|---|---|---|
classes | array | A array of strings, use to add class for selector (classes: ['col-6'] ) |
[ ] |
group | integer | Any selectors that have the same group will be in the same group | null |
group_classes | array | Any class of group (group) | |
content | Text | `<p><strong>Buon Ngu</strong></p>` |
SingleSelect2
- Use like DropDown
SwitchInput
- result:
true
orfalse
Captcha
Option | Type | Desciption | Defalut Value |
---|---|---|---|
numberOfChar | Number | Number character | 4 |
type | String | 'number' or 'alphabet' or null |
null |
message | String | Message of captcha | 'Captcha not found' |
- Use
......
('captcha' is key of Captcha input in Form)
Update&fill
-
use
support.UpdateInputsValue(inputs, optionsData)
to update options for Dropdown, Radio, ListCheckBox, Select2 -
use
supportUpdateFormValue(input, valuesData)
to fill data for inputs controll -
Full Example (app.component.ts):
...keysChange = 'textbox';public optionsData = dropdown: label: 'Ha Noi' value: 1 label: 'TP - HCM' value: 2 label: 'Da Nang' value: 3 radio: label: 'Nam' value: 'nam' label: 'Nu' value: 'nu' listcheckbox: label: 'Football' value: 1 label: 'Volleyball' value: 2 label: 'Movies' value: 3 label: 'Camping' value: 4 select2: label: 'Football' value: 1 label: 'Volleyball' value: 2 label: 'Movies' value: 3 label: 'Camping' value: 4 singleselect2: label: 'Football' value: 1 label: 'Volleyball' value: 2 label: 'Movies' value: 3 label: 'Camping' value: 4 ; public valuesData: any = dropdown: _ radio: 'nu' listcheckbox: 2 3 select2: 4 1 checkbox: true datetimepicker: uploadfile: 'http://www.tensorflownews.com/wp-content/uploads/2018/09/1_8GVucX9yhnL21KCtcyFDRQ.png' 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTxadr9ykSPoaet-5e7-_YZtueYaRJSvggWtEShh2EJyAjAf5-D' phonecode: code: '84' value: '3684523975' textarea: 'Content' tinymce: '<b>blabla</b>' textboxmask: '07101995' singleselect2: _ selectionbyapi: created_at: '2018-12-18T03:53:00.000Z' email: 'admin@reflaunt.com' id: 2 last_login: '2019-03-28T08:35:08.000Z' status: 0 updated_at: '2019-03-28T08:35:08.000Z' ; { const inputs: InputBase<any> = key: 'textbox11111' label: 'Textbox' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'textbox' label: 'Textbox' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'dropdown' label: 'Dropdown' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'radio' label: 'Radio' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'listcheckbox' label: 'ListCheckBox' classes: 'col-12' group_classes: 'col-12' group: 1 id: 1 key: 'select2' label: 'Select2' classes: 'col-12' group_classes: 'col-12' group: 1 isSelectAll: true key: 'checkbox' label: 'CheckBox' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'datetimepicker' label: 'DateTimePicker' classes: 'col-12' group_classes: 'col-12' group: 1 monthNavigator: true yearNavigator: true yearRange: '1990:2030' key: 'uploadfile' label: 'UploadFile' classes: 'col-12' group_classes: 'col-12' group: 1 accept: 'png|jpg|jpeg' allowMaxSize: 2 apiUpload: '/api/v1/upload' multiple: true resultdata0full_path paramName: 'files' key: 'phonecode' label: 'PhoneCode' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'textarea' label: 'TextArea' classes: 'col-12' group_classes: 'col-12' group: 1 placeholder: 'placeholder of textarea' key: 'tinymce' label: 'TinyMce' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'textboxmask' label: 'TextBoxMask' classes: 'col-12' group_classes: 'col-12' group: 1 mask: /\d/ /\d/ '/' /\d/ /\d/ '/' /\d/ /\d/ /\d/ /\d/ key: 'province' label: 'Province' classes: 'col-12' group_classes: 'col-12' group: 1 key: 'selectionbyapi' label: 'SelectionByApi' classes: 'col-12' group_classes: 'col-12' group: 1 apiUpload: '/api/v1/admin/users?search=' resultdata resultemail multiple: false lengthToSearch: 1 key: 'singleselect2' label: 'Single Select2' classes: 'col-12' group_classes: 'col-12' group: 1 ; thisinputs = inputs; thisinputs = support; thisinputs = support; } ...
Validation
Default Validation
https://angular.io/api/forms/Validators
- Use & Example:
...... ... validators: validator: Validatorsrequired message: 'This field is required' validator: Validators message: 'This field must be a email address' validator: Validators message: 'Minimmum alowed charactes are 6' validator: ValidatorsmaxLength20 message: 'Maximmum alowed charactes are 20' ... ...
Custom Validation
https://angular.io/guide/form-validation#custom-validators
Reactive-Form provide us some default validator
- isEqualValidator('input-key')
- isDifferentValidator('input-key')
- isExistValidator('apiUrl', 'your-message') - 'apiUrl' must return { exist: true } if item exist
...;... ... validators: validator: DefaultValidators message: 'This field not match with input-key ' validator: DefaultValidators message: 'This field must diffrent with input-key' asyncValidators: DefaultValidators ... ...
If you want create a custom validator:
- Step 1: Create new file (example.validators.ts)
... ; { return control: AbstractControl: ValidationErrors | { const value = controlvalue; if value const compareValue = controlrootvalue; if value !== compareValue return notEqual: valid: false value: controlvalue ; return null; }; } : AsyncValidatorFn { return control: AbstractControl: Promise<ValidationErrors | null> | Observable<ValidationErrors | null> /* Your code */ return async { if value /* Your code => result */ if resultexist === true ; ; ; }; ; }...
- Step 2: Use (app.component.ts)
...;... ... validators: validator: message: 'This field not match with input-key ' asyncValidators: ... ...