UNPKG

mui-extended

Version:

Extended UI Components built on Material UI

208 lines (207 loc) 9.14 kB
import { __awaiter, __extends, __generator } from "tslib"; import { jsx as _jsx } from "react/jsx-runtime"; import { validate } from "decorated-ajv"; import { cloneDeep } from "lodash"; import { Component } from "react"; import { FormContext } from "./FormContext"; import { debugEvent } from "./debug"; var getDefaultValidator = function (schema) { return function (name, value) { return __awaiter(void 0, void 0, void 0, function () { var violations; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, validate(schema, value)]; case 1: violations = _a.sent(); if (violations.length > 0) { throw new Error(violations[0].message); } return [2 /*return*/]; } }); }); }; }; var Form = /** @class */ (function (_super) { __extends(Form, _super); function Form(props) { var _this = _super.call(this, props) || this; _this.validationErrors = {}; _this.onFieldBlur = _this.onFieldBlur.bind(_this); _this.onFieldChange = _this.onFieldChange.bind(_this); _this.submit = _this.submit.bind(_this); _this.reset = _this.reset.bind(_this); _this._validateField = _this._validateField.bind(_this); _this._validateWrapper = _this._validateWrapper.bind(_this); _this.validateField = _this.validateField.bind(_this); _this.validate = _this.validate.bind(_this); _this._getInitialState = _this._getInitialState.bind(_this); _this.state = _this._getInitialState(); return _this; } Form.prototype._getInitialState = function () { return { values: cloneDeep(this.props.initialValues), errors: cloneDeep(this.props.initialErrors || {}), touched: {}, isDirty: false, isSubmitting: false, isValid: true, onFieldBlur: this.onFieldBlur, onFieldChange: this.onFieldChange, submit: this.submit, reset: this.reset }; }; Form.prototype.onFieldBlur = function (name) { var _this = this; var touched = cloneDeep(this.state.touched); touched[name] = true; this.setState({ isDirty: true, touched: touched }); setTimeout(function () { // delay the validation _this.validateField(name); }, 10); }; Form.prototype.onFieldChange = function (name, value) { var values = cloneDeep(this.state.values); values[name] = value; this.setState({ values: values }); }; Form.prototype._validateField = function (name) { return __awaiter(this, void 0, void 0, function () { var validator, e_1, errorMessage; return __generator(this, function (_a) { switch (_a.label) { case 0: debugEvent("_validateField", "start " + (name && name.toLocaleString())); validator = this.props.validators && this.props.validators[name] ? this.props.validators[name] : this.props.schemas && this.props.schemas[name] ? getDefaultValidator(this.props.schemas[name]) : undefined; if (!validator) return [3 /*break*/, 4]; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, validator(name, this.state.values[name])]; case 2: _a.sent(); delete this.validationErrors[name]; return [3 /*break*/, 4]; case 3: e_1 = _a.sent(); errorMessage = e_1.message; /*** * TODO: handle error message properly here, for better readability */ this.validationErrors[name] = errorMessage; return [3 /*break*/, 4]; case 4: debugEvent("_validateField", "end " + (name && name.toLocaleString())); return [2 /*return*/]; } }); }); }; Form.prototype._validateWrapper = function (validator) { return __awaiter(this, void 0, void 0, function () { var result; return __generator(this, function (_a) { switch (_a.label) { case 0: debugEvent("_validateWrapper", "start"); return [4 /*yield*/, validator()]; case 1: result = _a.sent(); this.setState({ errors: this.validationErrors, isValid: Object.keys(this.validationErrors).length == 0 }); debugEvent("_validateWrapper", "end"); return [2 /*return*/, result]; } }); }); }; Form.prototype.validateField = function (name) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._validateWrapper(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._validateField(name)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; Form.prototype.validate = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: debugEvent("validate", "start"); return [4 /*yield*/, this._validateWrapper(function () { return __awaiter(_this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.allSettled(Object.keys(this.state.values).map(function (name) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._validateField(name)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }))]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); debugEvent("validate", "end"); return [2 /*return*/]; } }); }); }; Form.prototype.reset = function () { this.setState(this._getInitialState()); }; Form.prototype.submit = function () { var _this = this; setTimeout(function () { // delay the submit _this.setState({ isSubmitting: true }); _this.validate() .then(function () { if (_this.state.isValid) { return _this.props.onSubmit(_this.state.values); } }) .finally(function () { _this.setState({ isSubmitting: false }); }); }, 10); }; Form.prototype.render = function () { return (_jsx(FormContext.Provider, { value: this.state, children: this.props.children })); }; return Form; }(Component)); export { Form };