diff --git a/core/app/fields/base/base-field.component.ts b/core/app/fields/base/base-field.component.ts
index bda0e7ccf..06df77e57 100644
--- a/core/app/fields/base/base-field.component.ts
+++ b/core/app/fields/base/base-field.component.ts
@@ -27,11 +27,15 @@ export class BaseFieldComponent implements FieldComponentInterface {
newValue = this.typeFormatter.toInternalFormat(this.field.type, newValue);
}
- this.field.value = newValue;
+ this.setFieldValue(newValue);
}));
}
}
+ protected setFieldValue(newValue): void {
+ this.field.value = newValue;
+ }
+
protected unsubscribeAll(): void {
this.subs.forEach(sub => sub.unsubscribe());
}
diff --git a/core/app/fields/field.component.spec.ts b/core/app/fields/field.component.spec.ts
index b11a45ebd..4bb64bfe2 100644
--- a/core/app/fields/field.component.spec.ts
+++ b/core/app/fields/field.component.spec.ts
@@ -45,7 +45,7 @@ class FieldTestHostComponent {
{field: buildField({type: 'varchar', value: 'My Varchar'}), mode: 'list', expected: 'My Varchar'},
{field: buildField({type: 'varchar', value: 'My Varchar'}), mode: 'edit', expected: 'My Varchar'},
{
- field: buildField({type: 'varchar', criteria: {values: ['test'], operator: '='}}),
+ field: buildField({type: 'varchar', value: 'test', criteria: {values: ['test'], operator: '='}}),
mode: 'filter',
expected: 'test'
},
diff --git a/core/app/fields/field.component.ts b/core/app/fields/field.component.ts
index 455eb77bd..76533fe64 100644
--- a/core/app/fields/field.component.ts
+++ b/core/app/fields/field.component.ts
@@ -50,7 +50,7 @@ export class FieldComponent {
}
isEdit(): boolean {
- return this.mode === 'edit';
+ return this.mode === 'edit' || this.mode === 'filter';
}
getLink(): string {
diff --git a/core/app/fields/varchar/templates/filter/filter.component.html b/core/app/fields/varchar/templates/filter/filter.component.html
index 23f10e579..56a8d8fd7 100644
--- a/core/app/fields/varchar/templates/filter/filter.component.html
+++ b/core/app/fields/varchar/templates/filter/filter.component.html
@@ -1 +1,4 @@
-
\ No newline at end of file
+
diff --git a/core/app/fields/varchar/templates/filter/filter.component.spec.ts b/core/app/fields/varchar/templates/filter/filter.component.spec.ts
index 022b7d135..8f38e3d10 100644
--- a/core/app/fields/varchar/templates/filter/filter.component.spec.ts
+++ b/core/app/fields/varchar/templates/filter/filter.component.spec.ts
@@ -1,7 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {Component} from '@angular/core';
import {VarcharFilterFieldComponent} from './filter.component';
-import {FormsModule} from '@angular/forms';
import {Field} from '@app-common/record/field.model';
import {UserPreferenceStore} from '@store/user-preference/user-preference.store';
import {userPreferenceStoreMock} from '@store/user-preference/user-preference.store.spec.mock';
@@ -12,6 +11,9 @@ import {datetimeFormatterMock} from '@services/formatters/datetime/datetime-form
import {DateFormatter} from '@services/formatters/datetime/date-formatter.service';
import {dateFormatterMock} from '@services/formatters/datetime/date-formatter.service.spec.mock';
import {CurrencyFormatter} from '@services/formatters/currency/currency-formatter.service';
+import {VarcharFilterFieldModule} from '@fields/varchar/templates/filter/filter.module';
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+import {FormControl} from '@angular/forms';
@Component({
selector: 'varchar-filter-field-test-host-component',
@@ -20,10 +22,12 @@ import {CurrencyFormatter} from '@services/formatters/currency/currency-formatte
class VarcharFilterFieldTestHostComponent {
field: Field = {
type: 'varchar',
+ value: 'test filter value',
criteria: {
values: ['test filter value'],
operator: '='
- }
+ },
+ formControl: new FormControl('test filter value')
};
}
@@ -38,7 +42,8 @@ describe('VarcharFilterFieldComponent', () => {
VarcharFilterFieldComponent,
],
imports: [
- FormsModule
+ VarcharFilterFieldModule,
+ BrowserAnimationsModule
],
providers: [
{provide: UserPreferenceStore, useValue: userPreferenceStoreMock},
@@ -70,7 +75,7 @@ describe('VarcharFilterFieldComponent', () => {
it('should have update input when field changes', async(() => {
expect(testHostComponent).toBeTruthy();
- testHostComponent.field.criteria.values = ['New Field value'];
+ testHostComponent.field.formControl.setValue('New Field value');
testHostFixture.detectChanges();
testHostFixture.whenStable().then(() => {
diff --git a/core/app/fields/varchar/templates/filter/filter.component.ts b/core/app/fields/varchar/templates/filter/filter.component.ts
index 1814a748e..8849254db 100644
--- a/core/app/fields/varchar/templates/filter/filter.component.ts
+++ b/core/app/fields/varchar/templates/filter/filter.component.ts
@@ -1,4 +1,4 @@
-import {Component} from '@angular/core';
+import {Component, OnDestroy, OnInit} from '@angular/core';
import {BaseFieldComponent} from '@fields/base/base-field.component';
import {DataTypeFormatter} from '@services/formatters/data-type.formatter.service';
@@ -7,23 +7,31 @@ import {DataTypeFormatter} from '@services/formatters/data-type.formatter.servic
templateUrl: './filter.component.html',
styleUrls: []
})
-export class VarcharFilterFieldComponent extends BaseFieldComponent {
+export class VarcharFilterFieldComponent extends BaseFieldComponent implements OnInit, OnDestroy {
constructor(protected typeFormatter: DataTypeFormatter) {
super(typeFormatter);
}
- get value(): string {
+ ngOnInit(): void {
let current = '';
if (this.field.criteria.values && this.field.criteria.values.length > 0) {
current = this.field.criteria.values[0];
}
- return current;
+ this.field.value = current;
+ const formattedValue = this.typeFormatter.toUserFormat(this.field.type, current, {mode: 'edit'});
+ this.field.formControl.setValue(formattedValue);
+
+ this.subscribeValueChanges();
}
- set value(newValue: string) {
+ ngOnDestroy(): void {
+ this.unsubscribeAll();
+ }
+
+ protected setFieldValue(newValue): void {
this.field.value = newValue;
this.field.criteria.operator = '=';
this.field.criteria.values = [newValue];
diff --git a/core/app/fields/varchar/templates/filter/filter.module.ts b/core/app/fields/varchar/templates/filter/filter.module.ts
index 33647c4f7..e127e5570 100644
--- a/core/app/fields/varchar/templates/filter/filter.module.ts
+++ b/core/app/fields/varchar/templates/filter/filter.module.ts
@@ -3,7 +3,7 @@ import {CommonModule} from '@angular/common';
import {AppManagerModule} from '@base/app-manager/app-manager.module';
import {VarcharFilterFieldComponent} from './filter.component';
-import {FormsModule} from '@angular/forms';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
@NgModule({
declarations: [VarcharFilterFieldComponent],
@@ -11,7 +11,8 @@ import {FormsModule} from '@angular/forms';
imports: [
CommonModule,
AppManagerModule.forChild(VarcharFilterFieldComponent),
- FormsModule
+ FormsModule,
+ ReactiveFormsModule
]
})
export class VarcharFilterFieldModule {
diff --git a/core/app/src/app-common/metadata/list.metadata.model.ts b/core/app/src/app-common/metadata/list.metadata.model.ts
index 2fe3fe0b6..5e1fa87b4 100644
--- a/core/app/src/app-common/metadata/list.metadata.model.ts
+++ b/core/app/src/app-common/metadata/list.metadata.model.ts
@@ -3,6 +3,7 @@ import {BulkActionsMap} from '@app-common/actions/bulk-action.model';
import {LineAction} from '@app-common/actions/line-action.model';
import {ChartTypesMap} from '@app-common/containers/chart/chart.model';
import {WidgetMetadata} from '@app-common/metadata/widget.metadata';
+import {FieldDefinition} from '@app-common/record/field.model';
export interface ListViewMeta {
fields: ColumnDefinition[];
@@ -33,6 +34,7 @@ export interface SearchMetaField {
label?: string;
default?: boolean;
options?: string;
+ fieldDefinition?: FieldDefinition;
}
export interface SearchMeta {
diff --git a/core/app/src/app-common/record/record.model.ts b/core/app/src/app-common/record/record.model.ts
index af37c19a9..a8fa5b286 100644
--- a/core/app/src/app-common/record/record.model.ts
+++ b/core/app/src/app-common/record/record.model.ts
@@ -7,7 +7,7 @@ export interface AttributeMap {
export interface Record {
id?: string;
- type: string;
+ type?: string;
module: string;
attributes: AttributeMap;
fields?: FieldMap;
diff --git a/core/app/src/app-common/views/list/search-criteria.model.ts b/core/app/src/app-common/views/list/search-criteria.model.ts
index bff662bda..b95386443 100644
--- a/core/app/src/app-common/views/list/search-criteria.model.ts
+++ b/core/app/src/app-common/views/list/search-criteria.model.ts
@@ -1,5 +1,6 @@
export interface SearchCriteriaFieldFilter {
field?: string;
+ fieldType?: string;
operator: string;
values?: string[];
start?: string;
diff --git a/core/app/src/components/list-filter/list-filter.component.spec.ts b/core/app/src/components/list-filter/list-filter.component.spec.ts
index ecd1fbf88..bfbf9f91e 100644
--- a/core/app/src/components/list-filter/list-filter.component.spec.ts
+++ b/core/app/src/components/list-filter/list-filter.component.spec.ts
@@ -14,6 +14,7 @@ import {LanguageStore} from '@store/language/language.store';
import {languageStoreMock} from '@store/language/language.store.spec.mock';
import {RouterTestingModule} from '@angular/router/testing';
import {ApolloTestingModule} from 'apollo-angular/testing';
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
describe('ListFilterComponent', () => {
let testHostComponent: ListFilterComponent;
@@ -31,7 +32,8 @@ describe('ListFilterComponent', () => {
DropdownButtonModule,
FieldGridModule,
RouterTestingModule,
- ApolloTestingModule
+ ApolloTestingModule,
+ BrowserAnimationsModule
],
providers: [
{provide: ListViewStore, useValue: listviewStoreMock},
diff --git a/core/app/src/components/list-filter/list-filter.component.ts b/core/app/src/components/list-filter/list-filter.component.ts
index 53cc27ab2..c9b7b310c 100644
--- a/core/app/src/components/list-filter/list-filter.component.ts
+++ b/core/app/src/components/list-filter/list-filter.component.ts
@@ -5,10 +5,15 @@ import {DropdownButtonInterface} from '@components/dropdown-button/dropdown-butt
import {ButtonInterface} from '@components/button/button.model';
import {deepClone} from '@base/app-common/utils/object-utils';
import {combineLatest, Observable} from 'rxjs';
-import {map} from 'rxjs/operators';
-import {Field} from '@app-common/record/field.model';
+import {filter, map, startWith, take} from 'rxjs/operators';
+import {Field, FieldMap} from '@app-common/record/field.model';
import {SearchCriteria, SearchCriteriaFieldFilter} from '@app-common/views/list/search-criteria.model';
import {Filter, SearchMetaField} from '@app-common/metadata/list.metadata.model';
+import {FieldManager} from '@services/record/field/field.manager';
+import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
+import {Record} from '@app-common/record/record.model';
+import {AbstractControl, FormGroup} from '@angular/forms';
+import {MessageService} from '@services/message/message.service';
export interface FilterDataSource {
getFilter(): Observable;
@@ -34,8 +39,14 @@ export class ListFilterComponent implements OnInit {
searchCriteria: SearchCriteria;
vm$: Observable;
+ private record: Record;
- constructor(protected listStore: ListViewStore, protected language: LanguageStore) {
+ constructor(
+ protected listStore: ListViewStore,
+ protected language: LanguageStore,
+ protected fieldManager: FieldManager,
+ protected message: MessageService
+ ) {
this.vm$ = combineLatest([listStore.criteria$, listStore.metadata$]).pipe(
map(([criteria, metadata]) => {
@@ -51,6 +62,11 @@ export class ListFilterComponent implements OnInit {
this.reset();
+ this.record = {
+ module: this.listStore.getModuleName(),
+ attributes: {}
+ } as Record;
+
this.initFields();
this.initGridButtons();
this.initHeaderButtons();
@@ -72,15 +88,23 @@ export class ListFilterComponent implements OnInit {
}
const searchFields = searchMeta.layout[type];
+ const fields = {} as FieldMap;
+ const formControls = {} as { [key: string]: AbstractControl };
Object.keys(searchFields).forEach(key => {
const name = searchFields[key].name;
+
+ fields[name] = this.buildField(searchFields[key], languages, searchCriteria);
+ formControls[name] = fields[name].formControl;
+
if (name.includes('_only')) {
- this.special.push(this.buildField(searchFields[key], languages, searchCriteria));
+ this.special.push(fields[name]);
} else {
- this.fields.push(this.buildField(searchFields[key], languages, searchCriteria));
+ this.fields.push(fields[name]);
}
});
+
+ this.record.formGroup = new FormGroup(formControls);
}
protected reset(): void {
@@ -128,21 +152,34 @@ export class ListFilterComponent implements OnInit {
}
protected buildField(searchField: SearchMetaField, languages: LanguageStrings, searchCriteria: SearchCriteria): Field {
- const module = this.listStore.appState.module;
-
const fieldName = searchField.name;
- this.searchCriteria.filters[fieldName] = this.initFieldFilter(searchCriteria, fieldName);
+ const type = searchField.type;
+ this.searchCriteria.filters[fieldName] = this.initFieldFilter(searchCriteria, fieldName, type);
- return {
- type: 'varchar',
- value: '',
+ const definition = {
name: searchField.name,
- label: this.language.getFieldLabel(searchField.label, module, languages),
- criteria: this.searchCriteria.filters[fieldName]
- } as Field;
+ label: searchField.label,
+ type,
+ fieldDefinition: {}
+ } as ViewFieldDefinition;
+
+ if (searchField.fieldDefinition) {
+ definition.fieldDefinition = searchField.fieldDefinition;
+ }
+
+ if (type === 'bool' || type === 'boolean') {
+ definition.fieldDefinition.options = 'dom_int_bool';
+ }
+
+
+ const field = this.fieldManager.buildFilterField(this.record, definition, this.language);
+
+ field.criteria = this.searchCriteria.filters[fieldName];
+
+ return field;
}
- protected initFieldFilter(searchCriteria: SearchCriteria, fieldName: string): SearchCriteriaFieldFilter {
+ protected initFieldFilter(searchCriteria: SearchCriteria, fieldName: string, fieldType: string): SearchCriteriaFieldFilter {
let fieldCriteria: SearchCriteriaFieldFilter;
if (searchCriteria.filters[fieldName]) {
@@ -150,8 +187,9 @@ export class ListFilterComponent implements OnInit {
} else {
fieldCriteria = {
field: fieldName,
+ fieldType,
operator: '',
- values: [],
+ values: []
};
}
@@ -159,8 +197,28 @@ export class ListFilterComponent implements OnInit {
}
protected applyFilter(): void {
- this.listStore.showFilters = false;
- this.listStore.updateSearchCriteria(this.searchCriteria);
+ this.validate().pipe(take(1)).subscribe(valid => {
+
+ if (valid) {
+ this.listStore.showFilters = false;
+ this.listStore.updateSearchCriteria(this.searchCriteria);
+ return;
+ }
+
+ this.message.addWarningMessageByKey('LBL_VALIDATION_ERRORS');
+ });
+
+ }
+
+ protected validate(): Observable {
+
+ this.record.formGroup.markAllAsTouched();
+ return this.record.formGroup.statusChanges.pipe(
+ startWith(this.record.formGroup.status),
+ filter(status => status !== 'PENDING'),
+ take(1),
+ map(status => status === 'VALID')
+ );
}
protected clearFilter(): void {
diff --git a/core/app/src/services/formatters/datetime/datetime-formatter.service.ts b/core/app/src/services/formatters/datetime/datetime-formatter.service.ts
index f643686c5..5813ac9ae 100644
--- a/core/app/src/services/formatters/datetime/datetime-formatter.service.ts
+++ b/core/app/src/services/formatters/datetime/datetime-formatter.service.ts
@@ -91,7 +91,17 @@ export class DatetimeFormatter implements Formatter {
}
toUserFormat(dateString: string): string {
- return formatDate(dateString, this.getUserFormat(), this.locale);
+ if (!dateString) {
+ return '';
+ }
+
+ const dateTime = this.toDateTime(dateString);
+
+ if (!dateTime.isValid) {
+ return '';
+ }
+
+ return formatDate(dateTime.toJSDate(), this.getUserFormat(), this.locale);
}
toInternalFormat(dateString: string): string {
diff --git a/core/app/src/services/record/field/field.manager.ts b/core/app/src/services/record/field/field.manager.ts
index a00b07481..0efdb652d 100644
--- a/core/app/src/services/record/field/field.manager.ts
+++ b/core/app/src/services/record/field/field.manager.ts
@@ -1,7 +1,7 @@
import {Record} from '@app-common/record/record.model';
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
import {LanguageStore} from '@store/language/language.store';
-import {FormControl} from '@angular/forms';
+import {AsyncValidatorFn, FormControl, ValidatorFn} from '@angular/forms';
import {Field, FieldDefinition} from '@app-common/record/field.model';
import {Injectable} from '@angular/core';
import {ValidationManager} from '@services/record/validation/validation.manager';
@@ -28,14 +28,40 @@ export class FieldManager {
public buildField(record: Record, viewField: ViewFieldDefinition, language: LanguageStore = null): Field {
const definition = (viewField && viewField.fieldDefinition) || {} as FieldDefinition;
+ const {value, valueList} = this.parseValue(viewField, definition, record);
+ const {validators, asyncValidators} = this.getValidators(record, viewField);
+
+ return this.setupField(viewField, value, valueList, record, definition, validators, asyncValidators, language);
+ }
+
+ public buildFilterField(record: Record, viewField: ViewFieldDefinition, language: LanguageStore = null): Field {
+
+ const definition = (viewField && viewField.fieldDefinition) || {} as FieldDefinition;
+ const {value, valueList} = this.parseValue(viewField, definition, record);
+ const {validators, asyncValidators} = this.getFilterValidators(record, viewField);
+
+ return this.setupField(viewField, value, valueList, record, definition, validators, asyncValidators, language);
+ }
+
+ public getFieldLabel(label: string, module: string, language: LanguageStore): string {
+ const languages = language.getLanguageStrings();
+ return language.getFieldLabel(label, module, languages);
+ }
+
+ protected parseValue(
+ viewField: ViewFieldDefinition,
+ definition: FieldDefinition,
+ record: Record
+ ): { value: string; valueList: string[] } {
+
const type = (viewField && viewField.type) || '';
const source = (definition && definition.source) || '';
const rname = (definition && definition.rname) || 'name';
const viewName = viewField.name || '';
- let value;
- let valueList = null;
+ let value: string;
+ let valueList: string[] = null;
- if (!viewName) {
+ if (!viewName || !record.attributes[viewName]) {
value = '';
} else if (type === 'relate' && source === 'non-db' && rname !== '') {
value = record.attributes[viewName][rname];
@@ -48,8 +74,40 @@ export class FieldManager {
value = null;
}
- const validators = this.validationManager.getValidations(record.module, viewField, record);
- const asyncValidators = this.validationManager.getAsyncValidations(record.module, viewField, record);
+ return {value, valueList};
+ }
+
+ protected getValidators(
+ record: Record,
+ viewField: ViewFieldDefinition
+ ): { validators: ValidatorFn[]; asyncValidators: AsyncValidatorFn[] } {
+
+ const validators = this.validationManager.getSaveValidations(record.module, viewField, record);
+ const asyncValidators = this.validationManager.getAsyncSaveValidations(record.module, viewField, record);
+ return {validators, asyncValidators};
+ }
+
+ protected getFilterValidators(
+ record: Record,
+ viewField: ViewFieldDefinition
+ ): { validators: ValidatorFn[]; asyncValidators: AsyncValidatorFn[] } {
+
+ const validators = this.validationManager.getFilterValidations(record.module, viewField, record);
+ const asyncValidators: AsyncValidatorFn[] = [];
+
+ return {validators, asyncValidators};
+ }
+
+ protected setupField(
+ viewField: ViewFieldDefinition,
+ value: string,
+ valueList: string[],
+ record: Record,
+ definition: FieldDefinition,
+ validators: ValidatorFn[],
+ asyncValidators: AsyncValidatorFn[],
+ language: LanguageStore
+ ): Field {
const formattedValue = this.typeFormatter.toUserFormat(viewField.type, value, {mode: 'edit'});
@@ -73,12 +131,6 @@ export class FieldManager {
if (language) {
field.label = this.getFieldLabel(viewField.label, record.module, language);
}
-
return field;
}
-
- public getFieldLabel(label: string, module: string, language: LanguageStore): string {
- const languages = language.getLanguageStrings();
- return language.getFieldLabel(label, module, languages);
- }
}
diff --git a/core/app/src/services/record/validation/validation.manager.ts b/core/app/src/services/record/validation/validation.manager.ts
index 7a77de99e..003a5ccf9 100644
--- a/core/app/src/services/record/validation/validation.manager.ts
+++ b/core/app/src/services/record/validation/validation.manager.ts
@@ -4,7 +4,7 @@ import {Record} from '@app-common/record/record.model';
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
import {AsyncValidatorFn, ValidatorFn} from '@angular/forms';
import {AsyncValidatorInterface} from '@services/record/validation/aync-validator.Interface';
-import {OverridableMap} from '@app-common/types/OverridableMap';
+import {MapEntry, OverridableMap} from '@app-common/types/OverridableMap';
import {RequiredValidator} from '@services/record/validation/validators/required.validator';
import {CurrencyValidator} from '@services/record/validation/validators/currency.validator';
import {DateValidator} from '@services/record/validation/validators/date.validator';
@@ -16,25 +16,32 @@ import {PhoneValidator} from '@services/record/validation/validators/phone.valid
import {RangeValidator} from '@services/record/validation/validators/range.validator';
export interface ValidationManagerInterface {
- registerValidator(module: string, key: string, validator: ValidatorInterface): void;
+ registerSaveValidator(module: string, key: string, validator: ValidatorInterface): void;
- excludeValidator(module: string, key: string): void;
+ registerFilterValidator(module: string, key: string, validator: ValidatorInterface): void;
- registerAsyncValidator(module: string, key: string, validator: AsyncValidatorInterface): void;
+ excludeSaveValidator(module: string, key: string): void;
- excludeAsyncValidator(module: string, key: string): void;
+ excludeFilterValidator(module: string, key: string): void;
- getValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[];
+ registerAsyncSaveValidator(module: string, key: string, validator: AsyncValidatorInterface): void;
- getAsyncValidations(module: string, viewField: ViewFieldDefinition, record: Record): AsyncValidatorFn[];
+ excludeAsyncSaveValidator(module: string, key: string): void;
+
+ getSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[];
+
+ getFilterValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[];
+
+ getAsyncSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): AsyncValidatorFn[];
}
@Injectable({
providedIn: 'root'
})
export class ValidationManager implements ValidationManagerInterface {
- protected validators: OverridableMap;
- protected asyncValidators: OverridableMap;
+ protected saveValidators: OverridableMap;
+ protected asyncSaveValidators: OverridableMap;
+ protected filterValidators: OverridableMap;
constructor(
protected requiredValidator: RequiredValidator,
@@ -48,57 +55,66 @@ export class ValidationManager implements ValidationManagerInterface {
protected phoneValidator: PhoneValidator,
) {
- this.validators = new OverridableMap();
- this.asyncValidators = new OverridableMap();
+ this.saveValidators = new OverridableMap();
+ this.asyncSaveValidators = new OverridableMap();
+ this.filterValidators = new OverridableMap();
- this.validators.addEntry('default', 'required', requiredValidator);
- this.validators.addEntry('default', 'range', rangeValidator);
- this.validators.addEntry('default', 'currency', currencyValidator);
- this.validators.addEntry('default', 'date', dateValidator);
- this.validators.addEntry('default', 'datetime', datetimeValidator);
- this.validators.addEntry('default', 'email', emailValidator);
- this.validators.addEntry('default', 'float', floatValidator);
- this.validators.addEntry('default', 'int', intValidator);
- this.validators.addEntry('default', 'phone', phoneValidator);
+ this.saveValidators.addEntry('default', 'required', requiredValidator);
+ this.saveValidators.addEntry('default', 'range', rangeValidator);
+ this.saveValidators.addEntry('default', 'currency', currencyValidator);
+ this.saveValidators.addEntry('default', 'date', dateValidator);
+ this.saveValidators.addEntry('default', 'datetime', datetimeValidator);
+ this.saveValidators.addEntry('default', 'email', emailValidator);
+ this.saveValidators.addEntry('default', 'float', floatValidator);
+ this.saveValidators.addEntry('default', 'int', intValidator);
+ this.saveValidators.addEntry('default', 'phone', phoneValidator);
+
+ this.filterValidators.addEntry('default', 'date', dateValidator);
+ this.filterValidators.addEntry('default', 'datetime', datetimeValidator);
+ this.filterValidators.addEntry('default', 'float', floatValidator);
+ this.filterValidators.addEntry('default', 'currency', currencyValidator);
+ this.filterValidators.addEntry('default', 'int', intValidator);
+ this.filterValidators.addEntry('default', 'phone', phoneValidator);
}
- public registerValidator(module: string, key: string, validator: ValidatorInterface): void {
- this.validators.addEntry(module, key, validator);
+ public registerSaveValidator(module: string, key: string, validator: ValidatorInterface): void {
+ this.filterValidators.addEntry(module, key, validator);
}
- public excludeValidator(module: string, key: string): void {
- this.validators.excludeEntry(module, key);
+ public registerFilterValidator(module: string, key: string, validator: ValidatorInterface): void {
+ this.saveValidators.addEntry(module, key, validator);
}
- public registerAsyncValidator(module: string, key: string, validator: AsyncValidatorInterface): void {
- this.asyncValidators.addEntry(module, key, validator);
+ public excludeSaveValidator(module: string, key: string): void {
+ this.saveValidators.excludeEntry(module, key);
}
- public excludeAsyncValidator(module: string, key: string): void {
- this.validators.excludeEntry(module, key);
+ public excludeFilterValidator(module: string, key: string): void {
+ this.filterValidators.excludeEntry(module, key);
}
- public getValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
- let validations = [];
-
- const entries = this.validators.getGroupEntries(module);
-
- Object.keys(entries).forEach(validatorKey => {
-
- const validator = entries[validatorKey];
-
- if (validator.applies(record, viewField)) {
- validations = validations.concat(validator.getValidator(viewField, record));
- }
- });
-
- return validations;
+ public registerAsyncSaveValidator(module: string, key: string, validator: AsyncValidatorInterface): void {
+ this.asyncSaveValidators.addEntry(module, key, validator);
}
- public getAsyncValidations(module: string, viewField: ViewFieldDefinition, record: Record): AsyncValidatorFn[] {
+ public excludeAsyncSaveValidator(module: string, key: string): void {
+ this.saveValidators.excludeEntry(module, key);
+ }
+
+ public getSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
+ const entries = this.saveValidators.getGroupEntries(module);
+ return this.filterValidations(entries, record, viewField);
+ }
+
+ public getFilterValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
+ const entries = this.filterValidators.getGroupEntries(module);
+ return this.filterValidations(entries, record, viewField);
+ }
+
+ public getAsyncSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): AsyncValidatorFn[] {
const validations = [];
- const entries = this.asyncValidators.getGroupEntries(module);
+ const entries = this.asyncSaveValidators.getGroupEntries(module);
Object.keys(entries).forEach(validatorKey => {
@@ -111,4 +127,19 @@ export class ValidationManager implements ValidationManagerInterface {
return validations;
}
+
+ protected filterValidations(entries: MapEntry, record: Record, viewField: ViewFieldDefinition): ValidatorFn[] {
+ let validations = [];
+
+ Object.keys(entries).forEach(validatorKey => {
+
+ const validator = entries[validatorKey];
+
+ if (validator.applies(record, viewField)) {
+ validations = validations.concat(validator.getValidator(viewField, record));
+ }
+ });
+
+ return validations;
+ }
}