add InputRestriction support for reactiveValue.ts
This commit is contained in:
parent
b1ea3a670e
commit
a5695ccab6
@ -1,11 +1,14 @@
|
||||
import {action, computed, makeObservable, observable, reaction} from "mobx";
|
||||
import _ from "lodash";
|
||||
|
||||
|
||||
export class ReactiveValue<T> {
|
||||
@observable private val: T;
|
||||
@observable private isTouched: boolean = false;
|
||||
@observable private validators: ((value: T, field: string) => string)[] = [];
|
||||
@observable private inputRestrictions: ((value: T, field: string) => string)[] = [];
|
||||
@observable private errors: string[] = [];
|
||||
@observable private inputRestrictionError: string;
|
||||
@observable private fieldName: string;
|
||||
|
||||
constructor(fireImmediately: boolean = false) {
|
||||
@ -13,8 +16,10 @@ export class ReactiveValue<T> {
|
||||
reaction(() => ({value: this.val, touched: this.isTouched}), () => {
|
||||
if (!this.isTouched) {
|
||||
this.errors = [];
|
||||
this.inputRestrictionError = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
this.errors = this.validators
|
||||
.map(validator => validator(this.val, this.fieldName))
|
||||
.filter(error => error && error.length > 0);
|
||||
@ -28,8 +33,23 @@ export class ReactiveValue<T> {
|
||||
|
||||
@action.bound
|
||||
set(value: T) {
|
||||
this.val = value;
|
||||
this.isTouched = true;
|
||||
this.inputRestrictionError = undefined;
|
||||
|
||||
if (!_.isEmpty(value)) {
|
||||
for (const restriction of this.inputRestrictions) {
|
||||
const error = restriction(value, this.fieldName);
|
||||
if (error) {
|
||||
this.inputRestrictionError = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const lengthIsLessIfStringOrTrue = _.isString(value) && _.isString(this.val) ? value.length < this.val?.length : true;
|
||||
if (!this.inputRestrictionError || lengthIsLessIfStringOrTrue) {
|
||||
this.setAuto(value);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -56,23 +76,35 @@ export class ReactiveValue<T> {
|
||||
|
||||
@action.bound
|
||||
addValidator(validator: (value: T, field?: string) => string) {
|
||||
if (validator) {
|
||||
this.validators.push(validator);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
addInputRestriction(restriction: (value: T) => string) {
|
||||
if (restriction) {
|
||||
this.inputRestrictions.push(restriction);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@computed
|
||||
get invalid() {
|
||||
return this.errors.length > 0;
|
||||
return this.errors.length > 0 || !!this.inputRestrictionError;
|
||||
}
|
||||
|
||||
@computed
|
||||
get allErrors() {
|
||||
return this.errors;
|
||||
return [...this.errors, this.inputRestrictionError].filter(error => error);
|
||||
}
|
||||
|
||||
@computed
|
||||
get firstError() {
|
||||
return this.errors[0];
|
||||
return this.inputRestrictionError ?? this.errors[0];
|
||||
}
|
||||
|
||||
@action.bound
|
||||
@ -87,9 +119,10 @@ export class ReactiveValue<T> {
|
||||
|
||||
@action.bound
|
||||
clear() {
|
||||
this.val = null;
|
||||
this.val = undefined;
|
||||
this.isTouched = false;
|
||||
this.errors = [];
|
||||
this.inputRestrictionError = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user