-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2918118
commit 6a442d2
Showing
13 changed files
with
584 additions
and
2 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
projects/ng-utils/src/form/array/array-item.directive.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { FormArrayItemDirective } from './array-item.directive'; | ||
|
||
describe('FormArrayItemDirective', () => { | ||
it('should create an instance', () => { | ||
const directive = new FormArrayItemDirective(null, null, null); | ||
expect(directive).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Directive, forwardRef, Inject, OnChanges, OnInit, Optional, Self } from '@angular/core'; | ||
import { | ||
AsyncValidator, AsyncValidatorFn, ControlValueAccessor, NG_ASYNC_VALIDATORS, NG_VALIDATORS, | ||
NG_VALUE_ACCESSOR, NgControl, NgModel, Validator, ValidatorFn | ||
} from '@angular/forms'; | ||
|
||
import { setUpControl } from './form-array-utils'; | ||
|
||
@Directive({ | ||
selector: '[thaArrayItem]', | ||
providers: [ | ||
{provide: NgControl, useExisting: forwardRef(() => FormArrayItemDirective)} | ||
] | ||
}) | ||
export class FormArrayItemDirective extends NgModel implements OnInit, OnChanges { | ||
constructor( | ||
@Optional() @Self() @Inject(NG_VALIDATORS) validators: Array<Validator|ValidatorFn>, | ||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<AsyncValidator|AsyncValidatorFn>, | ||
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[] | ||
) { | ||
super(null, validators, asyncValidators, valueAccessors); | ||
} | ||
|
||
private ['_setUpControl' + '']() { | ||
this['_registered' + ''] = true; | ||
|
||
setUpControl(this.control, this); | ||
} | ||
|
||
public ngOnInit() { | ||
this['_setUpControl' + ''](); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { ControlValueAccessor, FormArray } from '@angular/forms'; | ||
import { noop } from '@thalesrc/js-utils/legacy'; | ||
import { BehaviorSubject, Subject } from 'rxjs'; | ||
import { takeUntil } from 'rxjs/operators'; | ||
|
||
export class ArrayValueAccessor implements ControlValueAccessor { | ||
private onChange: (v: any) => void = noop; | ||
private onTouched = noop; | ||
public array = new FormArray([]); | ||
public destroy$ = new Subject(); | ||
|
||
public statusChanges$ = new BehaviorSubject(this.array); | ||
|
||
constructor() { | ||
this.array.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => { | ||
this.onChange(value); | ||
}); | ||
|
||
this.array.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(status => { | ||
if (status === 'VALID') { | ||
this.array.setErrors(null, {emitEvent: false}); | ||
} else { | ||
this.array.setErrors(this.array.controls.map(({errors}) => errors), {emitEvent: false}); | ||
} | ||
|
||
this.statusChanges$.next(this.array); | ||
}); | ||
} | ||
|
||
public writeValue(value: any) { | ||
value = value || []; | ||
|
||
if (!(value instanceof Array)) { | ||
throw new Error('Value is not an array'); | ||
} | ||
|
||
this.array.setValue((<[]> this.array.value || []).map((v, i) => value[i] || v || null) , {emitEvent: true}); | ||
} | ||
|
||
public registerOnChange(fn: (v: any) => void) { | ||
this.onChange = fn; | ||
} | ||
public registerOnTouched(fn: () => void) { | ||
this.onTouched = fn; | ||
} | ||
|
||
public setDisabledState(disabled: boolean) { | ||
const method = disabled ? 'disable' : 'enable'; | ||
|
||
for (const control of this.array.controls) { | ||
control[method](); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { FormArrayDirective } from './array.directive'; | ||
|
||
describe('FormArrayDirective', () => { | ||
it('should create an instance', () => { | ||
const directive = new FormArrayDirective(null, null, null); | ||
expect(directive).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { | ||
AfterContentInit, ContentChildren, Directive, forwardRef, Host, Inject, Input, OnDestroy, Optional, QueryList, Self | ||
} from '@angular/core'; | ||
import { | ||
AsyncValidator, AsyncValidatorFn, ControlContainer, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgModel, Validator, ValidatorFn | ||
} from '@angular/forms'; | ||
import { Subject } from 'rxjs'; | ||
import { map, startWith, takeUntil } from 'rxjs/operators'; | ||
|
||
import { ArrayValueAccessor } from './array-value-accessor'; | ||
import { FormArrayItemDirective } from './array-item.directive'; | ||
|
||
@Directive({ | ||
selector: '[thaArrayModel]', | ||
providers: [ | ||
{provide: NgControl, useExisting: forwardRef(() => FormArrayDirective)} | ||
] | ||
}) | ||
export class FormArrayDirective extends NgModel implements AfterContentInit, OnDestroy { | ||
private onDestroy$ = new Subject(); | ||
|
||
public valueAccessor: ArrayValueAccessor; | ||
|
||
@ContentChildren(FormArrayItemDirective) | ||
private items: QueryList<FormArrayItemDirective>; | ||
|
||
@Input() | ||
public name: string; | ||
|
||
constructor( | ||
@Optional() @Host() parent: ControlContainer, | ||
@Optional() @Self() @Inject(NG_VALIDATORS) validators: Array<Validator|ValidatorFn>, | ||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<AsyncValidator|AsyncValidatorFn> | ||
) { | ||
super(parent, validators, asyncValidators, [new ArrayValueAccessor()]); | ||
} | ||
|
||
public ngAfterContentInit() { | ||
this.items.changes.pipe(startWith(null), map(() => this.items.toArray()), takeUntil(this.onDestroy$)).subscribe(items => { | ||
this.valueAccessor.array.clear(); | ||
|
||
for (const [index, item] of items.entries()) { | ||
this.valueAccessor.array.insert(index, item.control); | ||
} | ||
}); | ||
|
||
this.valueAccessor.statusChanges$.pipe(takeUntil(this.onDestroy$)).subscribe(array => { | ||
this.control.setErrors(array.errors); | ||
}); | ||
} | ||
|
||
public ngOnDestroy() { | ||
super.ngOnDestroy(); | ||
|
||
this.onDestroy$.next(); | ||
this.onDestroy$.complete(); | ||
|
||
this.valueAccessor.destroy$.next(); | ||
this.valueAccessor.destroy$.complete(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { FormsModule } from '@angular/forms'; | ||
import { FormArrayItemDirective } from './array-item.directive'; | ||
import { FormArrayDirective } from './array.directive'; | ||
|
||
@NgModule({ | ||
declarations: [ | ||
FormArrayDirective, | ||
FormArrayItemDirective, | ||
], | ||
imports: [ | ||
FormsModule | ||
], | ||
exports: [ | ||
FormArrayDirective, | ||
FormArrayItemDirective | ||
] | ||
}) | ||
export class ArrayModule { } |
Oops, something went wrong.