mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 18:44:14 +00:00
Fixed form error handler
This commit is contained in:
@@ -85,7 +85,7 @@ export const FORM_GROUP_TEST_GROUP = new FormGroup({
|
|||||||
dc_contributor_author: new FormControl(),
|
dc_contributor_author: new FormControl(),
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DsDynamicGroupComponent test suite', () => {
|
fdescribe('DsDynamicGroupComponent test suite', () => {
|
||||||
const config = {
|
const config = {
|
||||||
form: {
|
form: {
|
||||||
validatorMap: {
|
validatorMap: {
|
||||||
@@ -188,8 +188,8 @@ describe('DsDynamicGroupComponent test suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => {
|
it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
const config = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel;
|
const formConfig = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel;
|
||||||
const formModel = service.modelFromConfiguration(config, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly);
|
const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly);
|
||||||
const chips = new Chips([], 'value', 'dc.contributor.author');
|
const chips = new Chips([], 'value', 'dc.contributor.author');
|
||||||
|
|
||||||
expect(groupComp.formCollapsed).toEqual(Observable.of(false));
|
expect(groupComp.formCollapsed).toEqual(Observable.of(false));
|
||||||
@@ -258,8 +258,8 @@ describe('DsDynamicGroupComponent test suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => {
|
it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
const config = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel;
|
const formConfig = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel;
|
||||||
const formModel = service.modelFromConfiguration(config, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly);
|
const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly);
|
||||||
const chips = new Chips(modelValue, 'value', 'dc.contributor.author');
|
const chips = new Chips(modelValue, 'value', 'dc.contributor.author');
|
||||||
|
|
||||||
expect(groupComp.formCollapsed).toEqual(Observable.of(true));
|
expect(groupComp.formCollapsed).toEqual(Observable.of(true));
|
||||||
|
@@ -43,6 +43,19 @@ export class DynamicGroupModel extends DsDynamicInputModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get value() {
|
get value() {
|
||||||
|
return this._value
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(value) {
|
||||||
|
this._value = (isEmpty(value)) ? null : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
const value = this.getGroupValue();
|
||||||
|
return (value.length === 1 && isNull(value[0][this.mandatoryField]));
|
||||||
|
}
|
||||||
|
|
||||||
|
getGroupValue(): any[] {
|
||||||
if (isEmpty(this._value)) {
|
if (isEmpty(this._value)) {
|
||||||
// If items is empty, last element has been removed
|
// If items is empty, last element has been removed
|
||||||
// so emit an empty value that allows to dispatch
|
// so emit an empty value that allows to dispatch
|
||||||
@@ -57,12 +70,4 @@ export class DynamicGroupModel extends DsDynamicInputModel {
|
|||||||
}
|
}
|
||||||
return this._value
|
return this._value
|
||||||
}
|
}
|
||||||
|
|
||||||
set value(value) {
|
|
||||||
this._value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty() {
|
|
||||||
return (this.value.length === 1 && isNull(this.value[0][this.mandatoryField]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,10 @@ import { isObject, isString, mergeWith } from 'lodash';
|
|||||||
import { hasValue, isEmpty, isNotEmpty, isNotNull, isNotUndefined, isNull } from '../../empty.util';
|
import { hasValue, isEmpty, isNotEmpty, isNotNull, isNotUndefined, isNull } from '../../empty.util';
|
||||||
import { DynamicQualdropModel } from './ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
|
import { DynamicQualdropModel } from './ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
|
||||||
import { SubmissionFormsModel } from '../../../core/shared/config/config-submission-forms.model';
|
import { SubmissionFormsModel } from '../../../core/shared/config/config-submission-forms.model';
|
||||||
import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
|
import {
|
||||||
|
DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP,
|
||||||
|
DynamicGroupModel
|
||||||
|
} from './ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
|
||||||
import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './ds-dynamic-form-ui/models/tag/dynamic-tag.model';
|
import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './ds-dynamic-form-ui/models/tag/dynamic-tag.model';
|
||||||
import { RowParser } from './parsers/row-parser';
|
import { RowParser } from './parsers/row-parser';
|
||||||
|
|
||||||
@@ -150,7 +153,7 @@ export class FormBuilderService extends DynamicFormService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.isRelationGroup(controlModel)) {
|
if (this.isRelationGroup(controlModel)) {
|
||||||
const values = (controlModel as any).value;
|
const values = (controlModel as DynamicGroupModel).getGroupValue();
|
||||||
values.forEach((groupValue, groupIndex) => {
|
values.forEach((groupValue, groupIndex) => {
|
||||||
const newGroupValue = Object.create({});
|
const newGroupValue = Object.create({});
|
||||||
Object.keys(groupValue)
|
Object.keys(groupValue)
|
||||||
|
@@ -106,11 +106,12 @@ export class FormAddError implements Action {
|
|||||||
payload: {
|
payload: {
|
||||||
formId: string,
|
formId: string,
|
||||||
fieldId: string,
|
fieldId: string,
|
||||||
|
fieldIndex: number,
|
||||||
errorMessage: string,
|
errorMessage: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(formId: string, fieldId: string, errorMessage: string) {
|
constructor(formId: string, fieldId: string, fieldIndex: number, errorMessage: string) {
|
||||||
this.payload = {formId, fieldId, errorMessage};
|
this.payload = {formId, fieldId, fieldIndex, errorMessage};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +119,12 @@ export class FormRemoveErrorAction implements Action {
|
|||||||
type = FormActionTypes.FORM_REMOVE_ERROR;
|
type = FormActionTypes.FORM_REMOVE_ERROR;
|
||||||
payload: {
|
payload: {
|
||||||
formId: string,
|
formId: string,
|
||||||
fieldId: string
|
fieldId: string,
|
||||||
|
fieldIndex: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(formId: string, fieldId: string) {
|
constructor(formId: string, fieldId: string, fieldIndex: number,) {
|
||||||
this.payload = {formId, fieldId};
|
this.payload = {formId, fieldId, fieldIndex};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -162,14 +162,15 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
const {formGroup, formModel} = this;
|
const {formGroup, formModel} = this;
|
||||||
|
|
||||||
errors
|
errors
|
||||||
.filter((error: FormError) => findIndex(this.formErrors, {fieldId: error.fieldId}) === -1)
|
.filter((error: FormError) => findIndex(this.formErrors, {fieldId: error.fieldId, fieldIndex: error.fieldIndex}) === -1)
|
||||||
.forEach((error: FormError) => {
|
.forEach((error: FormError) => {
|
||||||
const {fieldId} = error;
|
const {fieldId} = error;
|
||||||
|
const {fieldIndex} = error;
|
||||||
let field: AbstractControl;
|
let field: AbstractControl;
|
||||||
if (!!this.parentFormModel) {
|
if (!!this.parentFormModel) {
|
||||||
field = this.formBuilderService.getFormControlById(fieldId, formGroup.parent as FormGroup, formModel);
|
field = this.formBuilderService.getFormControlById(fieldId, formGroup.parent as FormGroup, formModel, fieldIndex);
|
||||||
} else {
|
} else {
|
||||||
field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel);
|
field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel, fieldIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field) {
|
if (field) {
|
||||||
@@ -181,14 +182,15 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.formErrors
|
this.formErrors
|
||||||
.filter((error: FormError) => findIndex(errors, {fieldId: error.fieldId}) === -1)
|
.filter((error: FormError) => findIndex(errors, {fieldId: error.fieldId, fieldIndex: error.fieldIndex}) === -1)
|
||||||
.forEach((error: FormError) => {
|
.forEach((error: FormError) => {
|
||||||
const {fieldId} = error;
|
const {fieldId} = error;
|
||||||
|
const {fieldIndex} = error;
|
||||||
let field: AbstractControl;
|
let field: AbstractControl;
|
||||||
if (!!this.parentFormModel) {
|
if (!!this.parentFormModel) {
|
||||||
field = this.formBuilderService.getFormControlById(fieldId, formGroup.parent as FormGroup, formModel);
|
field = this.formBuilderService.getFormControlById(fieldId, formGroup.parent as FormGroup, formModel, fieldIndex);
|
||||||
} else {
|
} else {
|
||||||
field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel);
|
field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel, fieldIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field) {
|
if (field) {
|
||||||
@@ -251,8 +253,9 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const control: FormControl = event.control;
|
const control: FormControl = event.control;
|
||||||
|
const fieldIndex: number = (event.context && event.context.index) ? event.context.index : 0;
|
||||||
if (control.valid) {
|
if (control.valid) {
|
||||||
this.store.dispatch(new FormRemoveErrorAction(this.formId, event.model.id));
|
this.store.dispatch(new FormRemoveErrorAction(this.formId, event.model.id, fieldIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
import { FormEntry, formReducer } from './form.reducer';
|
import { formReducer } from './form.reducer';
|
||||||
import {
|
import {
|
||||||
FormAddError,
|
FormAddError,
|
||||||
FormChangeAction, FormClearErrorsAction,
|
FormChangeAction,
|
||||||
|
FormClearErrorsAction,
|
||||||
FormInitAction,
|
FormInitAction,
|
||||||
FormRemoveAction, FormRemoveErrorAction,
|
FormRemoveAction,
|
||||||
|
FormRemoveErrorAction,
|
||||||
FormStatusChangeAction
|
FormStatusChangeAction
|
||||||
} from './form.actions';
|
} from './form.actions';
|
||||||
|
|
||||||
@@ -165,15 +167,17 @@ describe('formReducer', () => {
|
|||||||
const expectedErrors = [
|
const expectedErrors = [
|
||||||
{
|
{
|
||||||
fieldId: 'title',
|
fieldId: 'title',
|
||||||
|
fieldIndex: 0,
|
||||||
message: 'Not valid'
|
message: 'Not valid'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const formId = 'testForm';
|
const formId = 'testForm';
|
||||||
const fieldId = 'title';
|
const fieldId = 'title';
|
||||||
|
const fieldIndex = 0;
|
||||||
const message = 'Not valid';
|
const message = 'Not valid';
|
||||||
|
|
||||||
const action = new FormAddError(formId, fieldId, message);
|
const action = new FormAddError(formId, fieldId, fieldIndex, message);
|
||||||
const newState = formReducer(initState, action);
|
const newState = formReducer(initState, action);
|
||||||
|
|
||||||
expect(newState.testForm.errors).toEqual(expectedErrors);
|
expect(newState.testForm.errors).toEqual(expectedErrors);
|
||||||
@@ -192,10 +196,12 @@ describe('formReducer', () => {
|
|||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
fieldId: 'author',
|
fieldId: 'author',
|
||||||
|
fieldIndex: 0,
|
||||||
message: 'error.validation.required'
|
message: 'error.validation.required'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldId: 'title',
|
fieldId: 'title',
|
||||||
|
fieldIndex: 0,
|
||||||
message: 'error.validation.required'
|
message: 'error.validation.required'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -205,13 +211,16 @@ describe('formReducer', () => {
|
|||||||
const expectedErrors = [
|
const expectedErrors = [
|
||||||
{
|
{
|
||||||
fieldId: 'title',
|
fieldId: 'title',
|
||||||
|
fieldIndex: 0,
|
||||||
message: 'error.validation.required'
|
message: 'error.validation.required'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const formId = 'testForm';
|
const formId = 'testForm';
|
||||||
|
const fieldId = 'author';
|
||||||
|
const fieldIndex = 0;
|
||||||
|
|
||||||
const action = new FormRemoveErrorAction(formId, 'author');
|
const action = new FormRemoveErrorAction(formId, fieldId, fieldIndex);
|
||||||
const newState = formReducer(initState, action);
|
const newState = formReducer(initState, action);
|
||||||
|
|
||||||
expect(newState.testForm.errors).toEqual(expectedErrors);
|
expect(newState.testForm.errors).toEqual(expectedErrors);
|
||||||
@@ -252,6 +261,7 @@ describe('formReducer', () => {
|
|||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
fieldId: 'author',
|
fieldId: 'author',
|
||||||
|
fieldIndex: 0,
|
||||||
message: 'error.validation.required'
|
message: 'error.validation.required'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@@ -14,6 +14,7 @@ import { isEqual, uniqWith } from 'lodash';
|
|||||||
export interface FormError {
|
export interface FormError {
|
||||||
message: string;
|
message: string;
|
||||||
fieldId: string;
|
fieldId: string;
|
||||||
|
fieldIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormEntry {
|
export interface FormEntry {
|
||||||
@@ -70,6 +71,7 @@ function addFormErrors(state: FormState, action: FormAddError) {
|
|||||||
if (hasValue(state[formId])) {
|
if (hasValue(state[formId])) {
|
||||||
const error: FormError = {
|
const error: FormError = {
|
||||||
fieldId: action.payload.fieldId,
|
fieldId: action.payload.fieldId,
|
||||||
|
fieldIndex: action.payload.fieldIndex,
|
||||||
message: action.payload.errorMessage
|
message: action.payload.errorMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,8 +90,9 @@ function addFormErrors(state: FormState, action: FormAddError) {
|
|||||||
function removeFormError(state: FormState, action: FormRemoveErrorAction) {
|
function removeFormError(state: FormState, action: FormRemoveErrorAction) {
|
||||||
const formId = action.payload.formId;
|
const formId = action.payload.formId;
|
||||||
const fieldId = action.payload.fieldId;
|
const fieldId = action.payload.fieldId;
|
||||||
|
const fieldIndex = action.payload.fieldIndex;
|
||||||
if (hasValue(state[formId])) {
|
if (hasValue(state[formId])) {
|
||||||
const errors = state[formId].errors.filter((error) => error.fieldId !== fieldId);
|
const errors = state[formId].errors.filter((error) => error.fieldId !== fieldId || error.fieldIndex !== fieldIndex);
|
||||||
const newState = Object.assign({}, state);
|
const newState = Object.assign({}, state);
|
||||||
newState[formId] = Object.assign({}, state[formId], {errors});
|
newState[formId] = Object.assign({}, state[formId], {errors});
|
||||||
return newState;
|
return newState;
|
||||||
|
Reference in New Issue
Block a user