@@ -36,6 +36,7 @@ import { VisibilityType } from './../../../../submission/sections/visibility-typ
3636import { setLayout } from './parser.utils' ;
3737import { ParserOptions } from './parser-options' ;
3838import { ParserType } from './parser-type' ;
39+ import { AbstractControl , ValidatorFn } from '@angular/forms' ;
3940
4041export const SUBMISSION_ID : InjectionToken < string > = new InjectionToken < string > ( 'submissionId' ) ;
4142export const CONFIG_DATA : InjectionToken < FormFieldModel > = new InjectionToken < FormFieldModel > ( 'configData' ) ;
@@ -48,6 +49,28 @@ export const PARSER_OPTIONS: InjectionToken<ParserOptions> = new InjectionToken<
4849 */
4950export const REGEX_FIELD_VALIDATOR = new RegExp ( '(\\/?)(.+)\\1([gimsuy]*)' , 'i' ) ;
5051
52+ /**
53+ * Define custom form validators here
54+ *
55+ * Register them by adding their key to a model's validator property, e.g:
56+ * ```ts
57+ * model.validators = Object.assign({}, model.validators, { notRepeatable: null });
58+ * ```
59+ */
60+ export const CUSTOM_VALIDATORS = new Map < string , ValidatorFn > ( [
61+ [ 'notRepeatable' , notRepeatableValidator ] ,
62+ ] ) ;
63+
64+ export function notRepeatableValidator ( control : AbstractControl ) {
65+ const value = control . value ;
66+ if ( ! Array . isArray ( value ) || value . length < 2 ) {
67+ return null ;
68+ }
69+ return {
70+ notRepeatable : true ,
71+ } ;
72+ }
73+
5174export abstract class FieldParser {
5275
5376 protected fieldId : string ;
@@ -131,7 +154,11 @@ export abstract class FieldParser {
131154 } ,
132155 } ;
133156
134- return new DynamicRowArrayModel ( config , layout ) ;
157+ const model = new DynamicRowArrayModel ( config , layout ) ;
158+ if ( config . notRepeatable ) {
159+ this . addNotRepeatableValidator ( model ) ;
160+ }
161+ return model ;
135162
136163 } else {
137164 const model = this . modelFactory ( this . getInitFieldValue ( ) ) ;
@@ -426,6 +453,17 @@ export abstract class FieldParser {
426453 { required : this . configData . mandatoryMessage } ) ;
427454 }
428455
456+ protected addNotRepeatableValidator ( controlModel ) {
457+ controlModel . validators = Object . assign ( { } , controlModel . validators , { notRepeatable : null } ) ;
458+ controlModel . errorMessages = Object . assign (
459+ { } ,
460+ controlModel . errorMessages ,
461+ {
462+ notRepeatable : 'error.validation.not.repeatable' ,
463+ } ,
464+ ) ;
465+ }
466+
429467 protected setLabel ( controlModel , label = true , labelEmpty = false ) {
430468 if ( label ) {
431469 controlModel . label = ( labelEmpty ) ? ' ' : this . configData . label ;
0 commit comments