From b084fd35e2ded06d6869e76b3105c856e1d7355a Mon Sep 17 00:00:00 2001 From: Renaud Michotte Date: Mon, 8 Jun 2020 15:09:06 +0200 Subject: [PATCH] validator : add custom unique validator for complex object. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a custom validator to check if complex object are unique into an array of objects. Comparing to UniqueValidator from ngx-formly, this new validator allows to specify which objects keys should be used to compare if values are unique into an array. Co-Authored-by: Johnny MarieĢthoz Co-Authored-by: Renaud Michotte --- .../src/lib/record/editor/editor.component.ts | 25 +++++++++++++++++++ .../src/lib/record/editor/extensions.ts | 4 +++ 2 files changed, 29 insertions(+) diff --git a/projects/rero/ng-core/src/lib/record/editor/editor.component.ts b/projects/rero/ng-core/src/lib/record/editor/editor.component.ts index 972fe833..ad099508 100644 --- a/projects/rero/ng-core/src/lib/record/editor/editor.component.ts +++ b/projects/rero/ng-core/src/lib/record/editor/editor.component.ts @@ -495,6 +495,31 @@ export class EditorComponent implements OnInit, OnChanges, OnDestroy { }; delete formOptions.validation.validators.valueAlreadyExists; } + // asyncValidators: valueKeysInObject + // This validator is similar to uniqueValidator but only check on some specific fields of array items. + if (formOptions.validation.validators.uniqueValueKeysInObject) { + field.validators = { + uniqueValueKeysInObject: { + expression: (control: FormControl) => { + // if value isn't an array or array contains less than 2 elements, no need to check + if (!(control.value instanceof Array) || control.value.length < 2) { + return true; + } + const keysToKeep = formOptions.validation.validators.uniqueValueKeysInObject.keys; + const uniqueItems = Array.from( + new Set(control.value.map((v: any) => { + const keys = keysToKeep.reduce((acc, elt) => { + acc[elt] = v[elt]; + return acc; + }, {}); + return JSON.stringify(keys); + })), + ); + return uniqueItems.length === control.value.length; + } + } + }; + } // validators: add validator with expressions const validatorsKey = Object.keys(formOptions.validation.validators); validatorsKey.map(validatorKey => { diff --git a/projects/rero/ng-core/src/lib/record/editor/extensions.ts b/projects/rero/ng-core/src/lib/record/editor/extensions.ts index cf2da8ff..82283da6 100644 --- a/projects/rero/ng-core/src/lib/record/editor/extensions.ts +++ b/projects/rero/ng-core/src/lib/record/editor/extensions.ts @@ -121,6 +121,10 @@ export function registerTranslateExtension(translate: TranslateService) { name: 'uniqueItems', message: () => translate.stream(_('should NOT have duplicate items')) }, + { + name: 'uniqueValueKeysInObject', + message: () => translate.stream(_('should NOT have duplicate items')) + }, { name: 'alreadyTaken', message: () => translate.stream(_('the value is already taken'))