form-dynamic-ajax 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +423 -0
- package/ng-package.json +10 -0
- package/package.json +14 -0
- package/src/lib/form-dynamic-angular.component.css +132 -0
- package/src/lib/form-dynamic-angular.component.html +412 -0
- package/src/lib/form-dynamic-angular.component.spec.ts +23 -0
- package/src/lib/form-dynamic-angular.component.ts +288 -0
- package/src/lib/form-dynamic-angular.module.ts +73 -0
- package/src/public-api.ts +6 -0
- package/tsconfig.lib.json +14 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +14 -0
@@ -0,0 +1,288 @@
|
|
1
|
+
import { FormBuilder, FormGroup, UntypedFormGroup } from '@angular/forms';
|
2
|
+
import { TranslateService } from '@ngx-translate/core';
|
3
|
+
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
4
|
+
export interface ITreeSelectOptions {
|
5
|
+
key: string,
|
6
|
+
label: string,
|
7
|
+
icon: string,
|
8
|
+
children?: ITreeSelectOptions[]
|
9
|
+
}
|
10
|
+
export interface IOptions {
|
11
|
+
description: string,
|
12
|
+
code: number | string
|
13
|
+
}
|
14
|
+
export interface ICols {
|
15
|
+
field: string,
|
16
|
+
header: string
|
17
|
+
}
|
18
|
+
|
19
|
+
export type TTypes =
|
20
|
+
"autocomplete" |
|
21
|
+
"button" |
|
22
|
+
"check-box" |
|
23
|
+
"currency" |
|
24
|
+
"check-box-multi" |
|
25
|
+
"date" |
|
26
|
+
"switch" |
|
27
|
+
"list" |
|
28
|
+
"likert" |
|
29
|
+
"mask" |
|
30
|
+
"multi" |
|
31
|
+
"number" |
|
32
|
+
"password" |
|
33
|
+
"photo" |
|
34
|
+
"radio-button" |
|
35
|
+
"select" |
|
36
|
+
"select-button" |
|
37
|
+
"table" |
|
38
|
+
"text" |
|
39
|
+
"text-area" |
|
40
|
+
"tree-select" |
|
41
|
+
"upload-files" |
|
42
|
+
"editable-table"
|
43
|
+
export interface IForm {
|
44
|
+
id: number | string,
|
45
|
+
label?: string,
|
46
|
+
type: TTypes,
|
47
|
+
col?: string,
|
48
|
+
disabled?: boolean | null,
|
49
|
+
formControl?: string,
|
50
|
+
required?: boolean,
|
51
|
+
placeholder?: string,
|
52
|
+
|
53
|
+
numberOfMonthsDate?: number;
|
54
|
+
selectionMode?: "multiple" | "range" | "single"
|
55
|
+
minDate?: Date,
|
56
|
+
maxDate?: Date,
|
57
|
+
viewDate?: 'month' | 'date',
|
58
|
+
dateFormat?: string
|
59
|
+
timeOnly?: boolean
|
60
|
+
showTime?: boolean,
|
61
|
+
|
62
|
+
maxlength?: number,
|
63
|
+
rowsTextArea?: number,
|
64
|
+
|
65
|
+
mask?: string,
|
66
|
+
unmask?: boolean,
|
67
|
+
|
68
|
+
search?: boolean,
|
69
|
+
options?: IOptions[]
|
70
|
+
treeSelectOptions?: ITreeSelectOptions[],
|
71
|
+
|
72
|
+
buttonClass?: string,
|
73
|
+
iconButton?: string,
|
74
|
+
|
75
|
+
formControlOther?: string,
|
76
|
+
hideLabelTop?: boolean,
|
77
|
+
|
78
|
+
scrollHeight?: string,
|
79
|
+
colsTable?: ICols[],
|
80
|
+
rowsTable?: any[],
|
81
|
+
rowsFooter?: any[],
|
82
|
+
buttonsTable?: IButtonsTable[],
|
83
|
+
|
84
|
+
acceptFiles?: string,
|
85
|
+
msgAcceptFiles?: string,
|
86
|
+
viewNameFile?: boolean,
|
87
|
+
multileFile?: boolean,
|
88
|
+
|
89
|
+
onChange?: Function,
|
90
|
+
onCLick?: Function,
|
91
|
+
onCLear?: Function,
|
92
|
+
onFocusDate?: Function,
|
93
|
+
}
|
94
|
+
export interface IButtonsStandard {
|
95
|
+
type: 'clean' | 'filter' | 'save' | 'cancel',
|
96
|
+
onCLick: Function,
|
97
|
+
styleClass?: string
|
98
|
+
}
|
99
|
+
export interface IButtonsOptional {
|
100
|
+
label: string,
|
101
|
+
onCLick: Function,
|
102
|
+
icon: string,
|
103
|
+
styleClass: string,
|
104
|
+
view?: Function;
|
105
|
+
}
|
106
|
+
|
107
|
+
export interface IButtonsTable {
|
108
|
+
styleClass: string,
|
109
|
+
label: string,
|
110
|
+
icon: string,
|
111
|
+
onCLick: Function
|
112
|
+
}
|
113
|
+
@Component({
|
114
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
115
|
+
selector: 'form-dynamic-angular',
|
116
|
+
templateUrl: 'form-dynamic-angular.component.html',
|
117
|
+
styleUrls: ['form-dynamic-angular.component.css']
|
118
|
+
})
|
119
|
+
|
120
|
+
export class FormDynamicAngularComponent implements OnInit {
|
121
|
+
@Input() title!: string;
|
122
|
+
@Input() subTitle!: string;
|
123
|
+
@Input() validateForm: boolean = false;
|
124
|
+
|
125
|
+
@Input() form: IForm[] = []
|
126
|
+
@Input() control: FormGroup;
|
127
|
+
|
128
|
+
@Input() buttonsStandard: IButtonsStandard[]
|
129
|
+
@Input() buttonsOptional: IButtonsOptional[]
|
130
|
+
|
131
|
+
@Input() files: any[] = [];
|
132
|
+
|
133
|
+
filesView: any[] = [];
|
134
|
+
filteredAutoComplete: any[] = [];
|
135
|
+
|
136
|
+
constructor(
|
137
|
+
public translate: TranslateService,
|
138
|
+
private formBuilder: FormBuilder
|
139
|
+
) {
|
140
|
+
this.control = this.formBuilder.group({});
|
141
|
+
}
|
142
|
+
|
143
|
+
ngOnInit(): void {
|
144
|
+
this.files.map(f => {
|
145
|
+
this.filesView.push({ ...f, type: f.contentType })
|
146
|
+
})
|
147
|
+
|
148
|
+
if (window.location.protocol === "https") {
|
149
|
+
navigator.mediaDevices.getUserMedia({ video: true })
|
150
|
+
.then(function (mediaStream) {
|
151
|
+
const video: HTMLVideoElement | null = document.querySelector('#video');
|
152
|
+
if (video) {
|
153
|
+
video.srcObject = mediaStream;
|
154
|
+
video.play();
|
155
|
+
}
|
156
|
+
})
|
157
|
+
.catch(function (err) { })
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
numberOfMonthsDate(numberOfMonthsDate: number) {
|
162
|
+
return numberOfMonthsDate ?? 1
|
163
|
+
}
|
164
|
+
|
165
|
+
selectionMode(selectionMode: string) {
|
166
|
+
return selectionMode ?? "single"
|
167
|
+
}
|
168
|
+
|
169
|
+
async capturePhoto(fileName: string) {
|
170
|
+
const canvas: HTMLCanvasElement | null = document.querySelector("#canvas");
|
171
|
+
const icon: HTMLButtonElement | null = document.querySelector("#icon-remove");
|
172
|
+
const video: HTMLVideoElement | null = document.querySelector('#video');
|
173
|
+
const button: HTMLButtonElement | null = document.querySelector('#button');
|
174
|
+
|
175
|
+
|
176
|
+
if (canvas && video) {
|
177
|
+
canvas.height = video.videoHeight;
|
178
|
+
canvas.width = video.videoWidth;
|
179
|
+
const context = canvas.getContext('2d');
|
180
|
+
if (context && icon && button) {
|
181
|
+
context.drawImage(video, 0, 0)
|
182
|
+
video.style.display = "none"
|
183
|
+
button.disabled = true
|
184
|
+
canvas.style.display = "block"
|
185
|
+
icon.style.visibility = "visible"
|
186
|
+
|
187
|
+
let aux = {
|
188
|
+
name: "photo user",
|
189
|
+
contentType: "image/png",
|
190
|
+
content: canvas.toDataURL("image/png")
|
191
|
+
};
|
192
|
+
|
193
|
+
this.control.get(fileName)?.setValue(aux);
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
removePhoto() {
|
199
|
+
const canvas: HTMLCanvasElement | null = document.querySelector("#canvas");
|
200
|
+
const icon: HTMLButtonElement | null = document.querySelector("#icon-remove");
|
201
|
+
const video: HTMLVideoElement | null = document.querySelector('#video');
|
202
|
+
const button: HTMLButtonElement | null = document.querySelector('#button');
|
203
|
+
|
204
|
+
if (canvas && video) {
|
205
|
+
const context = canvas.getContext('2d');
|
206
|
+
if (context && icon && button) {
|
207
|
+
video.style.display = "block"
|
208
|
+
button.disabled = false
|
209
|
+
canvas.style.display = "none"
|
210
|
+
icon.style.visibility = "collapse"
|
211
|
+
}
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
getUrl(file: File) {
|
216
|
+
return window.URL.createObjectURL(file)
|
217
|
+
}
|
218
|
+
|
219
|
+
async onSelectFile(fileName: string, event: any, multiple: boolean) {
|
220
|
+
const file = event.target.files
|
221
|
+
// if (!multiple) {
|
222
|
+
// this.filesView = [];
|
223
|
+
// }
|
224
|
+
this.filesView.push(...file);
|
225
|
+
|
226
|
+
const newFIles = file
|
227
|
+
let arr = [];
|
228
|
+
for (const item of newFIles) {
|
229
|
+
let aux = {
|
230
|
+
name: item.name,
|
231
|
+
contentType: item?.type,
|
232
|
+
content: await this.toBase64(item)
|
233
|
+
};
|
234
|
+
arr.push(aux);
|
235
|
+
}
|
236
|
+
this.control.get(fileName)?.setValue(arr);
|
237
|
+
}
|
238
|
+
|
239
|
+
onRemove(event: File, fileName: string) {
|
240
|
+
this.filesView.splice(this.filesView.indexOf(event), 1);
|
241
|
+
var input = document.getElementById('fileInput') as HTMLInputElement
|
242
|
+
if (input) {
|
243
|
+
input.value = ''
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
filterAutoComplete(event: { query: any; }, suggestionsAutoComplete: any) {
|
248
|
+
let filtered: any[] = [];
|
249
|
+
let query = event.query;
|
250
|
+
|
251
|
+
if (suggestionsAutoComplete) {
|
252
|
+
for (let i = 0; i < suggestionsAutoComplete.length; i++) {
|
253
|
+
let dados = suggestionsAutoComplete[i];
|
254
|
+
if (dados.description.toLowerCase().normalize('NFD').replace(/\p{M}/ug, '').indexOf(query.toLowerCase().normalize('NFD').replace(/\p{M}/ug, '')) != -1) {
|
255
|
+
filtered.push(dados);
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
this.filteredAutoComplete = filtered;
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
toBase64 = async (file: File) => {
|
264
|
+
return new Promise((resolve, _) => {
|
265
|
+
const reader = new FileReader();
|
266
|
+
reader.onloadend = () => resolve(reader.result);
|
267
|
+
reader.readAsDataURL(file);
|
268
|
+
});
|
269
|
+
}
|
270
|
+
|
271
|
+
onChange(change?: Function) {
|
272
|
+
if (change) {
|
273
|
+
change()
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
clickCLear(clear?: Function) {
|
278
|
+
if (clear) {
|
279
|
+
clear()
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
onBlur(blur?: Function) {
|
284
|
+
if (blur) {
|
285
|
+
blur()
|
286
|
+
}
|
287
|
+
}
|
288
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import { NgModule } from '@angular/core';
|
2
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
3
|
+
import { BrowserModule } from '@angular/platform-browser'
|
4
|
+
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
5
|
+
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
6
|
+
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
7
|
+
import { ButtonModule } from 'primeng/button';
|
8
|
+
import { DividerModule } from 'primeng/divider';
|
9
|
+
import { DropdownModule } from 'primeng/dropdown';
|
10
|
+
import { CalendarModule } from 'primeng/calendar';
|
11
|
+
import { TreeSelectModule } from 'primeng/treeselect';
|
12
|
+
import { RadioButtonModule } from 'primeng/radiobutton';
|
13
|
+
import { AutoCompleteModule } from 'primeng/autocomplete';
|
14
|
+
import { InputTextModule } from 'primeng/inputtext';
|
15
|
+
import { FormDynamicAngularComponent } from './form-dynamic-angular.component';
|
16
|
+
import { MessageService } from 'primeng/api';
|
17
|
+
import { InputTextareaModule } from 'primeng/inputtextarea';
|
18
|
+
import { CheckboxModule } from 'primeng/checkbox';
|
19
|
+
import { InputSwitchModule } from 'primeng/inputswitch';
|
20
|
+
import { SelectButtonModule } from 'primeng/selectbutton';
|
21
|
+
import { CommonModule } from '@angular/common';
|
22
|
+
import { MultiSelectModule } from 'primeng/multiselect';
|
23
|
+
import { FileUploadModule } from 'primeng/fileupload';
|
24
|
+
import { TableModule } from 'primeng/table';
|
25
|
+
import { PasswordModule } from 'primeng/password';
|
26
|
+
import { InputNumberModule } from 'primeng/inputnumber';
|
27
|
+
import { InputMaskModule } from 'primeng/inputmask';
|
28
|
+
import { OverlayPanelModule } from 'primeng/overlaypanel';
|
29
|
+
|
30
|
+
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
31
|
+
return new TranslateHttpLoader(http);
|
32
|
+
}
|
33
|
+
@NgModule({
|
34
|
+
declarations: [
|
35
|
+
FormDynamicAngularComponent
|
36
|
+
],
|
37
|
+
imports: [
|
38
|
+
InputMaskModule,
|
39
|
+
InputNumberModule,
|
40
|
+
PasswordModule,
|
41
|
+
ButtonModule,
|
42
|
+
TableModule,
|
43
|
+
FileUploadModule,
|
44
|
+
MultiSelectModule,
|
45
|
+
CommonModule,
|
46
|
+
SelectButtonModule,
|
47
|
+
InputSwitchModule,
|
48
|
+
CheckboxModule,
|
49
|
+
InputTextareaModule,
|
50
|
+
InputTextModule,
|
51
|
+
DividerModule,
|
52
|
+
CalendarModule,
|
53
|
+
DropdownModule,
|
54
|
+
TreeSelectModule,
|
55
|
+
RadioButtonModule,
|
56
|
+
AutoCompleteModule,
|
57
|
+
ReactiveFormsModule,
|
58
|
+
HttpClientModule,
|
59
|
+
OverlayPanelModule,
|
60
|
+
TranslateModule.forRoot({
|
61
|
+
loader: {
|
62
|
+
provide: TranslateLoader,
|
63
|
+
useFactory: HttpLoaderFactory,
|
64
|
+
deps: [HttpClient]
|
65
|
+
},
|
66
|
+
})
|
67
|
+
],
|
68
|
+
exports: [
|
69
|
+
FormDynamicAngularComponent
|
70
|
+
]
|
71
|
+
})
|
72
|
+
|
73
|
+
export class FormDynamicAngularModule { }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
2
|
+
{
|
3
|
+
"extends": "../../tsconfig.json",
|
4
|
+
"compilerOptions": {
|
5
|
+
"outDir": "../../out-tsc/lib",
|
6
|
+
"declaration": true,
|
7
|
+
"declarationMap": true,
|
8
|
+
"inlineSources": true,
|
9
|
+
"types": []
|
10
|
+
},
|
11
|
+
"exclude": [
|
12
|
+
"**/*.spec.ts"
|
13
|
+
]
|
14
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
2
|
+
{
|
3
|
+
"extends": "../../tsconfig.json",
|
4
|
+
"compilerOptions": {
|
5
|
+
"outDir": "../../out-tsc/spec",
|
6
|
+
"types": [
|
7
|
+
"jasmine"
|
8
|
+
]
|
9
|
+
},
|
10
|
+
"include": [
|
11
|
+
"**/*.spec.ts",
|
12
|
+
"**/*.d.ts"
|
13
|
+
]
|
14
|
+
}
|