diff --git a/config/config.example.yml b/config/config.example.yml index c3dc673b537..ca3737122ce 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -234,6 +234,8 @@ submission: - value: default style: text-muted icon: fa-circle-xmark + # Whether to show submission form errors 'onload' or 'onblur' + showErrorStrategy: onblur # Fallback language in which the UI will be rendered if the user's browser language is not an active language fallbackLanguage: en diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index 7097d63867e..a30be2acf49 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -7,6 +7,7 @@ import { OnDestroy, SimpleChanges, } from '@angular/core'; +import { AbstractControl } from '@angular/forms'; import { AuthService } from '@dspace/core/auth/auth.service'; import { SubmissionDefinitionsModel } from '@dspace/core/config/models/config-submission-definitions.model'; import { SubmissionSectionModel } from '@dspace/core/config/models/config-submission-section.model'; @@ -24,6 +25,11 @@ import { isNotEmpty, isNotUndefined, } from '@dspace/shared/utils/empty.util'; +import { + DYNAMIC_ERROR_MESSAGES_MATCHER, + DynamicFormControlModel, + DynamicFormValidationService, +} from '@ng-dynamic-forms/core'; import { TranslatePipe } from '@ngx-translate/core'; import isEqual from 'lodash/isEqual'; import { @@ -38,6 +44,7 @@ import { switchMap, } from 'rxjs/operators'; +import { environment } from '../../../environments/environment'; import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component'; import { UploaderOptions } from '../../shared/upload/uploader/uploader-options.model'; import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; @@ -67,6 +74,18 @@ import { ThemedSubmissionUploadFilesComponent } from './submission-upload-files/ ThemedSubmissionUploadFilesComponent, TranslatePipe, ], + providers: environment.submission.showErrorStrategy === 'onload' ? [ + // Always show validation errors, even if input hasn't been + // blurred yet + DynamicFormValidationService, + { + provide: DYNAMIC_ERROR_MESSAGES_MATCHER, + useValue: ( + _control: AbstractControl, + _model: DynamicFormControlModel, + hasFocus: boolean) => !hasFocus, + }, + ] : [], }) export class SubmissionFormComponent implements OnChanges, OnDestroy { diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 91adee2e0f5..5229265ad59 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -253,6 +253,7 @@ export class DefaultAppConfig implements AppConfig { ], }, }, + showErrorStrategy: 'onblur', }; // Fallback language in which the UI will be rendered if the user's browser language is not an active language diff --git a/src/config/submission-config.interface.ts b/src/config/submission-config.interface.ts index afc81a39e25..98de8faf063 100644 --- a/src/config/submission-config.interface.ts +++ b/src/config/submission-config.interface.ts @@ -31,9 +31,12 @@ export interface ConfidenceIconConfig extends Config { icon: string; } +type ShowErrorStrategy = 'onload' | 'onblur'; + export interface SubmissionConfig extends Config { autosave: AutosaveConfig; duplicateDetection: DuplicateDetectionConfig; typeBind: TypeBindConfig; icons: IconsConfig; + showErrorStrategy: ShowErrorStrategy; } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index bd456f328cd..1e3273de20c 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -194,6 +194,7 @@ export const environment: BuildConfig = { ], }, }, + showErrorStrategy: 'onblur', }, // NOTE: will log all redux actions and transfers in console