1 | import { Directive, TemplateRef, ViewContainerRef, Input, EventEmitter, Output, forwardRef, SkipSelf, HostListener, SimpleChange, NgModule } from '@angular/core';
|
2 | import { FormControl, FormGroup, FormArray, FormGroupDirective, ControlContainer, FormGroupName, FormArrayName, ReactiveFormsModule } from '@angular/forms';
|
3 | import { BehaviorSubject, Subject } from 'rxjs';
|
4 | import { takeUntil } from 'rxjs/operators';
|
5 | import { CommonModule } from '@angular/common';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | class EclatRecursiveConfig {
|
12 | }
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | var EclatFormUtility;
|
24 | (function (EclatFormUtility) {
|
25 | |
26 |
|
27 |
|
28 |
|
29 |
|
30 | function isEclatFormControlConfig(eclatForm) {
|
31 | if (Array.isArray(eclatForm)) {
|
32 | return true;
|
33 | }
|
34 | return false;
|
35 | }
|
36 | EclatFormUtility.isEclatFormControlConfig = isEclatFormControlConfig;
|
37 | |
38 |
|
39 |
|
40 |
|
41 |
|
42 | function isEclatFormGroupConfig(eclatForm) {
|
43 | if ((( (eclatForm))).controlsRules) {
|
44 | return true;
|
45 | }
|
46 | return false;
|
47 | }
|
48 | EclatFormUtility.isEclatFormGroupConfig = isEclatFormGroupConfig;
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 | function isEclatFormArrayConfig(eclatForm) {
|
55 | if ((( (eclatForm))).controlConfig) {
|
56 | return true;
|
57 | }
|
58 | return false;
|
59 | }
|
60 | EclatFormUtility.isEclatFormArrayConfig = isEclatFormArrayConfig;
|
61 | |
62 |
|
63 |
|
64 |
|
65 |
|
66 | function eclatRecursiveTransformer(data) {
|
67 |
|
68 | const path = recursivePathFinder(data);
|
69 | if (!path) {
|
70 | throw Error();
|
71 | }
|
72 |
|
73 | const paths = path.split('.');
|
74 |
|
75 | const latestPath = ( (paths.pop()));
|
76 | paths.reduce(( |
77 |
|
78 |
|
79 |
|
80 |
|
81 | (acc, cur) => {
|
82 | return acc[cur];
|
83 | }), ( (data)))[latestPath] = data;
|
84 | return ( (data));
|
85 | }
|
86 | EclatFormUtility.eclatRecursiveTransformer = eclatRecursiveTransformer;
|
87 | })(EclatFormUtility || (EclatFormUtility = {}));
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | function recursivePathFinder(data, path = null) {
|
94 | if (data instanceof EclatRecursiveConfig) {
|
95 | return '';
|
96 | }
|
97 | if (Array.isArray(data)) {
|
98 |
|
99 | let found = null;
|
100 | data.some(( |
101 |
|
102 |
|
103 |
|
104 |
|
105 | (value, key) => {
|
106 |
|
107 | const temp = recursivePathFinder(value, path);
|
108 | if (temp !== null) {
|
109 | if (temp) {
|
110 | found = key + '.' + temp;
|
111 | }
|
112 | else {
|
113 | found = key.toString();
|
114 | }
|
115 | }
|
116 | return !!found;
|
117 | }));
|
118 | return found;
|
119 | }
|
120 | if (data === Object(data)) {
|
121 |
|
122 | let found = null;
|
123 | Object.entries(data).some(( |
124 |
|
125 |
|
126 |
|
127 | ([key, value]) => {
|
128 |
|
129 | const temp = recursivePathFinder(value, path);
|
130 | if (temp !== null) {
|
131 | if (temp) {
|
132 | found = key + '.' + temp;
|
133 | }
|
134 | else {
|
135 | found = key;
|
136 | }
|
137 | }
|
138 | return !!found;
|
139 | }));
|
140 | return found;
|
141 | }
|
142 | return null;
|
143 | }
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | class AbstractEclatFormControl {
|
154 | |
155 |
|
156 |
|
157 | constructor(rules) {
|
158 |
|
159 | const validators = [];
|
160 |
|
161 | const asyncValidators = [];
|
162 |
|
163 | const errorMapping = {};
|
164 | if (rules) {
|
165 | rules.forEach(( |
166 |
|
167 |
|
168 |
|
169 | ({ validator, asyncValidator, key, message }) => {
|
170 | errorMapping[key] = message;
|
171 | if (validator) {
|
172 | validators.push(validator);
|
173 | }
|
174 | if (asyncValidator) {
|
175 | asyncValidators.push(asyncValidator);
|
176 | }
|
177 | }));
|
178 | }
|
179 | this.rules = errorMapping;
|
180 | this.validators = validators;
|
181 | this.asyncValidators = asyncValidators;
|
182 | }
|
183 | |
184 |
|
185 |
|
186 | get errorMessages() {
|
187 | if (!this.control.errors) {
|
188 | return [];
|
189 | }
|
190 | return Object.entries(this.control.errors).reduce(( |
191 |
|
192 |
|
193 |
|
194 |
|
195 | (acc, [key, value]) => {
|
196 | if (value) {
|
197 |
|
198 | const temp = this.rules[key];
|
199 |
|
200 | const errors = typeof temp === 'function' ? temp(this) : temp;
|
201 | if (Array.isArray(errors)) {
|
202 | acc.push(...errors);
|
203 | }
|
204 | else {
|
205 | acc.push(errors);
|
206 | }
|
207 | }
|
208 | return acc;
|
209 | }), ( ([])));
|
210 | }
|
211 | |
212 |
|
213 |
|
214 | get value() {
|
215 | return this.control.value;
|
216 | }
|
217 | |
218 |
|
219 |
|
220 | get valid() {
|
221 | return this.control.valid;
|
222 | }
|
223 | |
224 |
|
225 |
|
226 | get valueChanges() {
|
227 | return this.control.valueChanges;
|
228 | }
|
229 | |
230 |
|
231 |
|
232 |
|
233 |
|
234 | disable(isDisabled = true, opts) {
|
235 | if (isDisabled) {
|
236 | this.control.disable(opts);
|
237 | }
|
238 | else {
|
239 | this.control.enable(opts);
|
240 | }
|
241 | }
|
242 | }
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 | function getEclatControl(config, data) {
|
254 | if (EclatFormUtility.isEclatFormControlConfig(config)) {
|
255 | return new EclatFormControl(config, data);
|
256 | }
|
257 | if (EclatFormUtility.isEclatFormGroupConfig(config)) {
|
258 | return new EclatFormGroup(config, data);
|
259 | }
|
260 | if (EclatFormUtility.isEclatFormArrayConfig(config)) {
|
261 | return new EclatFormArray(config, data);
|
262 | }
|
263 | return null;
|
264 | }
|
265 |
|
266 |
|
267 |
|
268 | class EclatFormControl extends AbstractEclatFormControl {
|
269 | |
270 |
|
271 |
|
272 |
|
273 | constructor(config, initialData) {
|
274 | super(config);
|
275 | this.control = new FormControl(null, this.validators, this.asyncValidators);
|
276 | if (initialData) {
|
277 | this.resetState(initialData);
|
278 | }
|
279 | }
|
280 | |
281 |
|
282 |
|
283 |
|
284 |
|
285 | patchState(data, emitEvent = true) {
|
286 | this.control.patchValue(data, { emitEvent });
|
287 | }
|
288 | |
289 |
|
290 |
|
291 |
|
292 |
|
293 | resetState(data, emitEvent = true) {
|
294 | this.control.reset(data, { emitEvent });
|
295 | }
|
296 | }
|
297 |
|
298 |
|
299 |
|
300 | class EclatFormGroup extends AbstractEclatFormControl {
|
301 | |
302 |
|
303 |
|
304 |
|
305 | constructor(dfg, initialData) {
|
306 | super(dfg.rules);
|
307 |
|
308 | const children = {};
|
309 |
|
310 | const controls = {};
|
311 | Object.keys(dfg.controlsRules).forEach(( |
312 |
|
313 |
|
314 |
|
315 | (key) => {
|
316 |
|
317 | const value = dfg.controlsRules[( (key))];
|
318 |
|
319 | const eclatControl = getEclatControl(value);
|
320 | if (eclatControl) {
|
321 | children[key] = eclatControl;
|
322 | controls[key] = eclatControl.control;
|
323 | }
|
324 | }));
|
325 | this.control = new FormGroup(controls, this.validators, this.asyncValidators);
|
326 | this.children = children;
|
327 | if (initialData) {
|
328 | this.resetState(initialData);
|
329 | }
|
330 | }
|
331 | |
332 |
|
333 |
|
334 |
|
335 |
|
336 | patchState(data, emitEvent = true) {
|
337 | if (!data) {
|
338 | console.warn(`Expect an object, but ${data} is given`);
|
339 | return;
|
340 | }
|
341 | Object.entries(data).forEach(( |
342 |
|
343 |
|
344 |
|
345 | ([key, value]) => {
|
346 | if (this.children[( (key))]) {
|
347 | this.children[( (key))].patchState(value, false);
|
348 | }
|
349 | }));
|
350 | this.control.patchValue({}, { emitEvent });
|
351 | }
|
352 | |
353 |
|
354 |
|
355 |
|
356 |
|
357 | resetState(data, emitEvent = true) {
|
358 | if (!data) {
|
359 | console.warn(`Expect an object, but ${data} is given`);
|
360 | return;
|
361 | }
|
362 | Object.entries(data).forEach(( |
363 |
|
364 |
|
365 |
|
366 | ([key, value]) => {
|
367 | if (this.children[( (key))]) {
|
368 | this.children[( (key))].resetState(value, false);
|
369 | }
|
370 | }));
|
371 | this.control.reset(undefined, { emitEvent });
|
372 | }
|
373 | |
374 |
|
375 |
|
376 |
|
377 |
|
378 | getChild(key) {
|
379 | return this.children[key];
|
380 | }
|
381 | |
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 | addChild(key, config, data) {
|
389 |
|
390 | const eclatControl = getEclatControl(config);
|
391 | if (eclatControl) {
|
392 | eclatControl.resetState(data);
|
393 | this.children[key] = ( (eclatControl));
|
394 | this.control.addControl(key, this.children[key].control);
|
395 | }
|
396 | }
|
397 | |
398 |
|
399 |
|
400 |
|
401 |
|
402 | removeChild(key) {
|
403 | delete this.children[key];
|
404 | this.control.removeControl(key);
|
405 | }
|
406 | }
|
407 |
|
408 |
|
409 |
|
410 | class EclatFormArray extends AbstractEclatFormControl {
|
411 | |
412 |
|
413 |
|
414 |
|
415 | constructor(dfa, initialData) {
|
416 | super(dfa.rules);
|
417 | this.control = new FormArray([], this.validators, this.asyncValidators);
|
418 | this.childConfig = dfa.controlConfig;
|
419 | this.children = [];
|
420 | if (initialData) {
|
421 | this.resetState(initialData);
|
422 | }
|
423 | }
|
424 | |
425 |
|
426 |
|
427 |
|
428 | addChild(data) {
|
429 |
|
430 | const eclatControl = getEclatControl(this.childConfig);
|
431 | if (eclatControl) {
|
432 | eclatControl.resetState(data);
|
433 | this.children.push(( (eclatControl)));
|
434 | this.control.push(eclatControl.control);
|
435 | }
|
436 | }
|
437 | |
438 |
|
439 |
|
440 |
|
441 | removeChild(index) {
|
442 | this.children.splice(index, 1);
|
443 | this.control.removeAt(index);
|
444 | }
|
445 | |
446 |
|
447 |
|
448 |
|
449 |
|
450 | patchState(data, emitEvent = true) {
|
451 | if (!data) {
|
452 | console.warn(`Expect an array, but ${data} is given`);
|
453 | return;
|
454 | }
|
455 | this.control.controls = [];
|
456 | this.children = [];
|
457 | data.forEach(( |
458 |
|
459 |
|
460 |
|
461 | d => {
|
462 |
|
463 | const eclatControl = getEclatControl(this.childConfig);
|
464 | if (eclatControl) {
|
465 | eclatControl.patchState(d, false);
|
466 | this.children.push(( (eclatControl)));
|
467 | this.control.push(eclatControl.control);
|
468 | }
|
469 | }));
|
470 | this.control.patchValue([], { emitEvent });
|
471 | }
|
472 | |
473 |
|
474 |
|
475 |
|
476 |
|
477 | resetState(data, emitEvent = true) {
|
478 | if (!data) {
|
479 | console.warn(`Expect an array, but ${data} is given`);
|
480 | return;
|
481 | }
|
482 | this.control.controls = [];
|
483 | this.children = [];
|
484 | data.forEach(( |
485 |
|
486 |
|
487 |
|
488 | d => {
|
489 |
|
490 | const eclatControl = getEclatControl(this.childConfig);
|
491 | if (eclatControl) {
|
492 | eclatControl.resetState(d, false);
|
493 | this.children.push(( (eclatControl)));
|
494 | this.control.push(eclatControl.control);
|
495 | }
|
496 | }));
|
497 | this.control.reset(undefined, { emitEvent });
|
498 | }
|
499 | |
500 |
|
501 |
|
502 |
|
503 | getChild(index) {
|
504 | return this.children[index];
|
505 | }
|
506 | }
|
507 |
|
508 |
|
509 |
|
510 |
|
511 |
|
512 |
|
513 |
|
514 |
|
515 | class EclatFormContext {
|
516 | |
517 |
|
518 |
|
519 | constructor($implicit) {
|
520 | this.$implicit = $implicit;
|
521 | }
|
522 | }
|
523 |
|
524 |
|
525 |
|
526 | class EclatFormOfDirective {
|
527 | |
528 |
|
529 |
|
530 |
|
531 | constructor(templateRef, viewContainer) {
|
532 | this.templateRef = templateRef;
|
533 | this.viewContainer = viewContainer;
|
534 | }
|
535 | |
536 |
|
537 |
|
538 |
|
539 | set eclatFormOf(state) {
|
540 | if (!this.context || !this.latestState || this.latestState.config !== state.config) {
|
541 | this.setContext(getEclatControl(state.config, state.data));
|
542 | }
|
543 | else if (this.latestState.data !== state.data) {
|
544 | this.context.$implicit.resetState(state.data);
|
545 | }
|
546 | this.latestState = state;
|
547 | }
|
548 | |
549 |
|
550 |
|
551 |
|
552 |
|
553 | setContext(control) {
|
554 | if (!control) {
|
555 | throw new Error('control not found');
|
556 | }
|
557 | if (!this.context) {
|
558 | this.context = new EclatFormContext(control);
|
559 | this.viewContainer.createEmbeddedView(this.templateRef, this.context);
|
560 | }
|
561 | else {
|
562 | this.context.$implicit = control;
|
563 | }
|
564 | }
|
565 | }
|
566 | EclatFormOfDirective.decorators = [
|
567 | { type: Directive, args: [{ selector: '[eclatForm][eclatFormOf]' },] }
|
568 | ];
|
569 |
|
570 | EclatFormOfDirective.ctorParameters = () => [
|
571 | { type: TemplateRef },
|
572 | { type: ViewContainerRef }
|
573 | ];
|
574 | EclatFormOfDirective.propDecorators = {
|
575 | eclatFormOf: [{ type: Input }]
|
576 | };
|
577 |
|
578 |
|
579 |
|
580 |
|
581 |
|
582 |
|
583 |
|
584 |
|
585 |
|
586 | class EclatFormContainerDirective {
|
587 | |
588 |
|
589 |
|
590 | constructor() {
|
591 | this._formControl = new BehaviorSubject(undefined);
|
592 | this.onSubmit = new EventEmitter();
|
593 | }
|
594 | |
595 |
|
596 |
|
597 | get formControl() {
|
598 | return this._formControl.getValue();
|
599 | }
|
600 | |
601 |
|
602 |
|
603 | get formControl$() {
|
604 | return this._formControl.asObservable();
|
605 | }
|
606 | |
607 |
|
608 |
|
609 | submit() {
|
610 | if (this.formControl) {
|
611 | this.onSubmit.emit(this.formControl.value);
|
612 | }
|
613 | }
|
614 | }
|
615 | EclatFormContainerDirective.propDecorators = {
|
616 | onSubmit: [{ type: Output }]
|
617 | };
|
618 |
|
619 |
|
620 |
|
621 |
|
622 |
|
623 |
|
624 |
|
625 |
|
626 | class EclatFormErrorContext {
|
627 | |
628 |
|
629 |
|
630 | constructor(control) {
|
631 | this.control = control;
|
632 | }
|
633 | |
634 |
|
635 |
|
636 | get $implicit() {
|
637 | return this.control.errorMessages;
|
638 | }
|
639 | }
|
640 |
|
641 |
|
642 |
|
643 | class EclatFormErrorDirective {
|
644 | |
645 |
|
646 |
|
647 |
|
648 |
|
649 | constructor(templateRef, viewContainer, parent) {
|
650 | this.templateRef = templateRef;
|
651 | this.viewContainer = viewContainer;
|
652 | this.parent = parent;
|
653 | this.onDestroy$ = new Subject();
|
654 | this.errorMatcher = ( |
655 |
|
656 |
|
657 | () => true);
|
658 | }
|
659 | |
660 |
|
661 |
|
662 |
|
663 | set eclatControl(control) {
|
664 | this.setContext(control);
|
665 | }
|
666 | |
667 |
|
668 |
|
669 |
|
670 | set eclatControlName(controlName) {
|
671 | if (!this.parent.formControl) {
|
672 | throw new Error('parent formControl not exist');
|
673 | }
|
674 |
|
675 | const instance = !controlName ? this.parent.formControl : this.parent.formControl.getChild(controlName);
|
676 | if (!instance) {
|
677 | throw new Error('control not found');
|
678 | return;
|
679 | }
|
680 | this.latestControlName = controlName;
|
681 | this.setContext(instance);
|
682 | }
|
683 | |
684 |
|
685 |
|
686 |
|
687 | set eclatFormError(control) {
|
688 | if (control instanceof AbstractEclatFormControl) {
|
689 | this.setContext(control);
|
690 | }
|
691 | else {
|
692 | this.eclatControlName = control;
|
693 | }
|
694 | }
|
695 | |
696 |
|
697 |
|
698 | ngOnInit() {
|
699 | this.parent.formControl$.pipe(takeUntil(this.onDestroy$)).subscribe(( |
700 |
|
701 |
|
702 |
|
703 | (formControl) => {
|
704 | if (formControl && this.latestControlName) {
|
705 | this.eclatFormError = formControl.getChild(this.latestControlName);
|
706 | }
|
707 | }));
|
708 | }
|
709 | |
710 |
|
711 |
|
712 | ngOnDestroy() {
|
713 | this.onDestroy$.next();
|
714 | }
|
715 | |
716 |
|
717 |
|
718 |
|
719 |
|
720 | setContext(control) {
|
721 | if (!this.context) {
|
722 | this.context = new EclatFormErrorContext(control);
|
723 | this.viewContainer.createEmbeddedView(this.templateRef, this.context);
|
724 | }
|
725 | else if (this.context.control !== control) {
|
726 | this.context.control = control;
|
727 | }
|
728 | if (this.valueChangesSub) {
|
729 | this.valueChangesSub.unsubscribe();
|
730 | }
|
731 | this.checkValidity(control);
|
732 | this.valueChangesSub = control.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(( |
733 |
|
734 |
|
735 | () => {
|
736 | this.checkValidity(control);
|
737 | }));
|
738 | }
|
739 | |
740 |
|
741 |
|
742 |
|
743 |
|
744 | checkValidity(control) {
|
745 |
|
746 | const isAttached = !!this.viewContainer.length;
|
747 | if (!control.valid && this.errorMatcher(control)) {
|
748 | if (!isAttached) {
|
749 | this.viewContainer.createEmbeddedView(this.templateRef, this.context);
|
750 | }
|
751 | }
|
752 | else {
|
753 | if (isAttached) {
|
754 | this.viewContainer.remove();
|
755 | }
|
756 | }
|
757 | }
|
758 | }
|
759 | EclatFormErrorDirective.decorators = [
|
760 | { type: Directive, args: [{ selector: '[eclatFormError]' },] }
|
761 | ];
|
762 |
|
763 | EclatFormErrorDirective.ctorParameters = () => [
|
764 | { type: TemplateRef },
|
765 | { type: ViewContainerRef },
|
766 | { type: EclatFormContainerDirective }
|
767 | ];
|
768 | EclatFormErrorDirective.propDecorators = {
|
769 | errorMatcher: [{ type: Input }],
|
770 | eclatControl: [{ type: Input }],
|
771 | eclatControlName: [{ type: Input }],
|
772 | eclatFormError: [{ type: Input }]
|
773 | };
|
774 |
|
775 |
|
776 |
|
777 |
|
778 |
|
779 |
|
780 |
|
781 |
|
782 | class EclatFormGroupDirective extends EclatFormContainerDirective {
|
783 | constructor() {
|
784 | super();
|
785 | }
|
786 | |
787 |
|
788 |
|
789 |
|
790 | set eclatFormGroup(formGroup) {
|
791 | this._formControl.next(formGroup);
|
792 | }
|
793 | |
794 |
|
795 |
|
796 |
|
797 | getChild(key) {
|
798 | if (this.formControl) {
|
799 | return this.formControl.getChild(key);
|
800 | }
|
801 | return undefined;
|
802 | }
|
803 | }
|
804 | EclatFormGroupDirective.decorators = [
|
805 | { type: Directive, args: [{
|
806 | selector: '[eclatFormGroup]',
|
807 | providers: [{
|
808 | provide: EclatFormContainerDirective,
|
809 | useExisting: forwardRef(( |
810 |
|
811 |
|
812 | () => EclatFormGroupDirective)),
|
813 | }],
|
814 | },] }
|
815 | ];
|
816 |
|
817 | EclatFormGroupDirective.ctorParameters = () => [];
|
818 | EclatFormGroupDirective.propDecorators = {
|
819 | eclatFormGroup: [{ type: Input }]
|
820 | };
|
821 |
|
822 |
|
823 |
|
824 |
|
825 |
|
826 |
|
827 |
|
828 |
|
829 | class EclatFormGroupNameDirective extends EclatFormContainerDirective {
|
830 | |
831 |
|
832 |
|
833 | constructor(parent) {
|
834 | super();
|
835 | this.parent = parent;
|
836 | this.onDestroy$ = new Subject();
|
837 | }
|
838 | |
839 |
|
840 |
|
841 |
|
842 | set eclatFormGroupName(name) {
|
843 | this.latestName = name;
|
844 | this._formControl.next(( (this.parent.getChild(name))));
|
845 | }
|
846 | |
847 |
|
848 |
|
849 | ngOnDestroy() {
|
850 | this.onDestroy$.next();
|
851 | }
|
852 | |
853 |
|
854 |
|
855 | ngOnInit() {
|
856 | this.parent.formControl$.pipe(takeUntil(this.onDestroy$)).subscribe(( |
857 |
|
858 |
|
859 | () => {
|
860 | this.eclatFormGroupName = this.latestName;
|
861 | }));
|
862 | }
|
863 | |
864 |
|
865 |
|
866 |
|
867 | getChild(key) {
|
868 | if (this.formControl) {
|
869 | return this.formControl.getChild(key);
|
870 | }
|
871 | return undefined;
|
872 | }
|
873 | }
|
874 | EclatFormGroupNameDirective.decorators = [
|
875 | { type: Directive, args: [{
|
876 | selector: '[eclatFormGroupName]',
|
877 | providers: [{
|
878 | provide: EclatFormContainerDirective,
|
879 | useExisting: forwardRef(( |
880 |
|
881 |
|
882 | () => EclatFormGroupNameDirective)),
|
883 | }],
|
884 | },] }
|
885 | ];
|
886 |
|
887 | EclatFormGroupNameDirective.ctorParameters = () => [
|
888 | { type: EclatFormContainerDirective, decorators: [{ type: SkipSelf }] }
|
889 | ];
|
890 | EclatFormGroupNameDirective.propDecorators = {
|
891 | eclatFormGroupName: [{ type: Input }]
|
892 | };
|
893 |
|
894 |
|
895 |
|
896 |
|
897 |
|
898 |
|
899 |
|
900 |
|
901 | class EclatFormArrayNameDirective extends EclatFormContainerDirective {
|
902 | |
903 |
|
904 |
|
905 | constructor(parent) {
|
906 | super();
|
907 | this.parent = parent;
|
908 | this.onDestroy$ = new Subject();
|
909 | }
|
910 | |
911 |
|
912 |
|
913 |
|
914 | set eclatFormArrayName(name) {
|
915 | this.latestName = name;
|
916 | this._formControl.next(( (this.parent.getChild(name))));
|
917 | }
|
918 | |
919 |
|
920 |
|
921 | ngOnDestroy() {
|
922 | this.onDestroy$.next();
|
923 | }
|
924 | |
925 |
|
926 |
|
927 | ngOnInit() {
|
928 | this.parent.formControl$.pipe(takeUntil(this.onDestroy$)).subscribe(( |
929 |
|
930 |
|
931 | () => {
|
932 | this.eclatFormArrayName = this.latestName;
|
933 | }));
|
934 | }
|
935 | |
936 |
|
937 |
|
938 |
|
939 | getChild(key) {
|
940 | if (this.formControl) {
|
941 | return this.formControl.getChild(key);
|
942 | }
|
943 | return undefined;
|
944 | }
|
945 | }
|
946 | EclatFormArrayNameDirective.decorators = [
|
947 | { type: Directive, args: [{
|
948 | selector: '[eclatFormArrayName]',
|
949 | providers: [{
|
950 | provide: EclatFormContainerDirective,
|
951 | useExisting: forwardRef(( |
952 |
|
953 |
|
954 | () => EclatFormArrayNameDirective)),
|
955 | }],
|
956 | },] }
|
957 | ];
|
958 |
|
959 | EclatFormArrayNameDirective.ctorParameters = () => [
|
960 | { type: EclatFormContainerDirective, decorators: [{ type: SkipSelf }] }
|
961 | ];
|
962 | EclatFormArrayNameDirective.propDecorators = {
|
963 | eclatFormArrayName: [{ type: Input }]
|
964 | };
|
965 |
|
966 |
|
967 |
|
968 |
|
969 |
|
970 |
|
971 |
|
972 |
|
973 | class EclatFormArrayDirective extends EclatFormContainerDirective {
|
974 | constructor() {
|
975 | super();
|
976 | }
|
977 | |
978 |
|
979 |
|
980 |
|
981 | set eclatFormArray(formArray) {
|
982 | this._formControl.next(formArray);
|
983 | }
|
984 | |
985 |
|
986 |
|
987 |
|
988 | getChild(key) {
|
989 | if (this.formControl) {
|
990 | return this.formControl.getChild(key);
|
991 | }
|
992 | return undefined;
|
993 | }
|
994 | }
|
995 | EclatFormArrayDirective.decorators = [
|
996 | { type: Directive, args: [{
|
997 | selector: '[eclatFormArray]',
|
998 | providers: [{
|
999 | provide: EclatFormContainerDirective,
|
1000 | useExisting: forwardRef(( |
1001 |
|
1002 |
|
1003 | () => EclatFormArrayDirective)),
|
1004 | }],
|
1005 | },] }
|
1006 | ];
|
1007 |
|
1008 | EclatFormArrayDirective.ctorParameters = () => [];
|
1009 | EclatFormArrayDirective.propDecorators = {
|
1010 | eclatFormArray: [{ type: Input }]
|
1011 | };
|
1012 |
|
1013 |
|
1014 |
|
1015 |
|
1016 |
|
1017 |
|
1018 |
|
1019 |
|
1020 | class EclatFormArrayChildrenDirective {
|
1021 | |
1022 |
|
1023 |
|
1024 |
|
1025 |
|
1026 | constructor(templateRef, viewContainer, parent) {
|
1027 | this.templateRef = templateRef;
|
1028 | this.viewContainer = viewContainer;
|
1029 | this.parent = parent;
|
1030 | this.onDestroy$ = new Subject();
|
1031 | this.latestChildren = [];
|
1032 | }
|
1033 | |
1034 |
|
1035 |
|
1036 | ngOnDestroy() {
|
1037 | this.onDestroy$.next();
|
1038 | }
|
1039 | |
1040 |
|
1041 |
|
1042 | ngOnInit() {
|
1043 | this.parent.formControl$.pipe(takeUntil(this.onDestroy$)).subscribe(( |
1044 |
|
1045 |
|
1046 |
|
1047 | (formControl) => {
|
1048 | if (formControl) {
|
1049 | if (this.valueChangeSubs) {
|
1050 | this.valueChangeSubs.unsubscribe();
|
1051 | }
|
1052 | this.onChange(formControl);
|
1053 | this.valueChangeSubs = formControl.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(( |
1054 |
|
1055 |
|
1056 | () => {
|
1057 | this.onChange(formControl);
|
1058 | }));
|
1059 | }
|
1060 | }));
|
1061 | }
|
1062 | |
1063 |
|
1064 |
|
1065 |
|
1066 |
|
1067 | onChange(control) {
|
1068 |
|
1069 | const children = [];
|
1070 |
|
1071 | const controlChildrenLength = control.children.length;
|
1072 | control.children.forEach(( |
1073 |
|
1074 |
|
1075 |
|
1076 |
|
1077 | (c, index) => {
|
1078 |
|
1079 | const lastIndex = this.latestChildren.findIndex(( |
1080 |
|
1081 |
|
1082 |
|
1083 | o => o === c));
|
1084 |
|
1085 | const first = index === 0;
|
1086 |
|
1087 | const last = index === (controlChildrenLength - 1);
|
1088 | if (lastIndex < 0) {
|
1089 | this.viewContainer.createEmbeddedView(this.templateRef, { $implicit: index, last, first }, index);
|
1090 | }
|
1091 | else if (lastIndex !== index) {
|
1092 |
|
1093 | const embeddedView = ( (( (this.viewContainer.get(lastIndex)))));
|
1094 | embeddedView.context.$implicit = index;
|
1095 | embeddedView.context.last = last;
|
1096 | embeddedView.context.first = first;
|
1097 | this.viewContainer.move(embeddedView, index);
|
1098 | }
|
1099 | children.push(c);
|
1100 | }));
|
1101 | while (this.viewContainer.length > controlChildrenLength) {
|
1102 | this.viewContainer.remove();
|
1103 | }
|
1104 | this.latestChildren = children;
|
1105 | }
|
1106 | }
|
1107 | EclatFormArrayChildrenDirective.decorators = [
|
1108 | { type: Directive, args: [{
|
1109 | selector: '[eclatFormArrayChildren]',
|
1110 | },] }
|
1111 | ];
|
1112 |
|
1113 | EclatFormArrayChildrenDirective.ctorParameters = () => [
|
1114 | { type: TemplateRef },
|
1115 | { type: ViewContainerRef },
|
1116 | { type: EclatFormContainerDirective }
|
1117 | ];
|
1118 |
|
1119 |
|
1120 |
|
1121 |
|
1122 |
|
1123 | class EclatFormSubmitDirective {
|
1124 | |
1125 |
|
1126 |
|
1127 | constructor(parent) {
|
1128 | this.parent = parent;
|
1129 | }
|
1130 | |
1131 |
|
1132 |
|
1133 | onClick() {
|
1134 | this.parent.submit();
|
1135 | }
|
1136 | }
|
1137 | EclatFormSubmitDirective.decorators = [
|
1138 | { type: Directive, args: [{ selector: '[eclatFormSubmit]' },] }
|
1139 | ];
|
1140 |
|
1141 | EclatFormSubmitDirective.ctorParameters = () => [
|
1142 | { type: EclatFormContainerDirective }
|
1143 | ];
|
1144 | EclatFormSubmitDirective.propDecorators = {
|
1145 | onClick: [{ type: HostListener, args: ['click', ['$event'],] }, { type: HostListener, args: ['tap', ['$event'],] }]
|
1146 | };
|
1147 |
|
1148 |
|
1149 |
|
1150 |
|
1151 |
|
1152 |
|
1153 |
|
1154 |
|
1155 | class EclatFormArrayAddDirective {
|
1156 | |
1157 |
|
1158 |
|
1159 | constructor(parent) {
|
1160 | this.parent = parent;
|
1161 | }
|
1162 | |
1163 |
|
1164 |
|
1165 | onClick() {
|
1166 |
|
1167 | const control = this.parent.formControl;
|
1168 | if (control) {
|
1169 | control.addChild(this.value);
|
1170 | }
|
1171 | }
|
1172 | }
|
1173 | EclatFormArrayAddDirective.decorators = [
|
1174 | { type: Directive, args: [{
|
1175 | selector: '[eclatFormAddChildren]',
|
1176 | },] }
|
1177 | ];
|
1178 |
|
1179 | EclatFormArrayAddDirective.ctorParameters = () => [
|
1180 | { type: EclatFormContainerDirective }
|
1181 | ];
|
1182 | EclatFormArrayAddDirective.propDecorators = {
|
1183 | value: [{ type: Input, args: ['eclatFormAddChildren',] }],
|
1184 | onClick: [{ type: HostListener, args: ['click', ['$event'],] }]
|
1185 | };
|
1186 |
|
1187 |
|
1188 |
|
1189 |
|
1190 |
|
1191 |
|
1192 |
|
1193 |
|
1194 | class EclatFormValueContext {
|
1195 | |
1196 |
|
1197 |
|
1198 | constructor(control) {
|
1199 | this.control = control;
|
1200 | }
|
1201 | |
1202 |
|
1203 |
|
1204 | get $implicit() {
|
1205 | return this.control.value;
|
1206 | }
|
1207 | }
|
1208 |
|
1209 |
|
1210 |
|
1211 | class EclatFormValueDirective {
|
1212 | |
1213 |
|
1214 |
|
1215 |
|
1216 |
|
1217 | constructor(templateRef, viewContainer, parent) {
|
1218 | this.templateRef = templateRef;
|
1219 | this.viewContainer = viewContainer;
|
1220 | this.parent = parent;
|
1221 | this.onDestroy$ = new Subject();
|
1222 | }
|
1223 | |
1224 |
|
1225 |
|
1226 |
|
1227 | set eclatControl(control) {
|
1228 | this.setContext(control);
|
1229 | }
|
1230 | |
1231 |
|
1232 |
|
1233 |
|
1234 | set eclatControlName(controlName) {
|
1235 | if (!this.parent.formControl) {
|
1236 | throw new Error('parent formControl not exist');
|
1237 | }
|
1238 |
|
1239 | const instance = this.parent.formControl.getChild(controlName);
|
1240 | if (!instance) {
|
1241 | throw new Error('control not found');
|
1242 | return;
|
1243 | }
|
1244 | this.latestControlName = controlName;
|
1245 | this.setContext(instance);
|
1246 | }
|
1247 | |
1248 |
|
1249 |
|
1250 |
|
1251 | set eclatFormValue(control) {
|
1252 | if (control instanceof AbstractEclatFormControl) {
|
1253 | this.setContext(control);
|
1254 | }
|
1255 | else if (control || control === 0) {
|
1256 | this.eclatControlName = control;
|
1257 | }
|
1258 | }
|
1259 | |
1260 |
|
1261 |
|
1262 | ngOnInit() {
|
1263 | this.parent.formControl$.pipe(takeUntil(this.onDestroy$)).subscribe(( |
1264 |
|
1265 |
|
1266 |
|
1267 | (formControl) => {
|
1268 | if (formControl && this.latestControlName) {
|
1269 | this.eclatFormValue = formControl.getChild(this.latestControlName);
|
1270 | }
|
1271 | }));
|
1272 | }
|
1273 | |
1274 |
|
1275 |
|
1276 | ngOnDestroy() {
|
1277 | this.onDestroy$.next();
|
1278 | }
|
1279 | |
1280 |
|
1281 |
|
1282 |
|
1283 |
|
1284 | setContext(control) {
|
1285 | if (!this.context) {
|
1286 | this.context = new EclatFormValueContext(control);
|
1287 | this.viewContainer.createEmbeddedView(this.templateRef, this.context);
|
1288 | }
|
1289 | else if (this.context.control !== control) {
|
1290 | this.context.control = control;
|
1291 | }
|
1292 | }
|
1293 | }
|
1294 | EclatFormValueDirective.decorators = [
|
1295 | { type: Directive, args: [{ selector: '[eclatFormValue]' },] }
|
1296 | ];
|
1297 |
|
1298 | EclatFormValueDirective.ctorParameters = () => [
|
1299 | { type: TemplateRef },
|
1300 | { type: ViewContainerRef },
|
1301 | { type: EclatFormContainerDirective }
|
1302 | ];
|
1303 | EclatFormValueDirective.propDecorators = {
|
1304 | eclatControl: [{ type: Input }],
|
1305 | eclatControlName: [{ type: Input }],
|
1306 | eclatFormValue: [{ type: Input }]
|
1307 | };
|
1308 |
|
1309 |
|
1310 |
|
1311 |
|
1312 |
|
1313 |
|
1314 |
|
1315 |
|
1316 | class EclatFormGroupBinderDirective extends FormGroupDirective {
|
1317 | |
1318 |
|
1319 |
|
1320 |
|
1321 | set eclatFormGroup(formGroup) {
|
1322 | this.form = formGroup.control;
|
1323 | }
|
1324 | |
1325 |
|
1326 |
|
1327 |
|
1328 | ngOnChanges(changes) {
|
1329 |
|
1330 | const eclatFormGroupChanges = changes.eclatFormGroup;
|
1331 | if (eclatFormGroupChanges) {
|
1332 |
|
1333 | const prevValue = eclatFormGroupChanges.previousValue ? eclatFormGroupChanges.previousValue.control : undefined;
|
1334 |
|
1335 | const currentValue = eclatFormGroupChanges.currentValue.control;
|
1336 |
|
1337 | const firstChange = eclatFormGroupChanges.firstChange;
|
1338 | super.ngOnChanges({ form: new SimpleChange(prevValue, currentValue, firstChange) });
|
1339 | }
|
1340 | }
|
1341 | }
|
1342 | EclatFormGroupBinderDirective.decorators = [
|
1343 | { type: Directive, args: [{
|
1344 | selector: '[eclatFormGroup]',
|
1345 | providers: [{
|
1346 | provide: ControlContainer,
|
1347 | useExisting: forwardRef(( |
1348 |
|
1349 |
|
1350 | () => EclatFormGroupBinderDirective)),
|
1351 | }],
|
1352 | },] }
|
1353 | ];
|
1354 | EclatFormGroupBinderDirective.propDecorators = {
|
1355 | eclatFormGroup: [{ type: Input }]
|
1356 | };
|
1357 |
|
1358 |
|
1359 |
|
1360 |
|
1361 |
|
1362 |
|
1363 |
|
1364 |
|
1365 | class EclatFormGroupNameBinderDirective extends FormGroupName {
|
1366 | |
1367 |
|
1368 |
|
1369 |
|
1370 | set eclatFormGroupName(name) {
|
1371 | this.name = name;
|
1372 | }
|
1373 | }
|
1374 | EclatFormGroupNameBinderDirective.decorators = [
|
1375 | { type: Directive, args: [{
|
1376 | selector: '[eclatFormGroupName]',
|
1377 | providers: [{
|
1378 | provide: ControlContainer,
|
1379 | useExisting: forwardRef(( |
1380 |
|
1381 |
|
1382 | () => EclatFormGroupNameBinderDirective)),
|
1383 | }],
|
1384 | },] }
|
1385 | ];
|
1386 | EclatFormGroupNameBinderDirective.propDecorators = {
|
1387 | eclatFormGroupName: [{ type: Input }]
|
1388 | };
|
1389 |
|
1390 |
|
1391 |
|
1392 |
|
1393 |
|
1394 |
|
1395 |
|
1396 |
|
1397 | class EclatFormArrayNameBinderDirective extends FormArrayName {
|
1398 | |
1399 |
|
1400 |
|
1401 |
|
1402 | set eclatFormArrayName(name) {
|
1403 | this.name = name;
|
1404 | }
|
1405 | }
|
1406 | EclatFormArrayNameBinderDirective.decorators = [
|
1407 | { type: Directive, args: [{
|
1408 | selector: '[eclatFormArrayName]',
|
1409 | providers: [{
|
1410 | provide: ControlContainer,
|
1411 | useExisting: forwardRef(( |
1412 |
|
1413 |
|
1414 | () => EclatFormArrayNameBinderDirective)),
|
1415 | }],
|
1416 | },] }
|
1417 | ];
|
1418 | EclatFormArrayNameBinderDirective.propDecorators = {
|
1419 | eclatFormArrayName: [{ type: Input }]
|
1420 | };
|
1421 |
|
1422 |
|
1423 |
|
1424 |
|
1425 |
|
1426 |
|
1427 |
|
1428 |
|
1429 | class EclatFormArrayRemoveDirective {
|
1430 | |
1431 |
|
1432 |
|
1433 | constructor(parent) {
|
1434 | this.parent = parent;
|
1435 | }
|
1436 | |
1437 |
|
1438 |
|
1439 | onClick() {
|
1440 |
|
1441 | const control = this.parent.formControl;
|
1442 | if (control) {
|
1443 | control.removeChild(this.index);
|
1444 | }
|
1445 | }
|
1446 | }
|
1447 | EclatFormArrayRemoveDirective.decorators = [
|
1448 | { type: Directive, args: [{
|
1449 | selector: '[eclatFormRemoveChildren]',
|
1450 | },] }
|
1451 | ];
|
1452 |
|
1453 | EclatFormArrayRemoveDirective.ctorParameters = () => [
|
1454 | { type: EclatFormContainerDirective }
|
1455 | ];
|
1456 | EclatFormArrayRemoveDirective.propDecorators = {
|
1457 | index: [{ type: Input, args: ['eclatFormRemoveChildren',] }],
|
1458 | onClick: [{ type: HostListener, args: ['click', ['$event'],] }]
|
1459 | };
|
1460 |
|
1461 |
|
1462 |
|
1463 |
|
1464 |
|
1465 | class EclatFormModule {
|
1466 | }
|
1467 | EclatFormModule.decorators = [
|
1468 | { type: NgModule, args: [{
|
1469 | imports: [CommonModule, ReactiveFormsModule],
|
1470 | declarations: [EclatFormOfDirective, EclatFormErrorDirective, EclatFormGroupDirective, EclatFormGroupNameDirective, EclatFormArrayDirective, EclatFormArrayNameDirective, EclatFormArrayChildrenDirective, EclatFormSubmitDirective, EclatFormArrayAddDirective, EclatFormValueDirective, EclatFormGroupBinderDirective, EclatFormGroupNameBinderDirective, EclatFormArrayNameBinderDirective, EclatFormArrayRemoveDirective],
|
1471 | exports: [CommonModule, ReactiveFormsModule, EclatFormOfDirective, EclatFormErrorDirective, EclatFormGroupDirective, EclatFormGroupNameDirective, EclatFormArrayDirective, EclatFormArrayNameDirective, EclatFormArrayChildrenDirective, EclatFormSubmitDirective, EclatFormArrayAddDirective, EclatFormValueDirective, EclatFormGroupBinderDirective, EclatFormGroupNameBinderDirective, EclatFormArrayNameBinderDirective, EclatFormArrayRemoveDirective],
|
1472 | },] }
|
1473 | ];
|
1474 |
|
1475 |
|
1476 |
|
1477 |
|
1478 |
|
1479 |
|
1480 |
|
1481 |
|
1482 |
|
1483 |
|
1484 |
|
1485 | export { AbstractEclatFormControl, EclatFormArray, EclatFormContext, EclatFormControl, EclatFormErrorDirective, EclatFormGroup, EclatFormGroupDirective, EclatFormModule, EclatFormOfDirective, EclatFormUtility, EclatRecursiveConfig, getEclatControl, EclatFormContainerDirective as ɵa, EclatFormGroupNameDirective as ɵb, EclatFormArrayDirective as ɵc, EclatFormArrayNameDirective as ɵd, EclatFormArrayChildrenDirective as ɵe, EclatFormSubmitDirective as ɵf, EclatFormArrayAddDirective as ɵg, EclatFormValueDirective as ɵh, EclatFormGroupBinderDirective as ɵi, EclatFormGroupNameBinderDirective as ɵj, EclatFormArrayNameBinderDirective as ɵk, EclatFormArrayRemoveDirective as ɵl };
|
1486 |
|