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 {action, computed, makeObservable, observable, reaction} from "mobx";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
|
||||||
export class ReactiveValue<T> {
|
export class ReactiveValue<T> {
|
||||||
@observable private val: T;
|
@observable private val: T;
|
||||||
@observable private isTouched: boolean = false;
|
@observable private isTouched: boolean = false;
|
||||||
@observable private validators: ((value: T, field: string) => string)[] = [];
|
@observable private validators: ((value: T, field: string) => string)[] = [];
|
||||||
|
@observable private inputRestrictions: ((value: T, field: string) => string)[] = [];
|
||||||
@observable private errors: string[] = [];
|
@observable private errors: string[] = [];
|
||||||
|
@observable private inputRestrictionError: string;
|
||||||
@observable private fieldName: string;
|
@observable private fieldName: string;
|
||||||
|
|
||||||
constructor(fireImmediately: boolean = false) {
|
constructor(fireImmediately: boolean = false) {
|
||||||
@ -13,8 +16,10 @@ export class ReactiveValue<T> {
|
|||||||
reaction(() => ({value: this.val, touched: this.isTouched}), () => {
|
reaction(() => ({value: this.val, touched: this.isTouched}), () => {
|
||||||
if (!this.isTouched) {
|
if (!this.isTouched) {
|
||||||
this.errors = [];
|
this.errors = [];
|
||||||
|
this.inputRestrictionError = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.errors = this.validators
|
this.errors = this.validators
|
||||||
.map(validator => validator(this.val, this.fieldName))
|
.map(validator => validator(this.val, this.fieldName))
|
||||||
.filter(error => error && error.length > 0);
|
.filter(error => error && error.length > 0);
|
||||||
@ -28,8 +33,23 @@ export class ReactiveValue<T> {
|
|||||||
|
|
||||||
@action.bound
|
@action.bound
|
||||||
set(value: T) {
|
set(value: T) {
|
||||||
this.val = value;
|
|
||||||
this.isTouched = true;
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,23 +76,35 @@ export class ReactiveValue<T> {
|
|||||||
|
|
||||||
@action.bound
|
@action.bound
|
||||||
addValidator(validator: (value: T, field?: string) => string) {
|
addValidator(validator: (value: T, field?: string) => string) {
|
||||||
this.validators.push(validator);
|
if (validator) {
|
||||||
|
this.validators.push(validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action.bound
|
||||||
|
addInputRestriction(restriction: (value: T) => string) {
|
||||||
|
if (restriction) {
|
||||||
|
this.inputRestrictions.push(restriction);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
get invalid() {
|
get invalid() {
|
||||||
return this.errors.length > 0;
|
return this.errors.length > 0 || !!this.inputRestrictionError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
get allErrors() {
|
get allErrors() {
|
||||||
return this.errors;
|
return [...this.errors, this.inputRestrictionError].filter(error => error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
get firstError() {
|
get firstError() {
|
||||||
return this.errors[0];
|
return this.inputRestrictionError ?? this.errors[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@action.bound
|
@action.bound
|
||||||
@ -87,9 +119,10 @@ export class ReactiveValue<T> {
|
|||||||
|
|
||||||
@action.bound
|
@action.bound
|
||||||
clear() {
|
clear() {
|
||||||
this.val = null;
|
this.val = undefined;
|
||||||
this.isTouched = false;
|
this.isTouched = false;
|
||||||
this.errors = [];
|
this.errors = [];
|
||||||
|
this.inputRestrictionError = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user