refactor: form
parent
97aeaf74b4
commit
130982a037
|
@ -7,6 +7,7 @@ import warning from '../_util/warning';
|
|||
import FormItem from './FormItem';
|
||||
import { initDefaultProps, getListeners, getSlot } from '../_util/props-util';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
import { getParams } from './utils';
|
||||
|
||||
export const FormProps = {
|
||||
layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']),
|
||||
|
@ -45,6 +46,8 @@ export const ValidationRule = {
|
|||
transform: PropTypes.func,
|
||||
/** custom validate function (Note: callback must be called) */
|
||||
validator: PropTypes.func,
|
||||
// 提交失败自动滚动到第一个错误字段
|
||||
scrollToFirstError: PropTypes.bool,
|
||||
};
|
||||
|
||||
const Form = {
|
||||
|
@ -96,12 +99,17 @@ const Form = {
|
|||
this.$emit('submit', e);
|
||||
}
|
||||
},
|
||||
resetFields() {
|
||||
resetFields(props = this.fields) {
|
||||
if (!this.model) {
|
||||
warning(false, 'FormModel', 'model is required for resetFields to work.');
|
||||
return;
|
||||
}
|
||||
this.fields.forEach(field => {
|
||||
const fields = props.length
|
||||
? typeof props === 'string'
|
||||
? this.fields.filter(field => props === field.prop)
|
||||
: this.fields.filter(field => props.indexOf(field.prop) > -1)
|
||||
: this.fields;
|
||||
fields.forEach(field => {
|
||||
field.resetField();
|
||||
});
|
||||
},
|
||||
|
@ -151,17 +159,81 @@ const Form = {
|
|||
return promise;
|
||||
}
|
||||
},
|
||||
validateField(props, cb) {
|
||||
props = [].concat(props);
|
||||
const fields = this.fields.filter(field => props.indexOf(field.prop) !== -1);
|
||||
if (!fields.length) {
|
||||
warning(false, 'FormModel', 'please pass correct props!');
|
||||
return;
|
||||
}
|
||||
fields.forEach(field => {
|
||||
field.validate('', cb);
|
||||
scrollToField() {},
|
||||
getFieldsValue(allFields) {
|
||||
return allFields.map(({ prop, fieldValue }) => {
|
||||
return { [prop]: fieldValue };
|
||||
});
|
||||
},
|
||||
validateFields() {
|
||||
this.validateField(...arguments);
|
||||
},
|
||||
validateField(ns, opt, cb) {
|
||||
const pending = new Promise((resolve, reject) => {
|
||||
const params = getParams(ns, opt, cb);
|
||||
const { names, options } = params;
|
||||
let { callback } = params;
|
||||
if (!callback || typeof callback === 'function') {
|
||||
const oldCb = callback;
|
||||
callback = (errors, values) => {
|
||||
if (oldCb) {
|
||||
oldCb(errors, values);
|
||||
} else if (errors) {
|
||||
reject({ errors, values });
|
||||
} else {
|
||||
resolve(values);
|
||||
}
|
||||
};
|
||||
}
|
||||
const allFields = names
|
||||
? this.fields.filter(field => names.indexOf(field.prop) !== -1)
|
||||
: this.fields;
|
||||
const fields = allFields.filter(field => {
|
||||
const rules = field.getFilteredRule('');
|
||||
return rules && rules.length;
|
||||
});
|
||||
if (!fields.length) {
|
||||
callback(null, this.getFieldsValue(allFields));
|
||||
return;
|
||||
}
|
||||
if (!('firstFields' in options)) {
|
||||
options.firstFields = allFields.filter(field => {
|
||||
return !!field.validateFirst;
|
||||
});
|
||||
}
|
||||
let invalidFields = {};
|
||||
let valid = true;
|
||||
let count = 0;
|
||||
fields.forEach(field => {
|
||||
field.validate('', (message, field) => {
|
||||
if (message) {
|
||||
valid = false;
|
||||
}
|
||||
// TODO:
|
||||
invalidFields = Object.assign({}, invalidFields, field);
|
||||
if (typeof callback === 'function' && ++count === fields.length) {
|
||||
callback(valid, invalidFields);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
pending.catch(e => {
|
||||
if (console.error && process.env.NODE_ENV !== 'production') {
|
||||
console.error(e);
|
||||
}
|
||||
return e;
|
||||
});
|
||||
return pending;
|
||||
// names = [].concat(names);
|
||||
// const fields = this.fields.filter(field => names.indexOf(field.prop) !== -1);
|
||||
// if (!fields.length) {
|
||||
// warning(false, 'FormModel', 'please pass correct props!');
|
||||
// return;
|
||||
// }
|
||||
// fields.forEach(field => {
|
||||
// field.validate('', cb);
|
||||
// });
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
|
|
|
@ -59,6 +59,7 @@ export const FormItemProps = {
|
|||
rules: PropTypes.oneOfType([Array, Object]),
|
||||
autoLink: PropTypes.bool,
|
||||
required: PropTypes.bool,
|
||||
validateFirst: PropTypes.bool,
|
||||
validateStatus: PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
export function getValueFromEvent(e) {
|
||||
// To support custom element
|
||||
if (!e || !e.target) {
|
||||
return e;
|
||||
}
|
||||
const { target } = e;
|
||||
return target.type === 'checkbox' ? target.checked : target.value;
|
||||
}
|
||||
|
||||
export function getErrorStrs(errors) {
|
||||
if (errors) {
|
||||
return errors.map(e => {
|
||||
if (e && e.message) {
|
||||
return e.message;
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
export function getParams(ns, opt, cb) {
|
||||
let names = ns;
|
||||
let options = opt;
|
||||
let callback = cb;
|
||||
if (typeof names === 'string') {
|
||||
names = [names];
|
||||
}
|
||||
if (cb === undefined) {
|
||||
if (typeof names === 'function') {
|
||||
callback = names;
|
||||
options = {};
|
||||
names = undefined;
|
||||
} else if (Array.isArray(names)) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
} else {
|
||||
options = options || {};
|
||||
}
|
||||
} else {
|
||||
callback = options;
|
||||
options = names || {};
|
||||
names = undefined;
|
||||
}
|
||||
}
|
||||
return {
|
||||
names,
|
||||
options,
|
||||
callback,
|
||||
};
|
||||
}
|
||||
|
||||
export function hasRules(validate) {
|
||||
if (validate) {
|
||||
return validate.some(item => {
|
||||
return item.rules && item.rules.length;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -76,7 +76,7 @@
|
|||
"@commitlint/config-conventional": "^8.0.0",
|
||||
"@octokit/rest": "^16.0.0",
|
||||
"@vue/cli-plugin-eslint": "^4.0.0",
|
||||
"@vue/compiler-sfc": "^3.0.0-beta.14",
|
||||
"@vue/compiler-sfc": "^3.0.0-beta.20",
|
||||
"@vue/server-test-utils": "1.0.0-beta.16",
|
||||
"@vue/test-utils": "^2.0.0-alpha.6",
|
||||
"acorn": "^7.0.0",
|
||||
|
@ -152,7 +152,7 @@
|
|||
"terser-webpack-plugin": "^3.0.3",
|
||||
"through2": "^3.0.0",
|
||||
"url-loader": "^3.0.0",
|
||||
"vue": "^3.0.0-beta.19",
|
||||
"vue": "^3.0.0-beta.20",
|
||||
"vue-antd-md-loader": "^1.1.0",
|
||||
"vue-clipboard2": "0.3.1",
|
||||
"vue-draggable-resizable": "^2.1.0",
|
||||
|
|
Loading…
Reference in New Issue