@livelybone/form
Version:
A cross-framework form management library, realized validate, format, reset, submit
573 lines (493 loc) • 18.5 kB
JavaScript
/**
* Bundle of @livelybone/form
* Generated: 2020-07-27
* Version: 2.10.6
* License: MIT
* Author: 2631541504@qq.com
*/
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(source, true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(source).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
return;
}
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function itemValidate(item, formData, options) {
var $options = _objectSpread2({}, formData, {}, options.optionsForValidatorAndFormatter);
item.errorText = item.required && !item.value && item.value !== 0 ? options.emptyErrorTemplate.replace('{label}', item.label || '') : item.validator ? item.validator(item.value, $options) : '';
item.valid = !item.errorText;
return item.errorText;
}
function itemChange(item, value, formData, options) {
item.value = item.formatter ? item.formatter(value, _objectSpread2({}, formData, {}, options.optionsForValidatorAndFormatter)) : value; // 更新 data
formData[item.name] = item.value;
var _item$validateOnChang = item.validateOnChange,
validateOnChange = _item$validateOnChang === void 0 ? options.validateOnChange : _item$validateOnChang;
if (validateOnChange) itemValidate(item, formData, options);else item.errorText = '';
item.pristine = false;
}
function init(items, options) {
var values = _objectSpread2({}, options.initialValues);
var data = {};
var $items = items.map(function (item) {
var $value = values[item.name] !== undefined ? values[item.name] : item.value;
var value = item.formatter ? item.formatter($value, _objectSpread2({}, values, {}, options.optionsForValidatorAndFormatter)) : $value;
values[item.name] = value;
data[item.name] = value;
return _objectSpread2({}, item, {
id: item.id || item.name,
required: item.required !== undefined ? item.required : true,
value: value,
pristine: true,
valid: true,
errorText: '',
validateOnChange: item.validateOnChange || false
});
});
return {
data: data,
items: $items
};
}
function clearValidateRes(item) {
item.valid = true;
item.errorText = '';
}
function formItemsDictionary(formItems) {
var dictionary = {};
Object.entries(formItems).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
id = _ref2[0],
item = _ref2[1];
dictionary[id] = _objectSpread2({}, item, {
id: id
});
});
return dictionary;
}
var Form =
/*#__PURE__*/
function () {
/**
* @desc 表单项数组
*
* @desc Array of form items
* */
function Form(formItems) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Form);
_defineProperty(this, "items", void 0);
_defineProperty(this, "$errorText", '');
_defineProperty(this, "options", {});
_defineProperty(this, "data", void 0);
this.$updateOptions(options);
var itemsAndData = init(formItems, this.options);
this.items = itemsAndData.items;
this.data = itemsAndData.data;
this.$updateOptions({
initialValues: this.data
});
this.updateItemsRequired();
}
/**
* @desc 当前表单数据,由表单项数组生成
*
* @desc Data of the form, generated by form items
* */
_createClass(Form, [{
key: "getItemByName",
value: function getItemByName(name) {
return this.items.find(function (item) {
return item.name === name;
});
}
}, {
key: "getItemById",
value: function getItemById(id) {
return this.items.find(function (item) {
return item.id === id;
});
}
/**
* @desc 更新与参数 name 对应的表单项的值
*
* @desc Update the value of the form item that matched the param `name`
* */
}, {
key: "itemChange",
value: function itemChange$1(name, value) {
var shouldUpdateComp = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var item = this.getItemByName(name);
if (item) {
var oldValue = item.value;
itemChange(item, value, this.data, this.options);
if (oldValue !== item.value) this.updateItemsRequired();
this.errorText = '';
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
} else console.error(new Error("The name `".concat(name, "` isn't exist in this form")));
}
/**
* @desc 批量更新与表单项的值
*
* @desc Batch updates with the values of form items
* */
}, {
key: "itemsChange",
value: function itemsChange(values) {
var _this = this;
var shouldUpdateComp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var shouldUpdateRequired = false;
this.items.forEach(function (item) {
var name = item.name;
if (name in values) {
var oldValue = item.value;
itemChange(item, values[name], _this.data, _this.options);
shouldUpdateRequired = shouldUpdateRequired || oldValue !== item.value;
}
});
if (shouldUpdateRequired) {
this.updateItemsRequired();
}
this.errorText = '';
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
}
/**
* @desc 校验与参数 name 对应的表单项
*
* @desc Validate the value of the form item that matched the param `name`
* */
}, {
key: "itemValidate",
value: function itemValidate$1(name, updatePristine) {
var shouldUpdateComp = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var item = this.getItemByName(name);
if (item) {
if (updatePristine) item.pristine = false;
var err = itemValidate(item, this.data, this.options);
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
return err;
}
return 'The name isn\'t exist in this form';
}
/**
* @desc 从外部更新表单项的校验结果,这个可以用于异步校验
*
* @desc Update the validate result outside, it is useful for async validate
* */
}, {
key: "updateValidateResult",
value: function updateValidateResult(results) {
var shouldUpdateComp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
this.items.forEach(function (item) {
if (item.name in results) {
var errorText = results[item.name];
if (errorText) {
item.valid = false;
item.errorText = errorText;
} else {
item.valid = true;
item.errorText = '';
}
}
});
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
}
/**
* @desc 校验整个表单
* @params validateAll 是否校验所有表单项
* true - 校验所有表单项
* false - 当遇到第一个校验错误的表单项时,停止对其他表单项的校验
*
* 默认值: this.options.validateAll
*
* @desc Form validate
* @params validateAll Whether validate all the form item in the form
* true - validate all
* false - stop validate other form items when the first form item with a validation error is encountered
*
* Default: this.options.validateAll
*
* @return ErrorText
* */
}, {
key: "formValidate",
value: function formValidate() {
var validateAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.validateAll;
var shouldUpdateComp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var errorTxt = '';
for (var i = 0; i < this.items.length; i += 1) {
if (!validateAll && errorTxt) break;
var err = itemValidate(this.items[i], this.data, this.options);
if (!errorTxt) errorTxt = err;
}
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
return errorTxt;
}
/**
* @desc 在提交之前会先做一次表单校验(运行 formValidate)
*
* @desc Method formValidate will be called before run the onSubmit function in this method
* */
}, {
key: "submit",
value: function submit() {
var _this2 = this;
var shouldUpdateComp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
// reset the $errorText prop
this.errorText = '';
var errorText = this.formValidate(this.options.validateAll, false);
return (!errorText ? Promise.resolve(this.options.onSubmit(this.data)) : Promise.reject(new Error(errorText))).finally(function () {
if (shouldUpdateComp && _this2.options.componentUpdateFn) _this2.options.componentUpdateFn();
});
}
/**
* @desc 重置表单。会更新表单的初始值,如果不想更新初始值,请使用 itemsChange
*
* @desc Reset form. The initialValues of the form will be update. If you do not want to update the initialValues, use itemsChange
*
* @params values Default: this.options.initialValues
* */
}, {
key: "reset",
value: function reset() {
var values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.initialValues;
var shouldUpdateComp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
this.$updateOptions({
initialValues: values
});
var itemsAndData = init(this.items, this.options);
this.items = itemsAndData.items;
this.data = itemsAndData.data;
this.updateItemsRequired();
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
}
/**
* @desc 用参数 value 的值重置与参数 name 对应的表单项。会更新表单项的初始值
*
* @desc Reset form item that matched the param name with the param value. The initial value of the form item will be update
*
* @params name
* @params value Default: this.options.initialValues[name]
* */
}, {
key: "resetItem",
value: function resetItem(name) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.initialValues[name];
var shouldUpdateComp = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var item = this.getItemByName(name);
if (item) {
var oldValue = item.value;
item.pristine = true;
item.value = item.formatter ? item.formatter(value, _objectSpread2({}, this.data, {}, this.options.optionsForValidatorAndFormatter)) : value;
this.data[item.name] = item.value;
this.options.initialValues[item.name] = value;
if (oldValue !== item.value) this.updateItemsRequired();
clearValidateRes(item);
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
} else console.error(new Error("The name `".concat(name, "` isn't exist in this form")));
}
/**
* @desc 清除表单/表单项的校验结果
*
* @desc Clear the validate result of the form or the form item that matched the param name
*
* @params [name] If `!!name === true`, it will clear the validate result of the form item that matched the param name
* else, if will clear the validate result of the form
* */
}, {
key: "clearValidateResult",
value: function clearValidateResult(name) {
var shouldUpdateComp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (name) {
var item = this.getItemByName(name);
if (item) {
clearValidateRes(item);
} else console.error(new Error("The name `".concat(name, "` isn't exist in this form")));
} else {
this.items.forEach(clearValidateRes);
}
if (shouldUpdateComp && this.options.componentUpdateFn) this.options.componentUpdateFn();
}
}, {
key: "$updateOptions",
value: function $updateOptions(options) {
this.options.onSubmit = options.onSubmit || this.options.onSubmit || function (data) {
return Promise.resolve(data);
};
this.options.validateAll = options.validateAll || this.options.validateAll || false;
this.options.initialValues = _objectSpread2({}, this.options.initialValues, {}, options.initialValues);
this.options.validateOnChange = options.validateOnChange || this.options.validateOnChange || false;
this.options.emptyErrorTemplate = options.emptyErrorTemplate || this.options.emptyErrorTemplate || '{label}不能为空';
this.options.optionsForValidatorAndFormatter = _objectSpread2({}, this.options.optionsForValidatorAndFormatter, {}, options.optionsForValidatorAndFormatter);
this.options.componentUpdateFn = options.componentUpdateFn || this.options.componentUpdateFn;
}
/**
* 应在 this.options.optionsForValidatorAndFormatter 或者 this.data 发生变化时更新 required 值
*
* The required value of form item should be updated after the `this.options.optionsForValidatorAndFormatter` and `this.data` changed
* */
}, {
key: "updateItemsRequired",
value: function updateItemsRequired() {
var $options = _objectSpread2({}, this.options.optionsForValidatorAndFormatter, {}, this.data);
this.items.forEach(function (item) {
item.required = item.calcRequired ? !!item.calcRequired($options) : item.required !== undefined ? item.required : true;
});
}
}, {
key: "updateOptions",
value: function updateOptions(options) {
var _this3 = this;
var shouldUpdateItemsRequired = options.optionsForValidatorAndFormatter && Object.keys(options.optionsForValidatorAndFormatter).some(function (k) {
return options.optionsForValidatorAndFormatter[k] !== _this3.options.optionsForValidatorAndFormatter[k];
});
this.$updateOptions(options);
if (shouldUpdateItemsRequired) this.updateItemsRequired();
}
}, {
key: "pristine",
get: function get() {
return this.items.every(function (item) {
return item.pristine;
});
}
}, {
key: "valid",
get: function get() {
return this.items.every(function (item) {
return item.valid;
});
}
/**
* @desc 当前表单应该显示的错误信息
*
* @desc The current errorText of the form
* */
}, {
key: "errorText",
get: function get() {
if (this.$errorText) return this.$errorText;
var item = this.items.find(function ($item) {
return $item.errorText;
});
return item ? item.errorText : '';
},
set: function set(errorText) {
this.$errorText = errorText;
}
}]);
return Form;
}();
var FormItemsManager =
/*#__PURE__*/
function () {
function FormItemsManager(formItems) {
_classCallCheck(this, FormItemsManager);
_defineProperty(this, "allItems", void 0);
this.allItems = formItemsDictionary(formItems);
}
_createClass(FormItemsManager, [{
key: "getItem",
value: function getItem(id) {
var item = _objectSpread2({}, this.allItems[id]);
if (!item) {
throw new Error("The form item you search for by id `".concat(id, "` is not exist, please make sure param id correct"));
}
return item;
}
}, {
key: "getItems",
value: function getItems(ids) {
return ids.map(this.getItem.bind(this));
}
}]);
return FormItemsManager;
}();
export { Form, FormItemsManager };