mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 10:34:15 +00:00
updated with latest changes
This commit is contained in:
@@ -288,6 +288,7 @@
|
|||||||
<ds-dynamic-group [model]="model"
|
<ds-dynamic-group [model]="model"
|
||||||
[formId]="formId"
|
[formId]="formId"
|
||||||
[group]="group"
|
[group]="group"
|
||||||
|
[showErrorMessages]="showErrorMessages"
|
||||||
(blur)="onBlur($event)"
|
(blur)="onBlur($event)"
|
||||||
(change)="onValueChange($event)"
|
(change)="onValueChange($event)"
|
||||||
(focus)="onFocus($event)"></ds-dynamic-group>
|
(focus)="onFocus($event)"></ds-dynamic-group>
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
[value]="year"
|
[value]="year"
|
||||||
[invalid]="showErrorMessages"
|
[invalid]="showErrorMessages"
|
||||||
[placeholder]='yearPlaceholder'
|
[placeholder]='yearPlaceholder'
|
||||||
|
(blur)="onBlur($event)"
|
||||||
(change)="onChange($event)"
|
(change)="onChange($event)"
|
||||||
(focus)="onFocus($event)"
|
(focus)="onFocus($event)"
|
||||||
></ds-number-picker>
|
></ds-number-picker>
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
[value]="month"
|
[value]="month"
|
||||||
[placeholder]="monthPlaceholder"
|
[placeholder]="monthPlaceholder"
|
||||||
[disabled]="!year || model.disabled"
|
[disabled]="!year || model.disabled"
|
||||||
|
(blur)="onBlur($event)"
|
||||||
(change)="onChange($event)"
|
(change)="onChange($event)"
|
||||||
(focus)="onFocus($event)"
|
(focus)="onFocus($event)"
|
||||||
></ds-number-picker>
|
></ds-number-picker>
|
||||||
@@ -38,6 +40,7 @@
|
|||||||
[value]="day"
|
[value]="day"
|
||||||
[placeholder]="dayPlaceholder"
|
[placeholder]="dayPlaceholder"
|
||||||
[disabled]="!month || model.disabled"
|
[disabled]="!month || model.disabled"
|
||||||
|
(blur)="onBlur($event)"
|
||||||
(change)="onChange($event)"
|
(change)="onChange($event)"
|
||||||
(focus)="onFocus($event)"
|
(focus)="onFocus($event)"
|
||||||
></ds-number-picker>
|
></ds-number-picker>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
|
||||||
import { FormGroup } from '@angular/forms';
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import { DynamicDsDatePickerModel } from './date-picker.model';
|
import { DynamicDsDatePickerModel } from './date-picker.model';
|
||||||
import { hasValue, isNotEmpty } from '../../../../../empty.util';
|
import { hasValue, isNotEmpty } from '../../../../../empty.util';
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ export class DsDatePickerComponent implements OnInit {
|
|||||||
|
|
||||||
@Output() selected = new EventEmitter<number>();
|
@Output() selected = new EventEmitter<number>();
|
||||||
@Output() remove = new EventEmitter<number>();
|
@Output() remove = new EventEmitter<number>();
|
||||||
|
@Output() blur = new EventEmitter<any>();
|
||||||
@Output() change = new EventEmitter<any>();
|
@Output() change = new EventEmitter<any>();
|
||||||
@Output() focus = new EventEmitter<any>();
|
@Output() focus = new EventEmitter<any>();
|
||||||
|
|
||||||
@@ -76,6 +77,10 @@ export class DsDatePickerComponent implements OnInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBlur(event) {
|
||||||
|
this.blur.emit();
|
||||||
|
}
|
||||||
|
|
||||||
onChange(event) {
|
onChange(event) {
|
||||||
// update year-month-day
|
// update year-month-day
|
||||||
switch (event.field) {
|
switch (event.field) {
|
||||||
|
@@ -15,14 +15,16 @@
|
|||||||
(click)="expandForm()"></span>
|
(click)="expandForm()"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="pt-2" [ngClass]="{'border-top': !invalid, 'border border-danger': invalid}">
|
<div class="pt-2" [ngClass]="{'border-top': !showErrorMessages, 'border border-danger': showErrorMessages}">
|
||||||
<div *ngIf="!(formCollapsed | async)" class="pl-2 row" @shrinkInOut>
|
<div *ngIf="!(formCollapsed | async)" class="pl-2 row" @shrinkInOut>
|
||||||
<ds-form #formRef="formComponent"
|
<ds-form #formRef="formComponent"
|
||||||
class="col-sm-12 col-md-8 col-lg-9 col-xl-10 pl-0"
|
class="col-sm-12 col-md-8 col-lg-9 col-xl-10 pl-0"
|
||||||
[formId]="formId"
|
[formId]="formId"
|
||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[displaySubmit]="false"
|
[displaySubmit]="false"
|
||||||
(dfChange)="onChange($event)"></ds-form>
|
[emitChange]="false"
|
||||||
|
(dfBlur)="onBlur($event)"
|
||||||
|
(dfFocus)="onFocus($event)"></ds-form>
|
||||||
|
|
||||||
|
|
||||||
<div *ngIf="!(formCollapsed | async)" class="col p-0 m-0 d-flex justify-content-center align-items-center">
|
<div *ngIf="!(formCollapsed | async)" class="col p-0 m-0 d-flex justify-content-center align-items-center">
|
||||||
|
@@ -11,12 +11,7 @@ import {
|
|||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import {
|
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicInputModel } from '@ng-dynamic-forms/core';
|
||||||
DynamicFormControlEvent,
|
|
||||||
DynamicFormControlModel,
|
|
||||||
DynamicFormGroupModel,
|
|
||||||
DynamicInputModel
|
|
||||||
} from '@ng-dynamic-forms/core';
|
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
import { DynamicGroupModel, PLACEHOLDER_PARENT_METADATA } from './dynamic-group.model';
|
import { DynamicGroupModel, PLACEHOLDER_PARENT_METADATA } from './dynamic-group.model';
|
||||||
@@ -25,7 +20,6 @@ import { SubmissionFormsModel } from '../../../../../../core/shared/config/confi
|
|||||||
import { FormService } from '../../../../form.service';
|
import { FormService } from '../../../../form.service';
|
||||||
import { FormComponent } from '../../../../form.component';
|
import { FormComponent } from '../../../../form.component';
|
||||||
import { Chips } from '../../../../../chips/models/chips.model';
|
import { Chips } from '../../../../../chips/models/chips.model';
|
||||||
import { DynamicLookupModel } from '../lookup/dynamic-lookup.model';
|
|
||||||
import { hasValue, isEmpty, isNotEmpty } from '../../../../../empty.util';
|
import { hasValue, isEmpty, isNotEmpty } from '../../../../../empty.util';
|
||||||
import { shrinkInOut } from '../../../../../animations/shrink';
|
import { shrinkInOut } from '../../../../../animations/shrink';
|
||||||
import { ChipsItem } from '../../../../../chips/models/chips-item.model';
|
import { ChipsItem } from '../../../../../chips/models/chips-item.model';
|
||||||
@@ -48,6 +42,7 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
@Input() formId: string;
|
@Input() formId: string;
|
||||||
@Input() group: FormGroup;
|
@Input() group: FormGroup;
|
||||||
@Input() model: DynamicGroupModel;
|
@Input() model: DynamicGroupModel;
|
||||||
|
@Input() showErrorMessages = false;
|
||||||
|
|
||||||
@Output() blur: EventEmitter<any> = new EventEmitter<any>();
|
@Output() blur: EventEmitter<any> = new EventEmitter<any>();
|
||||||
@Output() change: EventEmitter<any> = new EventEmitter<any>();
|
@Output() change: EventEmitter<any> = new EventEmitter<any>();
|
||||||
@@ -57,7 +52,6 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
public formCollapsed = Observable.of(false);
|
public formCollapsed = Observable.of(false);
|
||||||
public formModel: DynamicFormControlModel[];
|
public formModel: DynamicFormControlModel[];
|
||||||
public editMode = false;
|
public editMode = false;
|
||||||
public invalid = false;
|
|
||||||
|
|
||||||
private selectedChipItem: ChipsItem;
|
private selectedChipItem: ChipsItem;
|
||||||
private subs: Subscription[] = [];
|
private subs: Subscription[] = [];
|
||||||
@@ -72,7 +66,7 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const config = {rows: this.model.formConfiguration} as SubmissionFormsModel;
|
const config = {rows: this.model.formConfiguration} as SubmissionFormsModel;
|
||||||
if (isNotEmpty(this.model.value)) {
|
if (!this.model.isEmpty()) {
|
||||||
this.formCollapsed = Observable.of(true);
|
this.formCollapsed = Observable.of(true);
|
||||||
}
|
}
|
||||||
this.model.valueUpdates.subscribe((value: any[]) => {
|
this.model.valueUpdates.subscribe((value: any[]) => {
|
||||||
@@ -80,38 +74,22 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.formId = this.formService.getUniqueId(this.model.id);
|
this.formId = this.formService.getUniqueId(this.model.id);
|
||||||
this.formModel = this.formBuilderService.modelFromConfiguration(config, this.model.scopeUUID, {});
|
this.formModel = this.formBuilderService.modelFromConfiguration(config, this.model.scopeUUID, {}, this.model.submissionScope, this.model.readOnly);
|
||||||
this.chips = new Chips(this.model.value, 'value', this.model.mandatoryField);
|
const initChipsValue = this.model.isEmpty() ? [] : this.model.value;
|
||||||
|
this.chips = new Chips(initChipsValue, 'value', this.model.mandatoryField);
|
||||||
this.subs.push(
|
this.subs.push(
|
||||||
this.chips.chipsItems
|
this.chips.chipsItems
|
||||||
.subscribe((subItems: any[]) => {
|
.subscribe((subItems: any[]) => {
|
||||||
const items = this.chips.getChipsItems();
|
const items = this.chips.getChipsItems();
|
||||||
// Does not emit change if model value is equal to the current value
|
// Does not emit change if model value is equal to the current value
|
||||||
if (!isEqual(items, this.model.value)) {
|
if (!isEqual(items, this.model.value)) {
|
||||||
if (isEmpty(items)) {
|
// if ((isNotEmpty(items) && !this.model.isEmpty()) || (isEmpty(items) && !this.model.isEmpty())) {
|
||||||
// If items is empty, last element has been removed
|
if (!(isEmpty(items) && this.model.isEmpty())) {
|
||||||
// so emit an empty value that allows to dispatch
|
this.model.valueUpdates.next(items);
|
||||||
// a remove JSON PATCH operation
|
this.change.emit();
|
||||||
const emptyItem = Object.create({});
|
|
||||||
Object.keys(this.model.value[0])
|
|
||||||
.forEach((key) => {
|
|
||||||
emptyItem[key] = null;
|
|
||||||
});
|
|
||||||
items.push(emptyItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.model.valueUpdates.next(items);
|
|
||||||
this.change.emit();
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
// Invalid state for year
|
|
||||||
this.group.get(this.model.id).statusChanges.subscribe((state) => {
|
|
||||||
if (state === 'INVALID') {
|
|
||||||
this.invalid = true;
|
|
||||||
} else {
|
|
||||||
this.invalid = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +108,8 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(event: DynamicFormControlEvent) {
|
onBlur(event) {
|
||||||
return
|
this.blur.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
onChipSelected(event) {
|
onChipSelected(event) {
|
||||||
@@ -142,26 +120,23 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
modelRow.group.forEach((model: DynamicInputModel) => {
|
modelRow.group.forEach((model: DynamicInputModel) => {
|
||||||
const value = (this.selectedChipItem.item[model.name] === PLACEHOLDER_PARENT_METADATA
|
const value = (this.selectedChipItem.item[model.name] === PLACEHOLDER_PARENT_METADATA
|
||||||
|| this.selectedChipItem.item[model.name].value === PLACEHOLDER_PARENT_METADATA)
|
|| this.selectedChipItem.item[model.name].value === PLACEHOLDER_PARENT_METADATA)
|
||||||
? null
|
? null
|
||||||
: this.selectedChipItem.item[model.name];
|
: this.selectedChipItem.item[model.name];
|
||||||
if (value instanceof FormFieldMetadataValueObject || value instanceof AuthorityValueModel) {
|
if (value instanceof FormFieldMetadataValueObject || value instanceof AuthorityValueModel) {
|
||||||
model.valueUpdates.next(value.display);
|
model.valueUpdates.next(value.display);
|
||||||
} else {
|
} else {
|
||||||
model.valueUpdates.next(value);
|
model.valueUpdates.next(value);
|
||||||
}
|
}
|
||||||
// if (model instanceof DynamicLookupModel) {
|
|
||||||
// (model as DynamicLookupModel).valueUpdates.next(value);
|
|
||||||
// } else if (model instanceof DynamicInputModel) {
|
|
||||||
// model.valueUpdates.next(value);
|
|
||||||
// } else {
|
|
||||||
// (model as any).value = value;
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editMode = true;
|
this.editMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFocus(event) {
|
||||||
|
this.focus.emit(event);
|
||||||
|
}
|
||||||
|
|
||||||
collapseForm() {
|
collapseForm() {
|
||||||
this.formCollapsed = Observable.of(true);
|
this.formCollapsed = Observable.of(true);
|
||||||
this.clear();
|
this.clear();
|
||||||
@@ -178,7 +153,9 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit {
|
|||||||
this.editMode = false;
|
this.editMode = false;
|
||||||
}
|
}
|
||||||
this.resetForm();
|
this.resetForm();
|
||||||
// this.change.emit(event);
|
if (!this.model.isEmpty()) {
|
||||||
|
this.formCollapsed = Observable.of(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
import { DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core';
|
import { DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core';
|
||||||
import { FormRowModel } from '../../../../../../core/shared/config/config-submission-forms.model';
|
import { FormRowModel } from '../../../../../../core/shared/config/config-submission-forms.model';
|
||||||
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
|
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
|
||||||
|
import { AuthorityValueModel } from '../../../../../../core/integration/models/authority-value.model';
|
||||||
|
import { isEmpty, isNull } from '../../../../../empty.util';
|
||||||
|
|
||||||
export const DYNAMIC_FORM_CONTROL_TYPE_RELATION = 'RELATION';
|
export const DYNAMIC_FORM_CONTROL_TYPE_RELATION = 'RELATION';
|
||||||
export const PLACEHOLDER_PARENT_METADATA = '#PLACEHOLDER_PARENT_METADATA_VALUE#';
|
export const PLACEHOLDER_PARENT_METADATA = '#PLACEHOLDER_PARENT_METADATA_VALUE#';
|
||||||
@@ -14,6 +16,7 @@ export interface DynamicGroupModelConfig extends DsDynamicInputModelConfig {
|
|||||||
name: string,
|
name: string,
|
||||||
relationFields: string[],
|
relationFields: string[],
|
||||||
scopeUUID: string,
|
scopeUUID: string,
|
||||||
|
submissionScope: string;
|
||||||
value?: any;
|
value?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +28,8 @@ export class DynamicGroupModel extends DsDynamicInputModel {
|
|||||||
@serializable() mandatoryField: string;
|
@serializable() mandatoryField: string;
|
||||||
@serializable() relationFields: string[];
|
@serializable() relationFields: string[];
|
||||||
@serializable() scopeUUID: string;
|
@serializable() scopeUUID: string;
|
||||||
@serializable() value: any[];
|
@serializable() submissionScope: string;
|
||||||
|
@serializable() _value: any[];
|
||||||
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_RELATION;
|
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_RELATION;
|
||||||
|
|
||||||
constructor(config: DynamicGroupModelConfig, layout?: DynamicFormControlLayout) {
|
constructor(config: DynamicGroupModelConfig, layout?: DynamicFormControlLayout) {
|
||||||
@@ -35,7 +39,32 @@ export class DynamicGroupModel extends DsDynamicInputModel {
|
|||||||
this.mandatoryField = config.mandatoryField;
|
this.mandatoryField = config.mandatoryField;
|
||||||
this.relationFields = config.relationFields;
|
this.relationFields = config.relationFields;
|
||||||
this.scopeUUID = config.scopeUUID;
|
this.scopeUUID = config.scopeUUID;
|
||||||
|
this.submissionScope = config.submissionScope;
|
||||||
const value = config.value || [];
|
const value = config.value || [];
|
||||||
this.valueUpdates.next(value)
|
this.valueUpdates.next(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
if (isEmpty(this._value)) {
|
||||||
|
// If items is empty, last element has been removed
|
||||||
|
// so emit an empty value that allows to dispatch
|
||||||
|
// a remove JSON PATCH operation
|
||||||
|
const emptyItem = Object.create({});
|
||||||
|
emptyItem[this.mandatoryField] = null;
|
||||||
|
this.relationFields
|
||||||
|
.forEach((field) => {
|
||||||
|
emptyItem[field] = null;
|
||||||
|
});
|
||||||
|
return [emptyItem];
|
||||||
|
}
|
||||||
|
return this._value
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(value) {
|
||||||
|
this._value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
return (this.value.length === 1 && isNull(this.value[0][this.mandatoryField]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -162,12 +162,13 @@ export class FormBuilderService extends DynamicFormService {
|
|||||||
Object.keys(groupValue)
|
Object.keys(groupValue)
|
||||||
.forEach((key) => {
|
.forEach((key) => {
|
||||||
const normValue = normalizeValue(controlModel, groupValue[key], groupIndex);
|
const normValue = normalizeValue(controlModel, groupValue[key], groupIndex);
|
||||||
if (iterateResult.hasOwnProperty(key)) {
|
if (normValue.hasValue()) {
|
||||||
iterateResult[key].push(normValue);
|
if (iterateResult.hasOwnProperty(key)) {
|
||||||
} else {
|
iterateResult[key].push(normValue);
|
||||||
iterateResult[key] = [normValue];
|
} else {
|
||||||
|
iterateResult[key] = [normValue];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// newGroupValue[key] = normalizeValue(controlModel, groupValue[key], groupIndex);
|
|
||||||
});
|
});
|
||||||
// controlArrayValue.push(newGroupValue);
|
// controlArrayValue.push(newGroupValue);
|
||||||
})
|
})
|
||||||
|
@@ -13,7 +13,8 @@ export class GroupFieldParser extends FieldParser {
|
|||||||
constructor(protected configData: FormFieldModel,
|
constructor(protected configData: FormFieldModel,
|
||||||
protected initFormValues,
|
protected initFormValues,
|
||||||
protected readOnly: boolean,
|
protected readOnly: boolean,
|
||||||
protected authorityUuid: string) {
|
protected submissionScope: string,
|
||||||
|
protected authorityUuid: string,) {
|
||||||
super(configData, initFormValues, readOnly);
|
super(configData, initFormValues, readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ export class GroupFieldParser extends FieldParser {
|
|||||||
const modelConfiguration: DynamicGroupModelConfig = this.initModel();
|
const modelConfiguration: DynamicGroupModelConfig = this.initModel();
|
||||||
|
|
||||||
modelConfiguration.scopeUUID = this.authorityUuid;
|
modelConfiguration.scopeUUID = this.authorityUuid;
|
||||||
|
modelConfiguration.submissionScope = this.submissionScope;
|
||||||
if (this.configData && this.configData.rows && this.configData.rows.length > 0) {
|
if (this.configData && this.configData.rows && this.configData.rows.length > 0) {
|
||||||
modelConfiguration.formConfiguration = this.configData.rows;
|
modelConfiguration.formConfiguration = this.configData.rows;
|
||||||
modelConfiguration.relationFields = [];
|
modelConfiguration.relationFields = [];
|
||||||
|
@@ -90,7 +90,7 @@ export class RowParser {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'group':
|
case 'group':
|
||||||
fieldModel = new GroupFieldParser(fieldData, this.initFormValues, this.readOnly, this.authorityOptions.uuid).parse();
|
fieldModel = new GroupFieldParser(fieldData, this.initFormValues, this.readOnly, this.submissionScope, this.authorityOptions.uuid).parse();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'twobox':
|
case 'twobox':
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
[formGroup]="formGroup"
|
[formGroup]="formGroup"
|
||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[formLayout]="formLayout"
|
[formLayout]="formLayout"
|
||||||
|
(change)="$event.stopPropagation();"
|
||||||
(dfBlur)="onBlur($event)"
|
(dfBlur)="onBlur($event)"
|
||||||
(dfChange)="onChange($event)"
|
(dfChange)="onChange($event)"
|
||||||
(dfFocus)="onFocus($event)">
|
(dfFocus)="onFocus($event)">
|
||||||
|
@@ -8,6 +8,7 @@ import {
|
|||||||
DynamicFormGroupModel, DynamicFormLayout,
|
DynamicFormGroupModel, DynamicFormLayout,
|
||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
import { findIndex } from 'lodash';
|
||||||
|
|
||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
import {
|
import {
|
||||||
@@ -37,6 +38,7 @@ import { isEmpty } from 'lodash';
|
|||||||
})
|
})
|
||||||
export class FormComponent implements OnDestroy, OnInit {
|
export class FormComponent implements OnDestroy, OnInit {
|
||||||
|
|
||||||
|
private formErrors: FormError[] = [];
|
||||||
private formValid: boolean;
|
private formValid: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,6 +46,11 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
*/
|
*/
|
||||||
@Input() displaySubmit = true;
|
@Input() displaySubmit = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean that indicate if to emit a form change event
|
||||||
|
*/
|
||||||
|
@Input() emitChange = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The form unique ID
|
* The form unique ID
|
||||||
*/
|
*/
|
||||||
@@ -154,7 +161,9 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
.subscribe((errors: FormError[]) => {
|
.subscribe((errors: FormError[]) => {
|
||||||
const {formGroup, formModel} = this;
|
const {formGroup, formModel} = this;
|
||||||
|
|
||||||
errors.forEach((error: FormError) => {
|
errors
|
||||||
|
.filter((error: FormError) => findIndex(this.formErrors, {fieldId: error.fieldId}) === -1)
|
||||||
|
.forEach((error: FormError) => {
|
||||||
const {fieldId} = error;
|
const {fieldId} = error;
|
||||||
let field: AbstractControl;
|
let field: AbstractControl;
|
||||||
if (!!this.parentFormModel) {
|
if (!!this.parentFormModel) {
|
||||||
@@ -166,9 +175,29 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
if (field) {
|
if (field) {
|
||||||
const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel);
|
const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel);
|
||||||
this.formService.addErrorToField(field, model, error.message);
|
this.formService.addErrorToField(field, model, error.message);
|
||||||
|
// this.formService.validateAllFormFields(formGroup);
|
||||||
|
this.changeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.formErrors
|
||||||
|
.filter((error: FormError) => findIndex(errors, {fieldId: error.fieldId}) === -1)
|
||||||
|
.forEach((error: FormError) => {
|
||||||
|
const {fieldId} = error;
|
||||||
|
let field: AbstractControl;
|
||||||
|
if (!!this.parentFormModel) {
|
||||||
|
field = this.formBuilderService.getFormControlById(fieldId, formGroup.parent as FormGroup, formModel);
|
||||||
|
} else {
|
||||||
|
field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel);
|
||||||
|
this.formService.removeErrorFromField(field, model, error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.formErrors = errors;
|
||||||
this.changeDetectorRef.detectChanges();
|
this.changeDetectorRef.detectChanges();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -217,10 +246,11 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
this.store.dispatch(action);
|
this.store.dispatch(action);
|
||||||
this.formGroup.markAsPristine();
|
this.formGroup.markAsPristine();
|
||||||
|
|
||||||
this.change.emit(event);
|
if (this.emitChange) {
|
||||||
const control: FormControl = event.control;
|
this.change.emit(event);
|
||||||
|
}
|
||||||
|
|
||||||
// control.setErrors(null);
|
const control: FormControl = event.control;
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@@ -7,9 +7,9 @@ import { AppState } from '../../app.reducer';
|
|||||||
import { formObjectFromIdSelector } from './selectors';
|
import { formObjectFromIdSelector } from './selectors';
|
||||||
import { FormBuilderService } from './builder/form-builder.service';
|
import { FormBuilderService } from './builder/form-builder.service';
|
||||||
import { DynamicFormControlModel, DynamicFormGroupModel } from '@ng-dynamic-forms/core';
|
import { DynamicFormControlModel, DynamicFormGroupModel } from '@ng-dynamic-forms/core';
|
||||||
import { isNotEmpty, isNotUndefined } from '../empty.util';
|
import { isEmpty, isNotEmpty, isNotUndefined } from '../empty.util';
|
||||||
import { find, uniqueId } from 'lodash';
|
import { find, uniqueId } from 'lodash';
|
||||||
import { FormChangeAction } from './form.actions';
|
import { FormChangeAction, FormRemoveErrorAction } from './form.actions';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FormService {
|
export class FormService {
|
||||||
@@ -75,39 +75,46 @@ export class FormService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addErrorToField(field: AbstractControl, model: DynamicFormControlModel, message: string) {
|
public addErrorToField(field: AbstractControl, model: DynamicFormControlModel, message: string) {
|
||||||
const errorFound = !!(find(field.errors, (err) => err === message));
|
|
||||||
|
|
||||||
// search for the same error in the formControl.errors property
|
const error = {}; // create the error object
|
||||||
if (!errorFound) {
|
|
||||||
const errorKey = uniqueId('error-'); // create a single key for the error
|
|
||||||
const error = {}; // create the error object
|
|
||||||
|
|
||||||
error[errorKey] = message; // assign message
|
// if form control model has not errorMessages object, create it
|
||||||
|
if (!model.errorMessages) {
|
||||||
// if form control model has not errorMessages object, create it
|
model.errorMessages = {};
|
||||||
if (!model.errorMessages) {
|
|
||||||
model.errorMessages = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// put the error in the form control model
|
|
||||||
model.errorMessages[errorKey] = message;
|
|
||||||
|
|
||||||
// Use correct error messages from the model
|
|
||||||
const lastArray = message.split('.');
|
|
||||||
if (lastArray && lastArray.length > 0) {
|
|
||||||
const last = lastArray[lastArray.length - 1];
|
|
||||||
const modelMsg = model.errorMessages[last];
|
|
||||||
if (modelMsg && modelMsg.length > 0) {
|
|
||||||
model.errorMessages[errorKey] = modelMsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the error in the form control
|
|
||||||
field.setErrors(error);
|
|
||||||
|
|
||||||
// formGroup.markAsDirty();
|
|
||||||
field.markAsTouched();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use correct error messages from the model
|
||||||
|
const lastArray = message.split('.');
|
||||||
|
if (lastArray && lastArray.length > 0) {
|
||||||
|
// check if error code is already present in the set of model's validators
|
||||||
|
const last = lastArray[lastArray.length - 1];
|
||||||
|
const modelMsg = model.errorMessages[last];
|
||||||
|
if (isEmpty(modelMsg)) {
|
||||||
|
const errorKey = uniqueId('error-'); // create a single key for the error
|
||||||
|
error[errorKey] = true;
|
||||||
|
// put the error message in the form control model
|
||||||
|
model.errorMessages[errorKey] = message;
|
||||||
|
} else {
|
||||||
|
error[last] = modelMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the error in the form control
|
||||||
|
field.setErrors(error);
|
||||||
|
field.markAsTouched();
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeErrorFromField(field: AbstractControl, model: DynamicFormControlModel, message) {
|
||||||
|
const error = {};
|
||||||
|
|
||||||
|
// Use correct error messages from the model
|
||||||
|
const lastArray = message.split('.');
|
||||||
|
if (lastArray && lastArray.length > 0) {
|
||||||
|
const last = lastArray[lastArray.length - 1];
|
||||||
|
error[last] = null;
|
||||||
|
}
|
||||||
|
field.setErrors(error);
|
||||||
|
field.markAsUntouched();
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetForm(formGroup: FormGroup, groupModel: DynamicFormControlModel[], formId: string) {
|
public resetForm(formGroup: FormGroup, groupModel: DynamicFormControlModel[], formId: string) {
|
||||||
|
Reference in New Issue
Block a user