mobx-react-form
Version:
Reactive MobX Form State Management
1,022 lines • 41.9 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mobx_1 = require("mobx");
const lodash_1 = __importDefault(require("lodash"));
const Base_1 = __importDefault(require("./Base"));
const utils_1 = require("./utils");
const parser_1 = require("./parser");
const OptionsModel_1 = require("./models/OptionsModel");
const FieldProps_1 = require("./models/FieldProps");
const applyFieldPropFunc = (instance, prop) => {
if (typeof prop !== 'function')
return prop;
return prop.apply(instance, [{
field: instance,
form: instance.state.form
}]);
};
const retrieveFieldPropFunc = (prop) => (typeof prop === 'function') ? prop : undefined;
const propGetter = (instance, prop) => (typeof instance[`_${prop}`] === 'function')
? instance[`_${prop}`].apply(instance, [{
form: instance.state.form,
field: instance,
}]) : instance[`$${prop}`];
const setupFieldProps = (instance, props, data) => Object.assign(instance, {
// retrieve functions
_label: retrieveFieldPropFunc(props.$label || (data === null || data === void 0 ? void 0 : data.label)),
_placeholder: retrieveFieldPropFunc(props.$placeholder || (data === null || data === void 0 ? void 0 : data.placeholder)),
_disabled: retrieveFieldPropFunc(props.$disabled || (data === null || data === void 0 ? void 0 : data.disabled)),
_rules: retrieveFieldPropFunc(props.$rules || (data === null || data === void 0 ? void 0 : data.rules)),
_related: retrieveFieldPropFunc(props.$related || (data === null || data === void 0 ? void 0 : data.related)),
_deleted: retrieveFieldPropFunc(props.$deleted || (data === null || data === void 0 ? void 0 : data.deleted)),
_validators: retrieveFieldPropFunc(props.$validators || (data === null || data === void 0 ? void 0 : data.validators)),
_validatedWith: retrieveFieldPropFunc(props.$validatedWith || (data === null || data === void 0 ? void 0 : data.validatedWith)),
_bindings: retrieveFieldPropFunc(props.$bindings || (data === null || data === void 0 ? void 0 : data.bindings)),
_extra: retrieveFieldPropFunc(props.$extra || (data === null || data === void 0 ? void 0 : data.extra)),
_options: retrieveFieldPropFunc(props.$options || (data === null || data === void 0 ? void 0 : data.options)),
_autoFocus: retrieveFieldPropFunc(props.$autoFocus || (data === null || data === void 0 ? void 0 : data.autoFocus)),
_inputMode: retrieveFieldPropFunc(props.$inputMode || (data === null || data === void 0 ? void 0 : data.inputMode)),
// apply functions or value
$label: applyFieldPropFunc(instance, props.$label || (data === null || data === void 0 ? void 0 : data.label) || ""),
$placeholder: applyFieldPropFunc(instance, props.$placeholder || (data === null || data === void 0 ? void 0 : data.placeholder) || ""),
$disabled: applyFieldPropFunc(instance, props.$disabled || (data === null || data === void 0 ? void 0 : data.disabled) || false),
$rules: applyFieldPropFunc(instance, props.$rules || (data === null || data === void 0 ? void 0 : data.rules) || null),
$related: applyFieldPropFunc(instance, props.$related || (data === null || data === void 0 ? void 0 : data.related) || []),
$deleted: applyFieldPropFunc(instance, props.$deleted || (data === null || data === void 0 ? void 0 : data.deleted) || false),
$validatedWith: applyFieldPropFunc(instance, props.$validatedWith || (data === null || data === void 0 ? void 0 : data.validatedWith) || FieldProps_1.FieldPropsEnum.value),
$bindings: applyFieldPropFunc(instance, props.$bindings || (data === null || data === void 0 ? void 0 : data.bindings) || FieldProps_1.FieldPropsEnum.default),
$extra: applyFieldPropFunc(instance, props.$extra || (data === null || data === void 0 ? void 0 : data.extra) || null),
$options: applyFieldPropFunc(instance, props.$options || (data === null || data === void 0 ? void 0 : data.options) || {}),
$autoFocus: applyFieldPropFunc(instance, props.$autoFocus || (data === null || data === void 0 ? void 0 : data.autoFocus) || false),
$inputMode: applyFieldPropFunc(instance, props.$inputMode || (data === null || data === void 0 ? void 0 : data.inputMode) || undefined),
$validators: applyFieldPropFunc(instance, props.$validators || (data === null || data === void 0 ? void 0 : data.validators) || null),
// other props
$hooks: props.$hooks || (data === null || data === void 0 ? void 0 : data.hooks) || {},
$handlers: props.$handlers || (data === null || data === void 0 ? void 0 : data.handlers) || {},
$observers: props.$observers || (data === null || data === void 0 ? void 0 : data.observers) || null,
$interceptors: props.$interceptors || (data === null || data === void 0 ? void 0 : data.interceptors) || null,
$ref: props.$ref || (data === null || data === void 0 ? void 0 : data.ref) || undefined,
$nullable: props.$nullable || (data === null || data === void 0 ? void 0 : data.nullable) || false,
$autoComplete: props.$autoComplete || (data === null || data === void 0 ? void 0 : data.autoComplete) || undefined,
});
const setupDefaultProp = (instance, data, props, update, { isEmptyArray, fallbackValueOption }) => (0, parser_1.parseInput)((val) => val, {
isEmptyArray,
type: instance.type,
unified: update
? (0, parser_1.defaultValue)({
fallbackValueOption,
type: instance.type,
value: instance.value
})
: data === null || data === void 0 ? void 0 : data.default,
separated: props.$default,
fallback: instance.$initial,
});
class Field extends Base_1.default {
constructor({ key, path, struct, data = {}, props = {}, update = false, state, }) {
super();
Object.defineProperty(this, "hasInitialNestedFields", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "incremental", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "key", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$observers", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$interceptors", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$converter", {
enumerable: true,
configurable: true,
writable: true,
value: ($) => $
});
Object.defineProperty(this, "$input", {
enumerable: true,
configurable: true,
writable: true,
value: ($) => $
});
Object.defineProperty(this, "$output", {
enumerable: true,
configurable: true,
writable: true,
value: ($) => $
});
Object.defineProperty(this, "_value", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_label", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_placeholder", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_disabled", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_rules", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_related", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_deleted", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_validatedWith", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_validators", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_bindings", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_extra", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_autoFocus", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_inputMode", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$value", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$type", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$label", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$placeholder", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$default", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$initial", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$bindings", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$extra", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$related", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$validatedWith", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$validators", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$rules", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$disabled", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$focused", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$blurred", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$deleted", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$autoFocus", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$inputMode", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "$ref", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "$nullable", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$autoComplete", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "showError", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "errorSync", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "errorAsync", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "validationErrorStack", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "validationFunctionsData", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "validationAsyncData", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "debouncedValidation", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "disposeValidationOnBlur", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "disposeValidationOnChange", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "files", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
/* ------------------------------------------------------------------ */
/* EVENTS HANDLERS */
Object.defineProperty(this, "sync", {
enumerable: true,
configurable: true,
writable: true,
value: (0, mobx_1.action)((e, v = null) => {
const $get = ($) => (0, utils_1.isBool)($, this.value) ? $.target.checked : $.target.value;
// assume "v" or "e" are the values
if (lodash_1.default.isNil(e) || lodash_1.default.isNil(e.target)) {
if (!lodash_1.default.isNil(v) && !lodash_1.default.isNil(v.target)) {
v = $get(v); // eslint-disable-line
}
this.value = (0, utils_1.$try)(e, v);
return;
}
if (!lodash_1.default.isNil(e.target)) {
this.value = $get(e);
return;
}
this.value = e;
})
});
Object.defineProperty(this, "onSync", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.type === "file"
? this.onDrop(...args)
: this.execHandler(FieldProps_1.FieldPropsEnum.onChange, args, this.sync, FieldProps_1.FieldPropsEnum.onSync)
});
Object.defineProperty(this, "onChange", {
enumerable: true,
configurable: true,
writable: true,
value: this.onSync
});
Object.defineProperty(this, "onToggle", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onToggle, args, this.sync)
});
Object.defineProperty(this, "onBlur", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onBlur, args, (0, mobx_1.action)(() => {
this.$focused = false;
this.$blurred = true;
}))
});
Object.defineProperty(this, "onFocus", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onFocus, args, (0, mobx_1.action)(() => {
this.$focused = true;
this.$touched = true;
}))
});
Object.defineProperty(this, "onDrop", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onDrop, args, (0, mobx_1.action)(() => {
const e = args[0];
let files = null;
if ((0, utils_1.isEvent)(e) && (0, utils_1.hasFiles)(e)) {
files = lodash_1.default.map(e.target.files);
}
this.files = [
...lodash_1.default.map(this.files),
...(files || args)
];
}))
});
Object.defineProperty(this, "onKeyDown", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onKeyDown, args)
});
Object.defineProperty(this, "onKeyUp", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onKeyUp, args)
});
(0, mobx_1.makeObservable)(this, {
$options: mobx_1.observable,
$value: mobx_1.observable,
$type: mobx_1.observable,
$label: mobx_1.observable,
$placeholder: mobx_1.observable,
$default: mobx_1.observable,
$initial: mobx_1.observable,
$bindings: mobx_1.observable,
$extra: mobx_1.observable,
$related: mobx_1.observable,
$validatedWith: mobx_1.observable,
$validators: mobx_1.observable,
$rules: mobx_1.observable,
$disabled: mobx_1.observable,
$focused: mobx_1.observable,
$blurred: mobx_1.observable,
$deleted: mobx_1.observable,
showError: mobx_1.observable,
errorSync: mobx_1.observable,
errorAsync: mobx_1.observable,
validationErrorStack: mobx_1.observable,
validationFunctionsData: mobx_1.observable,
validationAsyncData: mobx_1.observable,
files: mobx_1.observable,
autoFocus: mobx_1.computed,
inputMode: mobx_1.computed,
ref: mobx_1.computed,
checkValidationErrors: mobx_1.computed,
checked: mobx_1.computed,
value: mobx_1.computed,
initial: mobx_1.computed,
default: mobx_1.computed,
actionRunning: mobx_1.computed,
type: mobx_1.computed,
label: mobx_1.computed,
placeholder: mobx_1.computed,
extra: mobx_1.computed,
options: mobx_1.computed,
bindings: mobx_1.computed,
related: mobx_1.computed,
disabled: mobx_1.computed,
rules: mobx_1.computed,
validators: mobx_1.computed,
validatedValue: mobx_1.computed,
error: mobx_1.computed,
hasError: mobx_1.computed,
isValid: mobx_1.computed,
isDefault: mobx_1.computed,
isDirty: mobx_1.computed,
isPristine: mobx_1.computed,
isEmpty: mobx_1.computed,
blurred: mobx_1.computed,
touched: mobx_1.computed,
deleted: mobx_1.computed,
setupField: mobx_1.action,
initNestedFields: mobx_1.action,
invalidate: mobx_1.action,
setValidationAsyncData: mobx_1.action,
resetValidation: mobx_1.action,
clear: mobx_1.action,
reset: mobx_1.action,
focus: mobx_1.action,
blur: mobx_1.action,
showErrors: mobx_1.action,
update: mobx_1.action
});
this.state = state;
this.setupField(key, path, struct, data, props, update);
// this.checkValidationPlugins();
this.initNestedFields(data, update);
this.incremental = this.hasIncrementalKeys;
this.debouncedValidation = lodash_1.default.debounce(this.validate, this.state.options.get(OptionsModel_1.OptionsEnum.validationDebounceWait, this), this.state.options.get(OptionsModel_1.OptionsEnum.validationDebounceOptions, this));
this.observeValidationOnBlur();
this.observeValidationOnChange();
this.initMOBXEvent(FieldProps_1.FieldPropsEnum.observers);
this.initMOBXEvent(FieldProps_1.FieldPropsEnum.interceptors);
// setup hooks & handlers from initialization methods
(0, mobx_1.runInAction)(() => { var _a; return Object.assign(this.$hooks, (_a = this.hooks) === null || _a === void 0 ? void 0 : _a.apply(this, [this])); });
(0, mobx_1.runInAction)(() => { var _a; return Object.assign(this.$handlers, (_a = this.handlers) === null || _a === void 0 ? void 0 : _a.apply(this, [this])); });
this.execHook(FieldProps_1.FieldPropsEnum.onInit);
// handle Field onChange Hook
(0, mobx_1.autorun)(() => this.changed && this.execHook(FieldProps_1.FieldPropsEnum.onChange));
}
/* ------------------------------------------------------------------ */
/* COMPUTED */
get checkValidationErrors() {
var _a;
return ((((_a = this.validationAsyncData) === null || _a === void 0 ? void 0 : _a.valid) === false &&
!lodash_1.default.isEmpty(this.validationAsyncData)) ||
!lodash_1.default.isEmpty(this.validationErrorStack) ||
lodash_1.default.isString(this.errorAsync) ||
lodash_1.default.isString(this.errorSync));
}
set value(newVal) {
if (lodash_1.default.isString(newVal) && this.state.options.get(OptionsModel_1.OptionsEnum.autoTrimValue, this)) {
newVal = newVal.trim();
}
if (this.$value === newVal)
return;
if (this.handleSetNumberValue(newVal))
return;
this.$value = this.$converter(newVal);
this.$changed++;
if (!this.actionRunning) {
this.state.form.$changed++;
}
;
}
handleSetNumberValue(newVal) {
if (!this.state.options.get(OptionsModel_1.OptionsEnum.autoParseNumbers, this))
return false;
if (lodash_1.default.isNumber(this.$initial) || this.type == 'number') {
if (new RegExp("^-?\\d+(,\\d+)*(\\.\\d+([eE]\\d+)?)?$", "g").exec(newVal)) {
this.$value = this.$converter(lodash_1.default.toNumber(newVal));
this.$changed++;
if (!this.actionRunning) {
this.state.form.$changed++;
}
;
return true;
}
}
}
get actionRunning() {
return this.submitting || this.clearing || this.resetting;
}
get checked() {
return this.type === "checkbox" ? this.value : undefined;
}
get value() {
return (typeof this._value === 'function' && !this.hasNestedFields)
? propGetter(this, FieldProps_1.FieldPropsEnum.value)
: this.getComputedProp(FieldProps_1.FieldPropsEnum.value);
}
get initial() {
return this.$initial
? (0, mobx_1.toJS)(this.$initial)
: this.getComputedProp(FieldProps_1.FieldPropsEnum.initial);
}
get default() {
return this.$default
? (0, mobx_1.toJS)(this.$default)
: this.getComputedProp(FieldProps_1.FieldPropsEnum.default);
}
set initial(val) {
this.$initial = val;
}
set default(val) {
this.$default = val;
}
get nullable() {
return propGetter(this, FieldProps_1.FieldPropsEnum.nullable);
}
get autoComplete() {
return propGetter(this, FieldProps_1.FieldPropsEnum.autoComplete);
}
get ref() {
return propGetter(this, FieldProps_1.FieldPropsEnum.ref);
}
get extra() {
return propGetter(this, FieldProps_1.FieldPropsEnum.extra);
}
get autoFocus() {
return propGetter(this, FieldProps_1.FieldPropsEnum.autoFocus);
}
get inputMode() {
return propGetter(this, FieldProps_1.FieldPropsEnum.inputMode);
}
get type() {
return propGetter(this, FieldProps_1.FieldPropsEnum.type);
}
get label() {
return propGetter(this, FieldProps_1.FieldPropsEnum.label);
}
get placeholder() {
return propGetter(this, FieldProps_1.FieldPropsEnum.placeholder);
}
get options() {
return propGetter(this, FieldProps_1.FieldPropsEnum.options);
}
get bindings() {
return propGetter(this, FieldProps_1.FieldPropsEnum.bindings);
}
get related() {
return propGetter(this, FieldProps_1.FieldPropsEnum.related);
}
get disabled() {
return propGetter(this, FieldProps_1.FieldPropsEnum.disabled);
}
get rules() {
return propGetter(this, FieldProps_1.FieldPropsEnum.rules);
}
get validators() {
return propGetter(this, FieldProps_1.FieldPropsEnum.validators);
}
get validatedWith() {
return propGetter(this, FieldProps_1.FieldPropsEnum.validatedWith);
}
get validatedValue() {
return (0, parser_1.parseCheckOutput)(this, this.validatedWith);
}
get error() {
if (this.showError === false)
return null;
return this.errorAsync || this.errorSync || null;
}
get hasError() {
return this.checkValidationErrors || this.check(FieldProps_1.FieldPropsEnum.hasError, true);
}
get isValid() {
return !this.checkValidationErrors && this.check(FieldProps_1.FieldPropsEnum.isValid, true);
}
get isDefault() {
return !lodash_1.default.isNil(this.default) && lodash_1.default.isEqual(this.default, this.value);
}
get isDirty() {
const value = this.changed ? this.value : this.initial;
return !lodash_1.default.isEqual(this.initial, value);
}
get isPristine() {
const value = this.changed ? this.value : this.initial;
return lodash_1.default.isEqual(this.initial, value);
}
get isEmpty() {
if (this.hasNestedFields)
return this.check(FieldProps_1.FieldPropsEnum.isEmpty, true);
if (lodash_1.default.isBoolean(this.value))
return !!this.$value;
if (lodash_1.default.isNumber(this.value))
return false;
if (lodash_1.default.isDate(this.value))
return false;
if (lodash_1.default.isNull(this.value))
return false;
return lodash_1.default.isEmpty(this.value);
}
get focused() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.focused, true) : this.$focused;
}
get blurred() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.blurred, true) : this.$blurred;
}
get touched() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.touched, true) : this.$touched;
}
get deleted() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.deleted, true) : this.$deleted;
}
setupField($key, $path, $struct, $data, $props, update) {
var _a;
this.key = $key;
this.path = $path;
this.id = (_a = this.state.options.get(OptionsModel_1.OptionsEnum.uniqueId)) === null || _a === void 0 ? void 0 : _a.apply(this, [this]);
const fallbackValueOption = this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this);
const applyInputConverterOnInit = this.state.options.get(OptionsModel_1.OptionsEnum.applyInputConverterOnInit, this);
const struct = this.state.struct();
const structPath = (0, utils_1.pathToStruct)(this.path);
const isEmptyArray = (0, utils_1.isArrayFromStruct)(struct, structPath);
const { $type, $input, $output, $converter, $converters, $computed } = $props;
if (lodash_1.default.isPlainObject($data)) {
const { type, input, output, converter, converters, computed } = $data;
this.name = lodash_1.default.toString($data.name || $key);
this.$type = $type || type || "text";
this.$converter = (0, utils_1.$try)($converter, $converters, converter, converters, this.$converter);
this.$input = (0, utils_1.$try)($input, input, this.$input);
this.$output = (0, utils_1.$try)($output, output, this.$output);
const value = (0, parser_1.parseInput)(applyInputConverterOnInit ? this.$input : (val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: computed || $data.value,
separated: $computed || $props.$value,
fallback: $props.$initial,
});
this._value = retrieveFieldPropFunc(value);
this.$value = (typeof this._value === 'function')
? applyFieldPropFunc(this, value)
: value;
this.$initial = (0, parser_1.parseInput)((val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: $data.initial,
separated: $props.$initial,
fallback: this.$value,
});
this.$default = setupDefaultProp(this, $data, $props, update, {
fallbackValueOption,
isEmptyArray,
});
setupFieldProps(this, $props, $data);
return;
}
/* The field IS the value here */
this.name = lodash_1.default.toString($key);
this.$type = $type || "text";
this.$converter = (0, utils_1.$try)($converter, $converters, this.$converter);
this.$input = (0, utils_1.$try)($input, this.$input);
this.$output = (0, utils_1.$try)($output, this.$output);
const value = (0, parser_1.parseInput)(applyInputConverterOnInit ? this.$input : (val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: $computed || $data,
separated: $computed || $props.$value,
});
this._value = retrieveFieldPropFunc(value);
this.$value = (typeof this._value === 'function')
? applyFieldPropFunc(this, value)
: value;
this.$initial = (0, parser_1.parseInput)((val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: $data,
separated: $props.$initial,
fallback: this.$value,
});
this.$default = setupDefaultProp(this, $data, $props, update, {
fallbackValueOption,
isEmptyArray,
});
setupFieldProps(this, $props, $data);
}
getComputedProp(key) {
if (this.incremental || this.hasNestedFields) {
return (key === FieldProps_1.FieldPropsEnum.value)
? this.get(key, false)
: (0, mobx_1.untracked)(() => this.get(key, false));
}
// @ts-ignore
const val = this[`$${key}`];
if (Array.isArray(val) || (0, mobx_1.isObservableArray)(val)) {
return [].slice.call(val);
}
return (0, mobx_1.toJS)(val);
}
// checkValidationPlugins(): void {
// const { drivers } = this.state.form.validator;
// const form = this.state.form.name ? `${this.state.form.name}/` : "";
// if (_.isNil(drivers.dvr) && !_.isNil(this.rules)) {
// throw new Error(
// `The DVR validation rules are defined but no DVR plugin provided. Field: "${
// form + this.path
// }".`
// );
// }
// if (_.isNil(drivers.vjf) && !_.isNil(this.validators)) {
// throw new Error(
// `The VJF validators functions are defined but no VJF plugin provided. Field: "${
// form + this.path
// }".`
// );
// }
// }
initNestedFields(field, update) {
const fields = lodash_1.default.isNil(field) ? null : field.fields;
if (Array.isArray(fields) && !lodash_1.default.isEmpty(fields)) {
this.hasInitialNestedFields = true;
}
this.initFields({ fields }, update);
if (!update && Array.isArray(fields) && lodash_1.default.isEmpty(fields)) {
if (Array.isArray(this.value) && !lodash_1.default.isEmpty(this.value)) {
this.hasInitialNestedFields = true;
this.initFields({ fields, values: this.value }, update);
}
}
}
invalidate(message, deep = true, async = false) {
if (async === true) {
this.errorAsync = message;
this.showErrors(true, deep);
return;
}
if (Array.isArray(message)) {
this.validationErrorStack = message;
this.showErrors(true, deep);
return;
}
this.validationErrorStack.unshift(message);
this.showErrors(true, deep);
}
setValidationAsyncData(valid = false, message = "") {
this.validationAsyncData = { valid, message };
}
resetValidation(deep = false) {
this.showError = false;
this.errorSync = null;
this.errorAsync = null;
this.validationAsyncData = undefined;
this.validationFunctionsData = [];
this.validationErrorStack = [];
Promise.resolve().then((0, mobx_1.action)(() => {
this.$resetting = false;
this.$clearing = false;
}));
deep && this.each((field) => field.resetValidation(deep));
}
clear(deep = true, execHook = true) {
execHook && this.execHook(FieldProps_1.FieldPropsEnum.onClear);
this.$clearing = true;
this.$touched = false;
this.$blurred = false;
this.$changed = 0;
this.files = undefined;
this.$value = (0, parser_1.defaultValue)({
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue),
value: this.$value,
nullable: this.$nullable,
type: this.type,
});
deep && this.each((field) => field.clear(deep));
this.state.options.get(OptionsModel_1.OptionsEnum.validateOnClear, this)
? this.validate({
showErrors: this.state.options.get(OptionsModel_1.OptionsEnum.showErrorsOnClear, this),
}) : this.resetValidation(deep);
}
reset(deep = true, execHook = true) {
execHook && this.execHook(FieldProps_1.FieldPropsEnum.onReset);
this.$resetting = true;
this.$touched = false;
this.$blurred = false;
this.$changed = 0;
this.files = undefined;
const useDefaultValue = this.$default !== this.$initial;
if (useDefaultValue)
this.value = this.$default;
if (!useDefaultValue)
this.value = this.$initial;
deep && this.each((field) => field.reset(deep));
this.state.options.get(OptionsModel_1.OptionsEnum.validateOnReset, this)
? this.validate({
showErrors: this.state.options.get(OptionsModel_1.OptionsEnum.showErrorsOnReset, this),
}) : this.resetValidation(deep);
}
focus() {
if (this.ref && !this.focused)
this.ref.focus();
this.$focused = true;
this.$touched = true;
}
blur() {
if (this.ref && this.focused)
this.ref.blur();
this.$focused = false;
this.$blurred = true;
}
trim() {
if (!lodash_1.default.isString(this.value))
return;
this.$value = this.value.trim();
}
showErrors(show = true, deep = true) {
var _a, _b;
this.showError = show;
this.errorSync = lodash_1.default.head(this.validationErrorStack) || null;
this.errorAsync = (((_a = this.validationAsyncData) === null || _a === void 0 ? void 0 : _a.valid) === false) ? (_b = this.validationAsyncData) === null || _b === void 0 ? void 0 : _b.message : null;
deep && this.each((field) => field.showErrors(show, deep));
}
observeValidationOnBlur() {
const opt = this.state.options;
if (opt.get(OptionsModel_1.OptionsEnum.validateOnBlur, this)) {
this.disposeValidationOnBlur = (0, mobx_1.observe)(this, "$focused", (change) => change.newValue === false &&
this.debouncedValidation({
showErrors: opt.get(OptionsModel_1.OptionsEnum.showErrorsOnBlur, this),
}));
}
}
observeValidationOnChange() {
const opt = this.state.options;
if (opt.get(OptionsModel_1.OptionsEnum.validateOnChange, this)) {
this.disposeValidationOnChange = (0, mobx_1.observe)(this, "$value", () => !this.actionRunning && this.debouncedValidation({
showErrors: opt.get(OptionsModel_1.OptionsEnum.showErrorsOnChange, this),
}));
}
else if (opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterInitialBlur, this) ||
opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterSubmit, this)) {
this.disposeValidationOnChange = (0, mobx_1.observe)(this, "$value", () => !this.actionRunning && ((opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterInitialBlur, this) && this.blurred)
|| (opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterSubmit, this) && this.state.form.submitted))
&& this.debouncedValidation({
showErrors: opt.get(OptionsModel_1.OptionsEnum.showErrorsOnChange, this),
}));
}
}
initMOBXEvent(type) {
if (!Array.isArray(this[`$${type}`]))
return;
let fn;
if (type === FieldProps_1.FieldPropsEnum.observers)
fn = this.observe;
if (type === FieldProps_1.FieldPropsEnum.interceptors)
fn = this.intercept;
this[`$${type}`].map((obj) => fn(lodash_1.default.omit(obj, FieldProps_1.FieldPropsEnum.path)));
}
bind(props = {}) {
return Object.assign(Object.assign({}, this.state.bindings.load(this, this.bindings, props)), { ref: ($ref) => (this.$ref = $ref) });
}
update(fields) {
if (!lodash_1.default.isPlainObject(fields)) {
throw new Error("The update() method accepts only plain objects.");
}
const fallback = this.state.options.get(OptionsModel_1.OptionsEnum.fallback, this);
const applyInputConverterOnUpdate = this.state.options.get(OptionsModel_1.OptionsEnum.applyInputConverterOnUpdate, this);
const x = this.state.struct().findIndex(s => s.startsWith(this.path.replace(/\.\d+\./, '[].') + '[]'));
if (!fallback && this.fields.size === 0 && x < 0) {
this.value = (0, parser_1.parseInput)(applyInputConverterOnUpdate ? this.$input : (val) => val, {
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this),
separated: fields,
});
return;
}
super.update(fields);
}
}
exports.default = Field;
//# sourceMappingURL=Field.js.map