mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-11 20:13:07 +00:00
bug fixing
This commit is contained in:
@@ -175,7 +175,7 @@
|
|||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
"head": "View Item",
|
"head": "View Item",
|
||||||
"title": "Item Edit - Item"
|
"title": "Item Edit - View"
|
||||||
},
|
},
|
||||||
"curate": {
|
"curate": {
|
||||||
"head": "Curate",
|
"head": "Curate",
|
||||||
|
@@ -7,19 +7,20 @@
|
|||||||
<div *ngIf="(editable | async)" class="field-container">
|
<div *ngIf="(editable | async)" class="field-container">
|
||||||
<ds-input-suggestions [suggestions]="(metadataFieldSuggestions | async)"
|
<ds-input-suggestions [suggestions]="(metadataFieldSuggestions | async)"
|
||||||
[(ngModel)]="metadata.key"
|
[(ngModel)]="metadata.key"
|
||||||
(submitSuggestion)="update(suggestionControl.control)"
|
(submitSuggestion)="update(suggestionControl)"
|
||||||
(clickSuggestion)="update(suggestionControl.control)"
|
(clickSuggestion)="update(suggestionControl)"
|
||||||
(typeSuggestion)="update(suggestionControl.control)"
|
(typeSuggestion)="update(suggestionControl)"
|
||||||
(blur)="checkValidity(suggestionControl.control)"
|
(dsClickOutside)="checkValidity(suggestionControl)"
|
||||||
(findSuggestions)="findMetadataFieldSuggestions($event)"
|
(findSuggestions)="findMetadataFieldSuggestions($event)"
|
||||||
#suggestionControl="ngModel"
|
#suggestionControl="ngModel"
|
||||||
[dsInListValidator]="metadataFields | async"
|
[dsInListValidator]="metadataFields"
|
||||||
[valid]="(valid | async)"
|
[valid]="(valid | async) !== false"
|
||||||
dsAutoFocus autoFocusSelector=".suggestion_input"
|
dsAutoFocus autoFocusSelector=".suggestion_input"
|
||||||
|
[ngModelOptions]="{standalone: true}"
|
||||||
></ds-input-suggestions>
|
></ds-input-suggestions>
|
||||||
</div>
|
</div>
|
||||||
<small class="text-danger"
|
<small class="text-danger"
|
||||||
*ngIf="!(valid | async)">{{"item.edit.metadata.metadatafield.invalid" | translate}}</small>
|
*ngIf="(valid | async) === false">{{"item.edit.metadata.metadatafield.invalid" | translate}}</small>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="w-100">
|
<td class="w-100">
|
||||||
|
@@ -11,7 +11,7 @@ import { FieldChangeType } from '../../../../core/data/object-updates/object-upd
|
|||||||
import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer';
|
import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer';
|
||||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||||
import { getSucceededRemoteData } from '../../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||||
import { FormControl } from '@angular/forms';
|
import { NgModel } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
// tslint:disable-next-line:component-selector
|
// tslint:disable-next-line:component-selector
|
||||||
@@ -27,14 +27,22 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
|||||||
* The current field, value and state of the metadatum
|
* The current field, value and state of the metadatum
|
||||||
*/
|
*/
|
||||||
@Input() fieldUpdate: FieldUpdate;
|
@Input() fieldUpdate: FieldUpdate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current url of this page
|
* The current url of this page
|
||||||
*/
|
*/
|
||||||
@Input() url: string;
|
@Input() url: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of strings with all metadata field keys available
|
||||||
|
*/
|
||||||
|
@Input() metadataFields: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The metadatum of this field
|
* The metadatum of this field
|
||||||
*/
|
*/
|
||||||
metadata: Metadatum;
|
metadata: Metadatum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits whether or not this field is currently editable
|
* Emits whether or not this field is currently editable
|
||||||
*/
|
*/
|
||||||
@@ -50,11 +58,6 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
|||||||
*/
|
*/
|
||||||
metadataFieldSuggestions: BehaviorSubject<InputSuggestion[]> = new BehaviorSubject([]);
|
metadataFieldSuggestions: BehaviorSubject<InputSuggestion[]> = new BehaviorSubject([]);
|
||||||
|
|
||||||
/**
|
|
||||||
* List of strings with all metadata field keys available
|
|
||||||
*/
|
|
||||||
metadataFields: Observable<string[]>;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private metadataFieldService: RegistryService,
|
private metadataFieldService: RegistryService,
|
||||||
private objectUpdatesService: ObjectUpdatesService,
|
private objectUpdatesService: ObjectUpdatesService,
|
||||||
@@ -67,26 +70,26 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.editable = this.objectUpdatesService.isEditable(this.url, this.metadata.uuid);
|
this.editable = this.objectUpdatesService.isEditable(this.url, this.metadata.uuid);
|
||||||
this.valid = this.objectUpdatesService.isValid(this.url, this.metadata.uuid);
|
this.valid = this.objectUpdatesService.isValid(this.url, this.metadata.uuid);
|
||||||
this.metadataFields = this.findMetadataFields()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a new change update for this field to the object updates service
|
* Sends a new change update for this field to the object updates service
|
||||||
*/
|
*/
|
||||||
update(control?: FormControl) {
|
update(ngModel?: NgModel) {
|
||||||
this.objectUpdatesService.saveChangeFieldUpdate(this.url, this.metadata);
|
this.objectUpdatesService.saveChangeFieldUpdate(this.url, this.metadata);
|
||||||
if (hasValue(control)) {
|
if (hasValue(ngModel)) {
|
||||||
this.checkValidity(control);
|
this.checkValidity(ngModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to check the validity of a form control
|
* Method to check the validity of a form control
|
||||||
* @param control The form control to check
|
* @param ngModel
|
||||||
*/
|
*/
|
||||||
private checkValidity(control: FormControl) {
|
private checkValidity(ngModel: NgModel) {
|
||||||
control.updateValueAndValidity();
|
ngModel.control.setValue(ngModel.viewModel);
|
||||||
this.objectUpdatesService.setValidFieldUpdate(this.url, this.metadata.uuid, control.valid);
|
ngModel.control.updateValueAndValidity();
|
||||||
|
this.objectUpdatesService.setValidFieldUpdate(this.url, this.metadata.uuid, ngModel.control.valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,30 +127,24 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
|||||||
* @param query The query to look for
|
* @param query The query to look for
|
||||||
*/
|
*/
|
||||||
findMetadataFieldSuggestions(query: string): void {
|
findMetadataFieldSuggestions(query: string): void {
|
||||||
this.metadataFieldService.queryMetadataFields(query).pipe(
|
if (isNotEmpty(query)) {
|
||||||
// getSucceededRemoteData(),
|
this.metadataFieldService.queryMetadataFields(query).pipe(
|
||||||
take(1),
|
// getSucceededRemoteData(),
|
||||||
map((data) => data.payload.page)
|
take(1),
|
||||||
).subscribe(
|
map((data) => data.payload.page)
|
||||||
(fields: MetadataField[]) => this.metadataFieldSuggestions.next(
|
).subscribe(
|
||||||
fields.map((field: MetadataField) => {
|
(fields: MetadataField[]) => this.metadataFieldSuggestions.next(
|
||||||
return {
|
fields.map((field: MetadataField) => {
|
||||||
displayValue: field.toString().split('.').join('.​'),
|
return {
|
||||||
value: field.toString()
|
displayValue: field.toString().split('.').join('.​'),
|
||||||
}
|
value: field.toString()
|
||||||
})
|
};
|
||||||
)
|
})
|
||||||
);
|
)
|
||||||
}
|
);
|
||||||
|
} else {
|
||||||
/**
|
this.metadataFieldSuggestions.next([]);
|
||||||
* Method to request all metadata fields and convert them to a list of strings
|
}
|
||||||
*/
|
|
||||||
findMetadataFields(): Observable<string[]> {
|
|
||||||
return this.metadataFieldService.getAllMetadataFields().pipe(
|
|
||||||
getSucceededRemoteData(),
|
|
||||||
take(1),
|
|
||||||
map((remoteData$) => remoteData$.payload.page.map((field: MetadataField) => field.toString())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
<tr *ngFor="let updateValue of ((updates$ | async)| dsObjectValues); trackBy: trackUpdate"
|
<tr *ngFor="let updateValue of ((updates$ | async)| dsObjectValues); trackBy: trackUpdate"
|
||||||
ds-edit-in-place-field
|
ds-edit-in-place-field
|
||||||
[fieldUpdate]="updateValue || {}"
|
[fieldUpdate]="updateValue || {}"
|
||||||
|
[metadataFields]="metadataFields$ | async"
|
||||||
[url]="url"
|
[url]="url"
|
||||||
[ngClass]="{
|
[ngClass]="{
|
||||||
'table-warning': updateValue.changeType === 0,
|
'table-warning': updateValue.changeType === 0,
|
||||||
|
@@ -11,12 +11,14 @@ import {
|
|||||||
Identifiable
|
Identifiable
|
||||||
} from '../../../core/data/object-updates/object-updates.reducer';
|
} from '../../../core/data/object-updates/object-updates.reducer';
|
||||||
import { Metadatum } from '../../../core/shared/metadatum.model';
|
import { Metadatum } from '../../../core/shared/metadatum.model';
|
||||||
import { first, map, switchMap, tap } from 'rxjs/operators';
|
import { first, map, switchMap, take, tap } from 'rxjs/operators';
|
||||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config';
|
import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { RegistryService } from '../../../core/registry/registry.service';
|
||||||
|
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-metadata',
|
selector: 'ds-item-metadata',
|
||||||
@@ -47,6 +49,11 @@ export class ItemMetadataComponent implements OnInit {
|
|||||||
|
|
||||||
private notitifactionPrefix = 'item.edit.metadata.notifications.';
|
private notitifactionPrefix = 'item.edit.metadata.notifications.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observable with a list of strings with all existing metadata field keys
|
||||||
|
*/
|
||||||
|
metadataFields$: Observable<string[]>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private itemService: ItemDataService,
|
private itemService: ItemDataService,
|
||||||
private objectUpdatesService: ObjectUpdatesService,
|
private objectUpdatesService: ObjectUpdatesService,
|
||||||
@@ -54,7 +61,8 @@ export class ItemMetadataComponent implements OnInit {
|
|||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||||
private route: ActivatedRoute
|
private route: ActivatedRoute,
|
||||||
|
private metadataFieldService: RegistryService,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -63,6 +71,7 @@ export class ItemMetadataComponent implements OnInit {
|
|||||||
* Set up and initialize all fields
|
* Set up and initialize all fields
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.metadataFields$ = this.findMetadataFields()
|
||||||
this.route.parent.data.pipe(map((data) => data.item))
|
this.route.parent.data.pipe(map((data) => data.item))
|
||||||
.pipe(
|
.pipe(
|
||||||
first(),
|
first(),
|
||||||
@@ -208,4 +217,14 @@ export class ItemMetadataComponent implements OnInit {
|
|||||||
return this.translateService.instant(this.notitifactionPrefix + key + '.content');
|
return this.translateService.instant(this.notitifactionPrefix + key + '.content');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to request all metadata fields and convert them to a list of strings
|
||||||
|
*/
|
||||||
|
findMetadataFields(): Observable<string[]> {
|
||||||
|
return this.metadataFieldService.getAllMetadataFields().pipe(
|
||||||
|
getSucceededRemoteData(),
|
||||||
|
take(1),
|
||||||
|
map((remoteData$) => remoteData$.payload.page.map((field: MetadataField) => field.toString())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -78,7 +78,7 @@ const initialFieldState = { editable: false, isNew: false, isValid: true };
|
|||||||
/**
|
/**
|
||||||
* Initial state for a newly added field
|
* Initial state for a newly added field
|
||||||
*/
|
*/
|
||||||
const initialNewFieldState = { editable: true, isNew: true, isValid: true };
|
const initialNewFieldState = { editable: true, isNew: true, isValid: undefined };
|
||||||
|
|
||||||
// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`)
|
// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`)
|
||||||
const initialState = Object.create(null);
|
const initialState = Object.create(null);
|
||||||
|
@@ -2,13 +2,12 @@
|
|||||||
[action]="action" (keydown)="onKeydown($event)"
|
[action]="action" (keydown)="onKeydown($event)"
|
||||||
(keydown.arrowdown)="shiftFocusDown($event)"
|
(keydown.arrowdown)="shiftFocusDown($event)"
|
||||||
(keydown.arrowup)="shiftFocusUp($event)" (keydown.esc)="close()"
|
(keydown.arrowup)="shiftFocusUp($event)" (keydown.esc)="close()"
|
||||||
(dsClickOutside)="close()">
|
(dsClickOutside)="close();">
|
||||||
<input #inputField type="text" [(ngModel)]="value" [name]="name"
|
<input #inputField type="text" [(ngModel)]="value" [name]="name"
|
||||||
class="form-control suggestion_input"
|
class="form-control suggestion_input"
|
||||||
[ngClass]="{'is-invalid': !valid}"
|
[ngClass]="{'is-invalid': !valid}"
|
||||||
[dsDebounce]="debounceTime" (onDebounce)="find($event)"
|
[dsDebounce]="debounceTime" (onDebounce)="find($event)"
|
||||||
[placeholder]="placeholder"
|
[placeholder]="placeholder"
|
||||||
(blur)="blur.emit($event);"
|
|
||||||
[ngModelOptions]="{standalone: true}" autocomplete="off"/>
|
[ngModelOptions]="{standalone: true}" autocomplete="off"/>
|
||||||
<input type="submit" class="d-none"/>
|
<input type="submit" class="d-none"/>
|
||||||
<div class="autocomplete dropdown-menu" [ngClass]="{'show': (show | async) && isNotEmpty(suggestions)}">
|
<div class="autocomplete dropdown-menu" [ngClass]="{'show': (show | async) && isNotEmpty(suggestions)}">
|
||||||
|
@@ -85,11 +85,6 @@ export class InputSuggestionsComponent implements ControlValueAccessor, OnChange
|
|||||||
*/
|
*/
|
||||||
@Output() findSuggestions = new EventEmitter();
|
@Output() findSuggestions = new EventEmitter();
|
||||||
|
|
||||||
/**
|
|
||||||
* Emits event when the input field loses focus
|
|
||||||
*/
|
|
||||||
@Output() blur = new EventEmitter();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits true when the list of suggestions should be shown
|
* Emits true when the list of suggestions should be shown
|
||||||
*/
|
*/
|
||||||
@@ -119,9 +114,14 @@ export class InputSuggestionsComponent implements ControlValueAccessor, OnChange
|
|||||||
*/
|
*/
|
||||||
_value: string;
|
_value: string;
|
||||||
|
|
||||||
|
/** Fields needed to add ngModel */
|
||||||
|
@Input() disabled = false;
|
||||||
propagateChange = (_: any) => {
|
propagateChange = (_: any) => {
|
||||||
/* Empty implementation */
|
/* Empty implementation */
|
||||||
};
|
};
|
||||||
|
propagateTouch = (_: any) => {
|
||||||
|
/* Empty implementation */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When any of the inputs change, check if we should still show the suggestions
|
* When any of the inputs change, check if we should still show the suggestions
|
||||||
@@ -214,9 +214,9 @@ export class InputSuggestionsComponent implements ControlValueAccessor, OnChange
|
|||||||
find(data) {
|
find(data) {
|
||||||
if (!this.blockReopen) {
|
if (!this.blockReopen) {
|
||||||
this.findSuggestions.emit(data);
|
this.findSuggestions.emit(data);
|
||||||
|
this.typeSuggestion.emit(data);
|
||||||
}
|
}
|
||||||
this.blockReopen = false;
|
this.blockReopen = false;
|
||||||
this.typeSuggestion.emit(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(data) {
|
onSubmit(data) {
|
||||||
@@ -230,11 +230,11 @@ export class InputSuggestionsComponent implements ControlValueAccessor, OnChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerOnTouched(fn: any): void {
|
registerOnTouched(fn: any): void {
|
||||||
/* no implementation */
|
this.propagateTouch = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
setDisabledState(isDisabled: boolean): void {
|
setDisabledState(isDisabled: boolean): void {
|
||||||
/* no implementation */
|
this.disabled = isDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeValue(value: any): void {
|
writeValue(value: any): void {
|
||||||
|
@@ -14,7 +14,6 @@ export class AutoFocusDirective implements AfterViewInit {
|
|||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
if (isNotEmpty(this.autoFocusSelector)) {
|
if (isNotEmpty(this.autoFocusSelector)) {
|
||||||
return this.el.nativeElement.querySelector(this.autoFocusSelector).focus();
|
return this.el.nativeElement.querySelector(this.autoFocusSelector).focus();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return this.el.nativeElement.focus();
|
return this.el.nativeElement.focus();
|
||||||
}
|
}
|
||||||
|
@@ -16,9 +16,11 @@ export class ClickOutsideDirective {
|
|||||||
constructor(private _elementRef: ElementRef) {
|
constructor(private _elementRef: ElementRef) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('document:click', ['$event.target'])
|
@HostListener('document:click')
|
||||||
public onClick(targetElement) {
|
public onClick() {
|
||||||
const clickedInside = this._elementRef.nativeElement.contains(targetElement);
|
const hostElement = this._elementRef.nativeElement;
|
||||||
|
const focusElement = hostElement.ownerDocument.activeElement;
|
||||||
|
const clickedInside = hostElement.contains(focusElement);
|
||||||
if (!clickedInside) {
|
if (!clickedInside) {
|
||||||
this.dsClickOutside.emit(null);
|
this.dsClickOutside.emit(null);
|
||||||
}
|
}
|
||||||
|
@@ -25,12 +25,6 @@ export class DebounceDirective implements OnInit, OnDestroy {
|
|||||||
@Input()
|
@Input()
|
||||||
public dsDebounce = 500;
|
public dsDebounce = 500;
|
||||||
|
|
||||||
/**
|
|
||||||
* True if no changes have been made to the input field's value
|
|
||||||
*/
|
|
||||||
@Input()
|
|
||||||
private isFirstChange = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subject to unsubscribe from
|
* Subject to unsubscribe from
|
||||||
*/
|
*/
|
||||||
@@ -47,11 +41,9 @@ export class DebounceDirective implements OnInit, OnDestroy {
|
|||||||
this.model.valueChanges.pipe(
|
this.model.valueChanges.pipe(
|
||||||
takeUntil(this.subject),
|
takeUntil(this.subject),
|
||||||
debounceTime(this.dsDebounce),
|
debounceTime(this.dsDebounce),
|
||||||
distinctUntilChanged(),)
|
distinctUntilChanged())
|
||||||
.subscribe((modelValue) => {
|
.subscribe((modelValue) => {
|
||||||
if (this.isFirstChange) {
|
if (this.model.dirty) {
|
||||||
this.isFirstChange = false;
|
|
||||||
} else {
|
|
||||||
this.onDebounce.emit(modelValue);
|
this.onDebounce.emit(modelValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -24,9 +24,6 @@ export class InListValidator implements Validator {
|
|||||||
* @param c The FormControl
|
* @param c The FormControl
|
||||||
*/
|
*/
|
||||||
validate(c: FormControl): ValidationErrors | null {
|
validate(c: FormControl): ValidationErrors | null {
|
||||||
if (this.dsInListValidator !== null) {
|
return inListValidator(this.dsInListValidator)(c);
|
||||||
return inListValidator(this.dsInListValidator)(c);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,17 @@
|
|||||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||||
|
import { isNotEmpty } from '../empty.util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a validator function to check if the control's value is in a given list
|
* Returns a validator function to check if the control's value is in a given list
|
||||||
* @param list The list to look in
|
* @param list The list to look in
|
||||||
*/
|
*/
|
||||||
export function inListValidator(list: string[]): ValidatorFn {
|
export function inListValidator(list: string[]): ValidatorFn {
|
||||||
return (control: AbstractControl): {[key: string]: any} | null => {
|
return (control: AbstractControl): { [key: string]: any } | null => {
|
||||||
const contains = list.indexOf(control.value) > -1;
|
const hasValue = isNotEmpty(control.value);
|
||||||
return contains ? null : {inList: {value: control.value}} };
|
let inList = true;
|
||||||
|
if (isNotEmpty(list)) {
|
||||||
|
inList = list.indexOf(control.value) > -1;
|
||||||
|
}
|
||||||
|
return (hasValue && inList) ? null : { inList: { value: control.value } }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user