Skip to content

Commit 941cfdb

Browse files
nicoleoliveirajhosefmarks
authored andcommitted
feat(dynamic-form): adiciona métodos para validação dos fields
Adiciona a propriedade p-validate para validação do formulário e a propriedade validate na interface dos fields para validar o campo de forma individual. Fixes DTHFUI-2414
1 parent 0ef53d7 commit 941cfdb

17 files changed

+2577
-1354
lines changed

projects/ui/src/lib/components/po-dynamic/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
export * from './po-dynamic-field-type.enum';
22
export * from './po-dynamic-form/po-dynamic-form-field.interface';
3+
export * from './po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-field-changed.interface';
4+
export * from './po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-field-validation.interface';
5+
export * from './po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-validation.interface';
36
export * from './po-dynamic-form/po-dynamic-form.component';
47
export * from './po-dynamic-view/po-dynamic-view-field.interface';
58
export * from './po-dynamic-view/po-dynamic-view.component';
Lines changed: 199 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,199 @@
1-
import { EventEmitter, Input, Output } from '@angular/core';
2-
import { NgForm } from '@angular/forms';
3-
4-
import { convertToBoolean } from '../../../utils/util';
5-
6-
import { PoDynamicFormField } from './po-dynamic-form-field.interface';
7-
8-
/**
9-
*
10-
* @description
11-
*
12-
* Componente para criação de formulários dinâmicos a partir de uma lista de objetos.
13-
*
14-
* Também é possível verificar se o formulário está válido e informar valores para a exibição de informações.
15-
*
16-
* > Temos uma ferramenta para criação de formulários, onde é possível inicializá-lo através de um JSON.
17-
* [**Veja aqui**](tools/dynamic-form).
18-
*/
19-
export class PoDynamicFormBaseComponent {
20-
21-
private _groupForm?: boolean = false;
22-
23-
/**
24-
* @optional
25-
*
26-
* @description
27-
*
28-
* Nome da propriedade, atribuída ao `PoDynamicFormField.property`, que iniciará o campo com foco.
29-
*
30-
* > Não é possivel iniciar os componentes abaixo com foco:
31-
* - `po-checkbox-group`
32-
* - `po-combo`
33-
* - `po-radio-group`
34-
* - `po-select`
35-
* - `po-switch`
36-
*/
37-
@Input('p-auto-focus') autoFocus?: string;
38-
39-
/**
40-
* @description
41-
*
42-
* Coleção de objetos que implementam a interface `PoDynamicFormField`, para definição dos campos que serão criados
43-
* dinamicamente.
44-
*
45-
* > Ex: `[ { property: 'name' } ]`
46-
*
47-
* Regras de tipagem e criação dos componentes:
48-
*
49-
* - Caso o *type* informado seja *boolean* o componente criado será o `po-switch`.
50-
* - Caso o *type* informado seja *currency* e não seja informado um *mask* ou *pattern* o componente criado será o `po-decimal`,
51-
* caso seja informado um *mask* ou *pattern* o componente criado será o `po-input`.
52-
* - Caso o *type* informado seja *number* e não seja informado um *mask* ou *pattern* o componente criado será o `po-decimal`, caso seja
53-
* informado um *mask* ou *pattern* o componente criado será o `po-input`.
54-
* - Caso a lista possua a propriedade `options` e a mesma possua até 3 itens o componente criado será o `po-radio-group`
55-
* ou `po-checkbox-group` se informar a propriedade `optionsMulti`.
56-
* - Caso a mesma possua 3 ou mais itens, será criado o componente `po-select` ou, `po-multiselect` se a propriedade `optionsMulti`
57-
* for verdadeira.
58-
* - Caso o *type* informado seja *date* ou *datetime* o componente criado será o `po-datepicker`.
59-
* - Caso seja informado a propriedade `optionsService` o componente criado será o `po-combo`.
60-
* - Caso o *type* informado seja *time* o componente criado será um `po-input` podendo receber um *mask* para formatar
61-
* o valor exibido, caso não seja informado um *mask* o componente será criado com a máscara '99:99' por padrão.
62-
* - Caso a lista possua a propriedade `rows` e esta seja definida com valor maior ou igual a 3 o componente criado será
63-
* o `po-textarea`, caso o valor da propriedade `rows` seja menor que 3 o componente criado será o `po-input`.
64-
* - Caso seja informada a propriedade `secret` o componente criado será o `po-password`.
65-
* - Caso o *type* informado seja *string* o componente criado será o `po-input`.
66-
*
67-
* @default `[]`
68-
*/
69-
@Input('p-fields') fields: Array<PoDynamicFormField>;
70-
71-
/**
72-
* Objeto que será utilizado como valor para exibir as informações, será recuperado e preenchido através do atributo *property*
73-
* dos objetos contidos na propridade `p-fields`.
74-
*
75-
* Pode iniciar com valor ou apenas com um objeto vazio que será preenchido conforme descrito acima.
76-
*
77-
* > Ex: `{ name: 'po' }`
78-
*/
79-
@Input('p-value') value: any;
80-
81-
/**
82-
* @optional
83-
*
84-
* @description
85-
*
86-
* Na inicialização do componente será repassado o objeto de formulário utilizado no componente,
87-
* podendo ser utilizado para validações e/ou detecção de mudança dos valores.
88-
*
89-
* Portanto existem duas maneiras de recuperar o formulário,
90-
* através de *template reference* e através do *output*, veja os exemplos abaixo:
91-
*
92-
* > *template reference*
93-
*
94-
* ```html
95-
* <po-dynamic-form #dynamicForm>
96-
* </po-dynamic-form>
97-
*
98-
* <po-button p-label="Adicionar" [p-disabled]="dynamicForm?.form.invalid">
99-
* </po-button>
100-
*
101-
* ```
102-
*
103-
* > *Output*
104-
*
105-
* ```html
106-
* ...
107-
* <po-dynamic-form (p-form)="getForm($event)">
108-
* </po-dynamic-form>
109-
*
110-
* <po-button p-label="Adicionar" [p-disabled]="dynamicForm?.invalid">
111-
* </po-button>
112-
* ...
113-
*
114-
* ```
115-
*
116-
* ```ts
117-
* ...
118-
*
119-
* export class AppComponent {
120-
*
121-
* dynamicForm: NgForm;
122-
*
123-
* getForm(form: NgForm) {
124-
* this.dynamicForm = form;
125-
* }
126-
*
127-
* }
128-
* ```
129-
*
130-
* > Caso a propriedade `p-group-form` for verdadeira não será repassado o formulário, pois o mesmo utilizará
131-
* o formulário pai.
132-
*/
133-
@Output('p-form') formOutput: EventEmitter<NgForm> = new EventEmitter<NgForm>();
134-
135-
/**
136-
* @optional
137-
*
138-
* @description
139-
* Ao informar esta propriedade, o componente passará a utilizar o formulário pai para criar os `FormControl`
140-
* e com isso é possível recuperar o valor do formulário e suas validações a partir do formulário pai.
141-
*
142-
* ```html
143-
* <form #parentForm="ngForm">
144-
*
145-
* <po-dynamic-form p-group-form [p-fields]="fields"></po-dynamic-form>
146-
*
147-
* <po-button p-label="Adicionar" [p-disabled]="parentForm.invalid"></po-button>
148-
* </form>
149-
* ```
150-
*/
151-
@Input('p-group-form') set groupForm(value: boolean) {
152-
this._groupForm = <any> value === '' ? true : convertToBoolean(value);
153-
}
154-
155-
get groupForm(): boolean {
156-
return this._groupForm;
157-
}
158-
159-
}
1+
import { EventEmitter, Input, Output } from '@angular/core';
2+
import { NgForm } from '@angular/forms';
3+
4+
import { convertToBoolean } from '../../../utils/util';
5+
6+
import { PoDynamicFormField } from './po-dynamic-form-field.interface';
7+
8+
/**
9+
*
10+
* @description
11+
*
12+
* Componente para criação de formulários dinâmicos a partir de uma lista de objetos.
13+
*
14+
* Também é possível verificar se o formulário está válido e informar valores para a exibição de informações.
15+
*
16+
* > Temos uma ferramenta para criação de formulários, onde é possível inicializá-lo através de um JSON.
17+
* [**Veja aqui**](tools/dynamic-form).
18+
*/
19+
export class PoDynamicFormBaseComponent {
20+
21+
private _groupForm?: boolean = false;
22+
23+
/**
24+
* @optional
25+
*
26+
* @description
27+
*
28+
* Nome da propriedade, atribuída ao `PoDynamicFormField.property`, que iniciará o campo com foco.
29+
*
30+
* > Não é possivel iniciar os componentes abaixo com foco:
31+
* - `po-checkbox-group`
32+
* - `po-combo`
33+
* - `po-radio-group`
34+
* - `po-select`
35+
* - `po-switch`
36+
*/
37+
@Input('p-auto-focus') autoFocus?: string;
38+
39+
/**
40+
* @description
41+
*
42+
* Coleção de objetos que implementam a interface `PoDynamicFormField`, para definição dos campos que serão criados
43+
* dinamicamente.
44+
*
45+
* > Ex: `[ { property: 'name' } ]`
46+
*
47+
* Regras de tipagem e criação dos componentes:
48+
*
49+
* - Caso o *type* informado seja *boolean* o componente criado será o `po-switch`.
50+
* - Caso o *type* informado seja *currency* e não seja informado um *mask* ou *pattern* o componente criado será o `po-decimal`,
51+
* caso seja informado um *mask* ou *pattern* o componente criado será o `po-input`.
52+
* - Caso o *type* informado seja *number* e não seja informado um *mask* ou *pattern* o componente criado será o `po-decimal`, caso seja
53+
* informado um *mask* ou *pattern* o componente criado será o `po-input`.
54+
* - Caso a lista possua a propriedade `options` e a mesma possua até 3 itens o componente criado será o `po-radio-group`
55+
* ou `po-checkbox-group` se informar a propriedade `optionsMulti`.
56+
* - Caso a mesma possua 3 ou mais itens, será criado o componente `po-select` ou, `po-multiselect` se a propriedade `optionsMulti`
57+
* for verdadeira.
58+
* - Caso o *type* informado seja *date* ou *datetime* o componente criado será o `po-datepicker`.
59+
* - Caso seja informado a propriedade `optionsService` o componente criado será o `po-combo`.
60+
* - Caso o *type* informado seja *time* o componente criado será um `po-input` podendo receber um *mask* para formatar
61+
* o valor exibido, caso não seja informado um *mask* o componente será criado com a máscara '99:99' por padrão.
62+
* - Caso a lista possua a propriedade `rows` e esta seja definida com valor maior ou igual a 3 o componente criado será
63+
* o `po-textarea`, caso o valor da propriedade `rows` seja menor que 3 o componente criado será o `po-input`.
64+
* - Caso seja informada a propriedade `secret` o componente criado será o `po-password`.
65+
* - Caso o *type* informado seja *string* o componente criado será o `po-input`.
66+
*
67+
* @default `[]`
68+
*/
69+
@Input('p-fields') fields: Array<PoDynamicFormField>;
70+
71+
/**
72+
* Objeto que será utilizado como valor para exibir as informações, será recuperado e preenchido através do atributo *property*
73+
* dos objetos contidos na propridade `p-fields`.
74+
*
75+
* Pode iniciar com valor ou apenas com um objeto vazio que será preenchido conforme descrito acima.
76+
*
77+
* > Ex: `{ name: 'po' }`
78+
*/
79+
@Input('p-value') value: any;
80+
81+
/**
82+
* @optional
83+
*
84+
* @description
85+
*
86+
* Na inicialização do componente será repassado o objeto de formulário utilizado no componente,
87+
* podendo ser utilizado para validações e/ou detecção de mudança dos valores.
88+
*
89+
* Portanto existem duas maneiras de recuperar o formulário,
90+
* através de *template reference* e através do *output*, veja os exemplos abaixo:
91+
*
92+
* > *template reference*
93+
*
94+
* ```html
95+
* <po-dynamic-form #dynamicForm>
96+
* </po-dynamic-form>
97+
*
98+
* <po-button p-label="Adicionar" [p-disabled]="dynamicForm?.form.invalid">
99+
* </po-button>
100+
*
101+
* ```
102+
*
103+
* > *Output*
104+
*
105+
* ```html
106+
* ...
107+
* <po-dynamic-form (p-form)="getForm($event)">
108+
* </po-dynamic-form>
109+
*
110+
* <po-button p-label="Adicionar" [p-disabled]="dynamicForm?.invalid">
111+
* </po-button>
112+
* ...
113+
*
114+
* ```
115+
*
116+
* ```ts
117+
* ...
118+
*
119+
* export class AppComponent {
120+
*
121+
* dynamicForm: NgForm;
122+
*
123+
* getForm(form: NgForm) {
124+
* this.dynamicForm = form;
125+
* }
126+
*
127+
* }
128+
* ```
129+
*
130+
* > Caso a propriedade `p-group-form` for verdadeira não será repassado o formulário, pois o mesmo utilizará
131+
* o formulário pai.
132+
*/
133+
@Output('p-form') formOutput: EventEmitter<NgForm> = new EventEmitter<NgForm>();
134+
135+
/**
136+
* @optional
137+
*
138+
* @description
139+
* Ao informar esta propriedade, o componente passará a utilizar o formulário pai para criar os `FormControl`
140+
* e com isso é possível recuperar o valor do formulário e suas validações a partir do formulário pai.
141+
*
142+
* ```html
143+
* <form #parentForm="ngForm">
144+
*
145+
* <po-dynamic-form p-group-form [p-fields]="fields"></po-dynamic-form>
146+
*
147+
* <po-button p-label="Adicionar" [p-disabled]="parentForm.invalid"></po-button>
148+
* </form>
149+
* ```
150+
*/
151+
@Input('p-group-form') set groupForm(value: boolean) {
152+
this._groupForm = <any> value === '' ? true : convertToBoolean(value);
153+
}
154+
155+
get groupForm(): boolean {
156+
return this._groupForm;
157+
}
158+
159+
/**
160+
* Função ou serviço para validar as **mudanças do formulário**.
161+
*
162+
* A propriedade aceita os seguintes tipos:
163+
* - **String**: Endpoint usado pelo componente para requisição via `POST`.
164+
* - **Function**: Método que será executado.
165+
*
166+
* Ao ser executado, irá receber como parâmetro um objeto com o nome da propriedade
167+
* alterada e o novo valor, conforme a interface `PoDynamicFormFieldChanged`:
168+
*
169+
* ```
170+
* { property: 'property name', value: 'new value' }
171+
* ```
172+
*
173+
* O retorno desta função deve ser do tipo [PoDynamicFormValidation](documentation/po-dynamic-form#po-dynamic-form-validation),
174+
* onde o usuário poderá determinar as novas atualizações dos campos.
175+
* Por exemplo:
176+
*
177+
* ```
178+
* onChangeFields(changeValue): PoDynamicFormValidation {
179+
*
180+
* if (changeValue.property === 'state') {
181+
*
182+
* return {
183+
* value: { city: undefined },
184+
* fields: [
185+
* { property: 'city', options: this.getCity(changeValue.value.state) }
186+
* ],
187+
* focus: 'city'
188+
* };
189+
* }
190+
*
191+
* ```
192+
* Para referenciar a sua função utilize a propriedade `bind`, por exemplo:
193+
* ```
194+
* [p-validate]="this.myFunction.bind(this)"
195+
* ```
196+
*/
197+
@Input('p-validate') validate?: string | Function;
198+
199+
}

0 commit comments

Comments
 (0)