ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
296 lines (265 loc) • 11 kB
JavaScript
import { createVNode as _createVNode } from "vue";
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 _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
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 _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
}
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
import { defineComponent, inject, provide, computed } from 'vue';
import PropTypes from '../_util/vue-types';
import classNames from '../_util/classNames';
import warning from '../_util/warning';
import FormItem from './FormItem';
import { getSlot } from '../_util/props-util';
import { defaultConfigProvider } from '../config-provider';
import { getNamePath, containsNamePath } from './utils/valueUtil';
import { defaultValidateMessages } from './utils/messages';
import { allPromiseFinish } from './utils/asyncUtil';
import { toArray } from './utils/typeUtil';
import isEqual from 'lodash-es/isEqual';
import scrollIntoView from 'scroll-into-view-if-needed';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import { tuple } from '../_util/type';
export var FormProps = {
layout: PropTypes.oneOf(tuple('horizontal', 'inline', 'vertical')),
labelCol: {
type: Object
},
wrapperCol: {
type: Object
},
colon: PropTypes.looseBool,
labelAlign: PropTypes.oneOf(tuple('left', 'right')),
prefixCls: PropTypes.string,
hideRequiredMark: PropTypes.looseBool,
model: PropTypes.object,
rules: {
type: Object
},
validateMessages: PropTypes.object,
validateOnRuleChange: PropTypes.looseBool,
// 提交失败自动滚动到第一个错误字段
scrollToFirstError: PropTypes.looseBool,
onSubmit: PropTypes.func,
onFinish: PropTypes.func,
onFinishFailed: PropTypes.func,
name: PropTypes.string,
validateTrigger: {
type: [String, Array]
}
};
function isEqualName(name1, name2) {
return isEqual(toArray(name1), toArray(name2));
}
var Form = defineComponent({
name: 'AForm',
inheritAttrs: false,
props: initDefaultProps(FormProps, {
layout: 'horizontal',
hideRequiredMark: false,
colon: true
}),
Item: FormItem,
setup: function setup(props) {
return {
configProvider: inject('configProvider', defaultConfigProvider),
fields: [],
form: undefined,
lastValidatePromise: null,
vertical: computed(function () {
return props.layout === 'vertical';
})
};
},
watch: {
rules: function rules() {
if (this.validateOnRuleChange) {
this.validateFields();
}
}
},
created: function created() {
provide('FormContext', this);
},
methods: {
addField: function addField(field) {
if (field) {
this.fields.push(field);
}
},
removeField: function removeField(field) {
if (field.fieldName) {
this.fields.splice(this.fields.indexOf(field), 1);
}
},
handleSubmit: function handleSubmit(e) {
var _this = this;
e.preventDefault();
e.stopPropagation();
this.$emit('submit', e);
var res = this.validateFields();
res.then(function (values) {
_this.$emit('finish', values);
}).catch(function (errors) {
_this.handleFinishFailed(errors);
});
},
getFieldsByNameList: function getFieldsByNameList(nameList) {
var provideNameList = !!nameList;
var namePathList = provideNameList ? toArray(nameList).map(getNamePath) : [];
if (!provideNameList) {
return this.fields;
} else {
return this.fields.filter(function (field) {
return namePathList.findIndex(function (namePath) {
return isEqualName(namePath, field.fieldName);
}) > -1;
});
}
},
resetFields: function resetFields(name) {
if (!this.model) {
warning(false, 'Form', 'model is required for resetFields to work.');
return;
}
this.getFieldsByNameList(name).forEach(function (field) {
field.resetField();
});
},
clearValidate: function clearValidate(name) {
this.getFieldsByNameList(name).forEach(function (field) {
field.clearValidate();
});
},
handleFinishFailed: function handleFinishFailed(errorInfo) {
var scrollToFirstError = this.scrollToFirstError;
this.$emit('finishFailed', errorInfo);
if (scrollToFirstError && errorInfo.errorFields.length) {
this.scrollToField(errorInfo.errorFields[0].name);
}
},
validate: function validate() {
return this.validateField.apply(this, arguments);
},
scrollToField: function scrollToField(name) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var fields = this.getFieldsByNameList(name);
if (fields.length) {
var fieldId = fields[0].fieldId;
var node = fieldId ? document.getElementById(fieldId) : null;
if (node) {
scrollIntoView(node, _extends({
scrollMode: 'if-needed',
block: 'nearest'
}, options));
}
}
},
// eslint-disable-next-line no-unused-vars
getFieldsValue: function getFieldsValue() {
var nameList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var values = {};
this.fields.forEach(function (_ref) {
var fieldName = _ref.fieldName,
fieldValue = _ref.fieldValue;
values[fieldName] = fieldValue;
});
if (nameList === true) {
return values;
} else {
var res = {};
toArray(nameList).forEach(function (namePath) {
return res[namePath] = values[namePath];
});
return res;
}
},
validateFields: function validateFields(nameList, options) {
var _this2 = this;
warning(!(nameList instanceof Function), 'Form', 'validateFields/validateField/validate not support callback, please use promise instead');
if (!this.model) {
warning(false, 'Form', 'model is required for validateFields to work.');
return Promise.reject('Form `model` is required for validateFields to work.');
}
var provideNameList = !!nameList;
var namePathList = provideNameList ? toArray(nameList).map(getNamePath) : []; // Collect result in promise list
var promiseList = [];
this.fields.forEach(function (field) {
// Add field if not provide `nameList`
if (!provideNameList) {
namePathList.push(field.getNamePath());
} // Skip if without rule
if (!field.getRules().length) {
return;
}
var fieldNamePath = field.getNamePath(); // Add field validate rule in to promise list
if (!provideNameList || containsNamePath(namePathList, fieldNamePath)) {
var promise = field.validateRules(_extends({
validateMessages: _extends(_extends({}, defaultValidateMessages), _this2.validateMessages)
}, options)); // Wrap promise with field
promiseList.push(promise.then(function () {
return {
name: fieldNamePath,
errors: []
};
}).catch(function (errors) {
return Promise.reject({
name: fieldNamePath,
errors: errors
});
}));
}
});
var summaryPromise = allPromiseFinish(promiseList);
this.lastValidatePromise = summaryPromise;
var returnPromise = summaryPromise.then(function () {
if (_this2.lastValidatePromise === summaryPromise) {
return Promise.resolve(_this2.getFieldsValue(namePathList));
}
return Promise.reject([]);
}).catch(function (results) {
var errorList = results.filter(function (result) {
return result && result.errors.length;
});
return Promise.reject({
values: _this2.getFieldsValue(namePathList),
errorFields: errorList,
outOfDate: _this2.lastValidatePromise !== summaryPromise
});
}); // Do not throw in console
returnPromise.catch(function (e) {
return e;
});
return returnPromise;
},
validateField: function validateField() {
return this.validateFields.apply(this, arguments);
}
},
render: function render() {
var _classNames;
var customizePrefixCls = this.prefixCls,
hideRequiredMark = this.hideRequiredMark,
layout = this.layout,
handleSubmit = this.handleSubmit;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('form', customizePrefixCls);
var _a = this.$attrs,
className = _a.class,
restProps = __rest(_a, ["class"]);
var formClassName = classNames(prefixCls, className, (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-horizontal"), layout === 'horizontal'), _defineProperty(_classNames, "".concat(prefixCls, "-vertical"), layout === 'vertical'), _defineProperty(_classNames, "".concat(prefixCls, "-inline"), layout === 'inline'), _defineProperty(_classNames, "".concat(prefixCls, "-hide-required-mark"), hideRequiredMark), _classNames));
return _createVNode("form", _objectSpread({
"onSubmit": handleSubmit,
"class": formClassName
}, restProps), [getSlot(this)]);
}
});
export default Form;