diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html
index f26238cc1f..5614e23c4a 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html
@@ -127,8 +127,8 @@
[showWeekdays]="getAdditional('showWeekdays', true)"
[showWeekNumbers]="getAdditional('showWeekNumbers', false)"
[startDate]="model.focusedDate"
+ (dateSelect)="onValueChange($event)"
(blur)="onBlur($event)"
- (change)="onValueChange($event)"
(focus)="onFocus($event)">
-
@@ -115,11 +112,11 @@
{{'form.no-results' | translate}}
+ (click)="$event.stopPropagation(); clearFields(); sdRef.close();">{{'form.no-results' | translate}}
{{listEntry.value}}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss
index a333fc881f..a697772020 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss
@@ -1,5 +1,9 @@
@import "../../../../../../../styles/variables";
+.dropdown-toggle::after {
+ display:none
+}
+
/* enable absolute positioning */
.spinner-addon {
position: relative;
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html
index 1ea1b62cd0..aed4e16bca 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html
@@ -30,11 +30,11 @@
(scrolled)="onScroll()"
[scrollWindow]="false">
- No results found
+ {{'form.no-results' | translate}}
{{inputFormatter(listEntry)}}
-
+ {{'form.loading' | translate}}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
index a261eef8f7..1d31fc0968 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
@@ -30,6 +30,7 @@ export class DsDynamicTypeaheadComponent implements OnInit {
searchFailed = false;
hideSearchingWhenUnsubscribed = new Observable(() => () => this.changeSearchingStatus(false));
currentValue: any;
+ inputValue: any;
formatter = (x: { display: string }) => {
return (typeof x === 'object') ? x.display : x
@@ -88,9 +89,8 @@ export class DsDynamicTypeaheadComponent implements OnInit {
onInput(event) {
if (!this.model.authorityOptions.closed && isNotEmpty(event.target.value)) {
const valueObj = new FormFieldMetadataValueObject(event.target.value);
- this.currentValue = valueObj;
- this.model.valueUpdates.next(valueObj as any);
- this.change.emit(valueObj);
+ this.inputValue = valueObj;
+ this.model.valueUpdates.next(this.inputValue);
}
if (event.data) {
// this.group.markAsDirty();
@@ -98,6 +98,10 @@ export class DsDynamicTypeaheadComponent implements OnInit {
}
onBlurEvent(event: Event) {
+ if (!this.model.authorityOptions.closed && isNotEmpty(this.inputValue)) {
+ this.change.emit(this.inputValue);
+ this.inputValue = null;
+ }
this.blur.emit(event);
}
@@ -114,6 +118,7 @@ export class DsDynamicTypeaheadComponent implements OnInit {
}
onSelectItem(event: NgbTypeaheadSelectItemEvent) {
+ this.inputValue = null;
this.currentValue = event.item;
this.model.valueUpdates.next(event.item);
this.change.emit(event.item);
diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts
index 78509f76de..2b0cddaaa4 100644
--- a/src/app/shared/form/builder/form-builder.service.ts
+++ b/src/app/shared/form/builder/form-builder.service.ts
@@ -10,20 +10,26 @@ import {
DynamicPathable,
JSONUtils,
} from '@ng-dynamic-forms/core';
-import { mergeWith } from 'lodash';
+import { mergeWith, isObject } from 'lodash';
import { isEmpty, isNotEmpty, isNotNull, isNotUndefined, isNull } from '../../empty.util';
import { DynamicComboboxModel } from './ds-dynamic-form-ui/models/ds-dynamic-combobox.model';
import { SubmissionFormsModel } from '../../../core/shared/config/config-submission-forms.model';
import { DynamicConcatModel } from './ds-dynamic-form-ui/models/ds-dynamic-concat.model';
import { DynamicListCheckboxGroupModel } from './ds-dynamic-form-ui/models/list/dynamic-list-checkbox-group.model';
-import { DynamicGroupModel } from './ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
-import { DynamicTagModel } from './ds-dynamic-form-ui/models/tag/dynamic-tag.model';
+import {
+ DYNAMIC_FORM_CONTROL_TYPE_RELATION,
+ DynamicGroupModel
+} from './ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { DYNAMIC_FORM_CONTROL_TYPE_TAG, DynamicTagModel } from './ds-dynamic-form-ui/models/tag/dynamic-tag.model';
import { DynamicListRadioGroupModel } from './ds-dynamic-form-ui/models/list/dynamic-list-radio-group.model';
import { RowParser } from './parsers/row-parser';
import { DynamicRowArrayModel } from './ds-dynamic-form-ui/models/ds-dynamic-row-array-model';
import { DynamicRowGroupModel } from './ds-dynamic-form-ui/models/ds-dynamic-row-group-model';
+import { DsDynamicInputModel } from './ds-dynamic-form-ui/models/ds-dynamic-input.model';
+import { FormFieldMetadataValueObject } from './models/form-field-metadata-value.model';
+import { AuthorityValueModel } from '../../../core/integration/models/authority-value.model';
@Injectable()
export class FormBuilderService extends DynamicFormService {
@@ -95,11 +101,25 @@ export class FormBuilderService extends DynamicFormService {
}
};
- const iterateControlModels = (findGroupModel: DynamicFormControlModel[]): void => {
+ const normalizeValue = (controlModel, controlValue, controlModelIndex) => {
+ const controlLanguage = (controlModel as DsDynamicInputModel).hasLanguages ? (controlModel as DsDynamicInputModel).language : null;
+ if (((isObject(controlValue) && controlValue.id) || controlValue instanceof AuthorityValueModel)) {
+ return new FormFieldMetadataValueObject(controlValue.value, controlLanguage, controlValue.id, controlValue.display, controlModelIndex);
+ } else if (!(controlValue instanceof FormFieldMetadataValueObject)) {
+ return new FormFieldMetadataValueObject(controlValue, controlLanguage, null, null, controlModelIndex);
+ } else {
+ const place = controlModelIndex || controlValue.place;
+ return Object.assign(new FormFieldMetadataValueObject(), controlValue, {place});
+ }
+ };
+
+ const iterateControlModels = (findGroupModel: DynamicFormControlModel[], controlModelIndex: number = 0): void => {
let iterateResult = Object.create({});
// Iterate over all group's controls
for (const controlModel of findGroupModel) {
+ /* tslint:disable-next-line:no-shadowed-variable */
+ // for (const {controlModel, controlModelIndex} of findGroupModel.map((controlModel, controlModelIndex) => ({ controlModel, controlModelIndex }))) {
if (controlModel instanceof DynamicRowGroupModel && !this.isCustomGroup(controlModel)) {
iterateResult = mergeWith(iterateResult, iterateControlModels((controlModel as DynamicFormGroupModel).group), customizer);
@@ -113,7 +133,7 @@ export class FormBuilderService extends DynamicFormService {
if (controlModel instanceof DynamicRowArrayModel) {
for (const arrayItemModel of controlModel.groups) {
- iterateResult = mergeWith(iterateResult, iterateControlModels(arrayItemModel.group), customizer);
+ iterateResult = mergeWith(iterateResult, iterateControlModels(arrayItemModel.group, arrayItemModel.index), customizer);
}
continue;
}
@@ -121,7 +141,7 @@ export class FormBuilderService extends DynamicFormService {
if (controlModel instanceof DynamicFormArrayModel) {
iterateResult[controlModel.name] = [];
for (const arrayItemModel of controlModel.groups) {
- iterateResult[controlModel.name].push(iterateControlModels(arrayItemModel.group));
+ iterateResult[controlModel.name].push(iterateControlModels(arrayItemModel.group, arrayItemModel.index));
}
continue;
}
@@ -135,12 +155,37 @@ export class FormBuilderService extends DynamicFormService {
controlId = controlModel.name;
}
- const controlValue = isNotUndefined((controlModel as any).value) ? (controlModel as any).value : null;
- if (controlId && iterateResult.hasOwnProperty(controlId) && isNotNull(iterateResult[controlId])) {
- iterateResult[controlId].push(controlValue);
- } else {
- iterateResult[controlId] = isNotEmpty(controlValue) ? (Array.isArray(controlValue) ? controlValue : [controlValue]) : null;
+ if (controlModel instanceof DynamicGroupModel) {
+ const values = (controlModel as any).value;
+ values.forEach((groupValue, groupIndex) => {
+ const newGroupValue = Object.create({});
+ Object.keys(groupValue)
+ .forEach((key) => {
+ const normValue = normalizeValue(controlModel, groupValue[key], groupIndex);
+ if (iterateResult.hasOwnProperty(key)) {
+ iterateResult[key].push(normValue);
+ } else {
+ iterateResult[key] = [normValue];
+ }
+ // newGroupValue[key] = normalizeValue(controlModel, groupValue[key], groupIndex);
+ });
+ // controlArrayValue.push(newGroupValue);
+ })
+ } else if (isNotUndefined((controlModel as any).value) && isNotEmpty((controlModel as any).value)) {
+ const controlArrayValue = [];
+ // Normalize control value as an array of FormFieldMetadataValueObject
+ const values = Array.isArray((controlModel as any).value) ? (controlModel as any).value : [(controlModel as any).value];
+ values.forEach((controlValue) => {
+ controlArrayValue.push(normalizeValue(controlModel, controlValue, controlModelIndex))
+ });
+
+ if (controlId && iterateResult.hasOwnProperty(controlId) && isNotNull(iterateResult[controlId])) {
+ iterateResult[controlId] = iterateResult[controlId].concat(controlArrayValue);
+ } else {
+ iterateResult[controlId] = isNotEmpty(controlArrayValue) ? controlArrayValue : null;
+ }
}
+
}
return iterateResult;
@@ -182,16 +227,29 @@ export class FormBuilderService extends DynamicFormService {
|| model.parent instanceof DynamicGroupModel);
}
+ isComboboxGroup(model: DynamicFormControlModel) {
+ return model && model instanceof DynamicComboboxModel;
+ }
+
isCustomGroup(model: DynamicFormControlModel) {
return model &&
(model instanceof DynamicConcatModel
|| model instanceof DynamicComboboxModel
- || model instanceof DynamicListCheckboxGroupModel
+ || this.isListGroup(model));
+ }
+
+ isListGroup(model: DynamicFormControlModel) {
+ return model &&
+ (model instanceof DynamicListCheckboxGroupModel
|| model instanceof DynamicListRadioGroupModel);
}
isModelInAuthorityGroup(model: DynamicFormControlModel) {
- return (model instanceof DynamicListCheckboxGroupModel || model instanceof DynamicTagModel);
+ return model && (this.isListGroup(model) || model.type === DYNAMIC_FORM_CONTROL_TYPE_TAG);
+ }
+
+ isRelationGroup(model: DynamicFormControlModel) {
+ return model && model.type === DYNAMIC_FORM_CONTROL_TYPE_RELATION;
}
getFormControlById(id: string, formGroup: FormGroup, groupModel: DynamicFormControlModel[], index = 0) {
diff --git a/src/app/shared/form/builder/models/form-field-metadata-value.model.ts b/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
index 7379d62de6..ebcdc9264c 100644
--- a/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
+++ b/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
@@ -2,7 +2,7 @@ import { isNotEmpty } from '../../../empty.util';
export class FormFieldMetadataValueObject {
metadata?: string;
- value: string;
+ value: any;
display: string;
language: any;
authority: string;
@@ -11,14 +11,14 @@ export class FormFieldMetadataValueObject {
closed: boolean;
label: string;
- constructor(value: string,
+ constructor(value: any = null,
language: any = null,
authority: string = null,
display: string = null,
+ place: number = 0,
confidence: number = -1,
- place: number = -1,
metadata: string = null) {
- this.value = value;
+ this.value = isNotNull(value) ? ((typeof value === 'string') ? value.trim() : value) : null;
this.language = language;
this.authority = authority;
this.display = display || value;
@@ -39,4 +39,8 @@ export class FormFieldMetadataValueObject {
hasAuthority(): boolean {
return isNotEmpty(this.authority);
}
+
+ hasValue(): boolean {
+ return isNotEmpty(this.value);
+ }
}
diff --git a/src/app/shared/form/builder/parsers/date-field-parser.ts b/src/app/shared/form/builder/parsers/date-field-parser.ts
index 57e4a4cacb..6ad244f298 100644
--- a/src/app/shared/form/builder/parsers/date-field-parser.ts
+++ b/src/app/shared/form/builder/parsers/date-field-parser.ts
@@ -4,20 +4,19 @@ import { FormFieldModel } from '../models/form-field.model';
import { DynamicDsDatePickerModel } from '../ds-dynamic-form-ui/models/date-picker/date-picker.model';
import { isNotEmpty } from '../../../empty.util';
import { DS_DATE_PICKER_SEPARATOR } from '../ds-dynamic-form-ui/models/date-picker/date-picker.component';
+import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
export class DateFieldParser extends FieldParser {
- public modelFactory(): any {
+ public modelFactory(fieldValue: FormFieldMetadataValueObject): any {
const inputDateModelConfig: DynamicDatePickerModelConfig = this.initModel();
inputDateModelConfig.toggleIcon = 'fa fa-calendar';
-
- const dateModel = new DynamicDsDatePickerModel(inputDateModelConfig);
-
+ this.setValues(inputDateModelConfig as any, fieldValue);
// Init Data and validity check
- if (isNotEmpty(this.getInitFieldValue())) {
+ if (isNotEmpty(inputDateModelConfig.value)) {
let malformedData = false;
- const value = this.getInitFieldValue().toString();
+ const value = inputDateModelConfig.value.toString();
if (value.length >= 4) {
const valuesArray = value.split(DS_DATE_PICKER_SEPARATOR);
if (valuesArray.length < 4) {
@@ -29,12 +28,8 @@ export class DateFieldParser extends FieldParser {
}
}
- if (!malformedData) {
- dateModel.valueUpdates.next(this.getInitFieldValue());
- } else {
+ if (malformedData) {
// TODO Set error message
- dateModel.malformedDate = true;
- // TODO
// const errorMessage = 'The stored date is not compliant';
// dateModel.validators = Object.assign({}, dateModel.validators, {malformedDate: null});
// dateModel.errorMessages = Object.assign({}, dateModel.errorMessages, {malformedDate: errorMessage});
@@ -44,6 +39,7 @@ export class DateFieldParser extends FieldParser {
}
}
+ const dateModel = new DynamicDsDatePickerModel(inputDateModelConfig);
return dateModel;
}
}
diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts
index 29a133171d..9845f1772d 100644
--- a/src/app/shared/form/builder/parsers/field-parser.ts
+++ b/src/app/shared/form/builder/parsers/field-parser.ts
@@ -118,9 +118,9 @@ export abstract class FieldParser {
const values: FormFieldMetadataValueObject[] = [];
fieldIds.forEach((id) => {
if (this.initFormValues.hasOwnProperty(id)) {
- const valueObj: FormFieldMetadataValueObject = Object.create({});
+ const valueObj: FormFieldMetadataValueObject = Object.assign(new FormFieldMetadataValueObject(), this.initFormValues[id][innerIndex]);
valueObj.metadata = id;
- valueObj.value = this.initFormValues[id][innerIndex];
+ // valueObj.value = this.initFormValues[id][innerIndex];
values.push(valueObj);
}
});
@@ -243,16 +243,21 @@ export abstract class FieldParser {
if (typeof fieldValue === 'object') {
modelConfig.language = fieldValue.language;
- if (hasValue(fieldValue.language)) {
- // Instance of FormFieldLanguageValueObject
- modelConfig.value = fieldValue.value;
- } else if (hasValue(fieldValue.metadata)) {
- // Is a combobox field's value
- modelConfig.value = fieldValue.value;
- } else {
- // Instance of FormFieldMetadataValueObject
+ if (forceValueAsObj) {
modelConfig.value = fieldValue;
+ } else {
+ modelConfig.value = fieldValue.value;
}
+ // if (hasValue(fieldValue.language)) {
+ // // Instance of FormFieldLanguageValueObject
+ // modelConfig.value = fieldValue.value;
+ // } else if (hasValue(fieldValue.metadata)) {
+ // // Is a combobox field's value
+ // modelConfig.value = fieldValue.value;
+ // } else {
+ // // Instance of FormFieldMetadataValueObject
+ // modelConfig.value = fieldValue;
+ // }
} else {
if (forceValueAsObj) {
// If value isn't an instance of FormFieldMetadataValueObject instantiate it
diff --git a/src/app/shared/form/builder/parsers/onebox-field-parser.ts b/src/app/shared/form/builder/parsers/onebox-field-parser.ts
index 3b1bfc935c..c5a4f50e0c 100644
--- a/src/app/shared/form/builder/parsers/onebox-field-parser.ts
+++ b/src/app/shared/form/builder/parsers/onebox-field-parser.ts
@@ -68,7 +68,6 @@ export class OneboxFieldParser extends FieldParser {
if (isNotEmpty(fieldValue)) {
selectModelConfig.value = fieldValue.metadata;
}
- selectModelConfig.disabled = true;
inputSelectGroup.group.push(new DynamicSelectModel(selectModelConfig, clsSelect));
const inputModelConfig: DsDynamicInputModelConfig = this.initModel(newId + COMBOBOX_VALUE_SUFFIX, true, true);
diff --git a/src/app/shared/form/form.actions.ts b/src/app/shared/form/form.actions.ts
index b1d5f2b3e3..7023d6bba1 100644
--- a/src/app/shared/form/form.actions.ts
+++ b/src/app/shared/form/form.actions.ts
@@ -114,6 +114,29 @@ export class FormAddError implements Action {
}
}
+export class FormRemoveErrorAction implements Action {
+ type = FormActionTypes.FORM_REMOVE_ERROR;
+ payload: {
+ formId: string,
+ fieldId: string
+ };
+
+ constructor(formId: string, fieldId: string) {
+ this.payload = {formId, fieldId};
+ }
+}
+
+export class FormClearErrorsAction implements Action {
+ type = FormActionTypes.FORM_CLEAR_ERRORS;
+ payload: {
+ formId: string
+ };
+
+ constructor(formId: string) {
+ this.payload = {formId};
+ }
+}
+
/* tslint:enable:max-classes-per-file */
/**
@@ -125,3 +148,5 @@ export type FormAction = FormInitAction
| FormRemoveAction
| FormStatusChangeAction
| FormAddError
+ | FormClearErrorsAction
+ | FormRemoveErrorAction
diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts
index 99712bde9c..981aed083e 100644
--- a/src/app/shared/form/form.component.ts
+++ b/src/app/shared/form/form.component.ts
@@ -10,7 +10,13 @@ import {
import { Store } from '@ngrx/store';
import { AppState } from '../../app.reducer';
-import { FormChangeAction, FormInitAction, FormRemoveAction, FormStatusChangeAction } from './form.actions';
+import {
+ FormChangeAction,
+ FormInitAction,
+ FormRemoveAction,
+ FormRemoveErrorAction,
+ FormStatusChangeAction
+} from './form.actions';
import { FormBuilderService } from './builder/form-builder.service';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
@@ -144,7 +150,7 @@ export class FormComponent implements OnDestroy, OnInit {
.filter((formState: FormEntry) => !!formState && !isEmpty(formState.errors))
.map((formState) => formState.errors)
.distinctUntilChanged()
- .delay(100) // this terrible delay is here to prevent the detection change error
+ // .delay(100) // this terrible delay is here to prevent the detection change error
.subscribe((errors: FormError[]) => {
const {formGroup, formModel} = this;
@@ -172,10 +178,10 @@ export class FormComponent implements OnDestroy, OnInit {
* Method provided by Angular. Invoked when the instance is destroyed
*/
ngOnDestroy() {
- this.store.dispatch(new FormRemoveAction(this.formId));
this.subs
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
+ this.store.dispatch(new FormRemoveAction(this.formId));
}
/**
@@ -206,7 +212,6 @@ export class FormComponent implements OnDestroy, OnInit {
}
onChange(event) {
- console.log(event, this.formGroup);
const action: FormChangeAction = new FormChangeAction(this.formId, this.formBuilderService.getValueFromModel(this.formModel));
this.store.dispatch(action);
@@ -215,7 +220,10 @@ export class FormComponent implements OnDestroy, OnInit {
this.change.emit(event);
const control: FormControl = event.control;
- control.setErrors(null);
+ // control.setErrors(null);
+ if (control.valid) {
+ this.store.dispatch(new FormRemoveErrorAction(this.formId, event.model.id));
+ }
}
/**
diff --git a/src/app/shared/form/form.reducers.ts b/src/app/shared/form/form.reducers.ts
index d06db331eb..c65f2405ec 100644
--- a/src/app/shared/form/form.reducers.ts
+++ b/src/app/shared/form/form.reducers.ts
@@ -1,9 +1,15 @@
import {
- FormAction, FormActionTypes, FormAddError, FormChangeAction, FormInitAction, FormRemoveAction,
+ FormAction,
+ FormActionTypes,
+ FormAddError,
+ FormChangeAction, FormClearErrorsAction,
+ FormInitAction,
+ FormRemoveAction,
+ FormRemoveErrorAction,
FormStatusChangeAction
} from './form.actions';
import { hasValue } from '../empty.util';
-import { uniqWith, isEqual } from 'lodash';
+import { isEqual, uniqWith } from 'lodash';
export interface FormError {
message: string;
@@ -45,6 +51,14 @@ export function formReducer(state = initialState, action: FormAction): FormState
return addFormErrors(state, action as FormAddError)
}
+ case FormActionTypes.FORM_REMOVE_ERROR: {
+ return removeFormError(state, action as FormRemoveErrorAction)
+ }
+
+ case FormActionTypes.FORM_CLEAR_ERRORS: {
+ return clearsFormErrors(state, action as FormClearErrorsAction)
+ }
+
default: {
return state;
}
@@ -60,7 +74,7 @@ function addFormErrors(state: FormState, action: FormAddError) {
};
return Object.assign({}, state, {
- [ formId ]: {
+ [formId]: {
data: state[formId].data,
valid: state[formId].valid,
errors: state[formId].errors ? uniqWith(state[formId].errors.concat(error), isEqual) : [].concat(error),
@@ -71,6 +85,31 @@ function addFormErrors(state: FormState, action: FormAddError) {
}
}
+function removeFormError(state: FormState, action: FormRemoveErrorAction) {
+ const formId = action.payload.formId;
+ const fieldId = action.payload.fieldId;
+ if (hasValue(state[formId])) {
+ const errors = state[formId].errors.filter((error) => error.fieldId !== fieldId);
+ const newState = Object.assign({}, state);
+ newState[formId] = Object.assign({}, state[formId], {errors});
+ return newState;
+ } else {
+ return state;
+ }
+}
+
+function clearsFormErrors(state: FormState, action: FormClearErrorsAction) {
+ const formId = action.payload.formId;
+ if (hasValue(state[formId])) {
+ const errors = [];
+ const newState = Object.assign({}, state);
+ newState[formId] = Object.assign({}, state[formId], {errors});
+ return newState;
+ } else {
+ return state;
+ }
+}
+
/**
* Init form state.
*
@@ -82,22 +121,18 @@ function addFormErrors(state: FormState, action: FormAddError) {
* the new state, with the form initialized.
*/
function initForm(state: FormState, action: FormInitAction): FormState {
- if (!hasValue(state[ action.payload.formId ])) {
+ const formState = {
+ data: action.payload.formData,
+ valid: action.payload.valid,
+ errors: []
+ };
+ if (!hasValue(state[action.payload.formId])) {
return Object.assign({}, state, {
- [ action.payload.formId ]: {
- data: action.payload.formData,
- valid: action.payload.valid,
- errors: []
- }
+ [action.payload.formId]: formState
});
} else {
const newState = Object.assign({}, state);
- newState[ action.payload.formId ] = Object.assign({}, newState[ action.payload.formId ], {
- data: action.payload.formData,
- valid: action.payload.valid,
- errors: []
- }
- );
+ newState[action.payload.formId] = Object.assign({}, newState[action.payload.formId], formState);
return newState;
}
}
@@ -113,18 +148,18 @@ function initForm(state: FormState, action: FormInitAction): FormState {
* the new state, with the data changed.
*/
function changeDataForm(state: FormState, action: FormChangeAction): FormState {
- if (!hasValue(state[ action.payload.formId ])) {
+ if (!hasValue(state[action.payload.formId])) {
return Object.assign({}, state, {
- [ action.payload.formId ]: {
+ [action.payload.formId]: {
data: action.payload.formData,
- valid: state[ action.payload.formId ].valid
+ valid: state[action.payload.formId].valid
}
});
} else {
const newState = Object.assign({}, state);
- newState[ action.payload.formId ] = Object.assign({}, newState[ action.payload.formId ], {
+ newState[action.payload.formId] = Object.assign({}, newState[action.payload.formId], {
data: action.payload.formData,
- valid: state[ action.payload.formId ].valid
+ valid: state[action.payload.formId].valid
}
);
return newState;
@@ -142,17 +177,17 @@ function changeDataForm(state: FormState, action: FormChangeAction): FormState {
* the new state, with the status changed.
*/
function changeStatusForm(state: FormState, action: FormStatusChangeAction): FormState {
- if (!hasValue(state[ action.payload.formId ])) {
+ if (!hasValue(state[action.payload.formId])) {
return Object.assign({}, state, {
- [ action.payload.formId ]: {
- data: state[ action.payload.formId ].data,
+ [action.payload.formId]: {
+ data: state[action.payload.formId].data,
valid: action.payload.valid
}
});
} else {
const newState = Object.assign({}, state);
- newState[ action.payload.formId ] = Object.assign({}, newState[ action.payload.formId ], {
- data: state[ action.payload.formId ].data,
+ newState[action.payload.formId] = Object.assign({}, newState[action.payload.formId], {
+ data: state[action.payload.formId].data,
valid: action.payload.valid
}
);
@@ -171,9 +206,9 @@ function changeStatusForm(state: FormState, action: FormStatusChangeAction): For
* the new state, with the form initialized.
*/
function removeForm(state: FormState, action: FormRemoveAction): FormState {
- if (hasValue(state[ action.payload.formId ])) {
+ if (hasValue(state[action.payload.formId])) {
const newState = Object.assign({}, state);
- delete newState[ action.payload.formId ];
+ delete newState[action.payload.formId];
return newState;
} else {
return state;
diff --git a/src/app/shared/form/form.service.ts b/src/app/shared/form/form.service.ts
index 2adef27179..f890d90012 100644
--- a/src/app/shared/form/form.service.ts
+++ b/src/app/shared/form/form.service.ts
@@ -84,7 +84,7 @@ export class FormService {
error[errorKey] = message; // assign message
- // if form control model has errorMessages object, create it
+ // if form control model has not errorMessages object, create it
if (!model.errorMessages) {
model.errorMessages = {};
}
diff --git a/src/app/shared/number-picker/number-picker.component.html b/src/app/shared/number-picker/number-picker.component.html
index 5eb45a0bfb..55e0c39078 100644
--- a/src/app/shared/number-picker/number-picker.component.html
+++ b/src/app/shared/number-picker/number-picker.component.html
@@ -1,7 +1,8 @@
-
+
@@ -9,22 +10,23 @@
diff --git a/src/app/shared/number-picker/number-picker.component.scss b/src/app/shared/number-picker/number-picker.component.scss
index 33ed45b295..4fa2f3ac21 100644
--- a/src/app/shared/number-picker/number-picker.component.scss
+++ b/src/app/shared/number-picker/number-picker.component.scss
@@ -1,17 +1,7 @@
-.ngb-tp {
- display: flex;
- align-items: center;
-}
-.ngb-tp-hour, .ngb-tp-minute, .ngb-tp-second, .ngb-tp-meridian {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-around;
-}
-.ngb-tp-spacer {
- width: 1em;
- text-align: center;
+:host {
+ outline: none;
}
+
.chevron::before {
border-style: solid;
border-width: 0.29em 0.29em 0 0;
@@ -33,12 +23,7 @@
-ms-transform: rotate(135deg);
transform: rotate(135deg);
}
+
input {
- text-align: center;
- display: inline-block;
max-width: 80px !important;
}
-
-//.error {
-// border-color: red;
-//}
diff --git a/src/app/shared/number-picker/number-picker.component.ts b/src/app/shared/number-picker/number-picker.component.ts
index 67b5107b79..b4172b7182 100644
--- a/src/app/shared/number-picker/number-picker.component.ts
+++ b/src/app/shared/number-picker/number-picker.component.ts
@@ -11,31 +11,22 @@ import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/f
})
export class NumberPickerComponent implements OnInit, ControlValueAccessor {
- @Output()
- selected = new EventEmitter();
- @Output()
- remove = new EventEmitter();
- @Output()
- change = new EventEmitter();
- @Input()
- step: number;
- @Input()
- min: number;
- @Input()
- max: number;
- @Input()
- size: number;
- @Input()
- placeholder: string;
- @Input()
- name: string;
- @Input()
- disabled: boolean;
- @Input()
- invalid: boolean;
- @Input()
- value: number;
+ @Input() step: number;
+ @Input() min: number;
+ @Input() max: number;
+ @Input() size: number;
+ @Input() placeholder: string;
+ @Input() name: string;
+ @Input() disabled: boolean;
+ @Input() invalid: boolean;
+ @Input() value: number;
+
+ @Output() selected = new EventEmitter();
+ @Output() remove = new EventEmitter();
+ @Output() change = new EventEmitter();
+ @Output() focus = new EventEmitter();
+
lastValue: number;
constructor(private fb: FormBuilder, private cd: ChangeDetectorRef) {
@@ -109,19 +100,18 @@ export class NumberPickerComponent implements OnInit, ControlValueAccessor {
this.value = null;
this.emitChange();
} else {
- this.value = this.lastValue;
- this.emitChange();
+ this.value = undefined;
}
} catch (e) {
- this.value = this.lastValue;
- this.emitChange();
+ this.value = undefined;
}
}
- onFocus() {
+ onFocus(event) {
if (this.value) {
this.lastValue = this.value;
}
+ this.focus.emit(event);
}
writeValue(value) {
@@ -135,10 +125,11 @@ export class NumberPickerComponent implements OnInit, ControlValueAccessor {
}
registerOnChange(fn) {
- // this.change = fn;
+ return
}
registerOnTouched(fn) {
+ return
}
emitChange() {