refactor: form

This commit is contained in:
tangjinzhou 2020-07-12 16:13:59 +08:00
parent 130982a037
commit e79bfd8c96
4 changed files with 96 additions and 49 deletions

View File

@ -1,4 +1,5 @@
import { inject, provide } from 'vue';
// import scrollIntoView from 'dom-scroll-into-view';
import PropTypes from '../_util/vue-types';
import classNames from 'classnames';
import { ColProps } from '../grid/Col';
@ -99,7 +100,7 @@ const Form = {
this.$emit('submit', e);
}
},
resetFields(props = this.fields) {
resetFields(props = []) {
if (!this.model) {
warning(false, 'FormModel', 'model is required for resetFields to work.');
return;
@ -123,50 +124,53 @@ const Form = {
field.clearValidate();
});
},
validate(callback) {
if (!this.model) {
warning(false, 'FormModel', 'model is required for resetFields to work.');
return;
}
let promise;
// if no callback, return promise
if (typeof callback !== 'function' && window.Promise) {
promise = new window.Promise((resolve, reject) => {
callback = function(valid) {
valid ? resolve(valid) : reject(valid);
};
});
}
let valid = true;
let count = 0;
// fieldscallback
if (this.fields.length === 0 && callback) {
callback(true);
}
let invalidFields = {};
this.fields.forEach(field => {
field.validate('', (message, field) => {
if (message) {
valid = false;
}
invalidFields = Object.assign({}, invalidFields, field);
if (typeof callback === 'function' && ++count === this.fields.length) {
callback(valid, invalidFields);
}
});
});
if (promise) {
return promise;
}
validate() {
return this.validateField(...arguments);
// if (!this.model) {
// warning(false, 'FormModel', 'model is required for resetFields to work.');
// return;
// }
// let promise;
// // if no callback, return promise
// if (typeof callback !== 'function' && window.Promise) {
// promise = new window.Promise((resolve, reject) => {
// callback = function(valid) {
// valid ? resolve(valid) : reject(valid);
// };
// });
// }
// let valid = true;
// let count = 0;
// // fieldscallback
// if (this.fields.length === 0 && callback) {
// callback(true);
// }
// let invalidFields = {};
// this.fields.forEach(field => {
// field.validate('', (message, field) => {
// if (message) {
// valid = false;
// }
// invalidFields = Object.assign({}, invalidFields, field);
// if (typeof callback === 'function' && ++count === this.fields.length) {
// callback(valid, invalidFields);
// }
// });
// });
// if (promise) {
// return promise;
// }
},
scrollToField() {},
getFieldsValue(allFields) {
return allFields.map(({ prop, fieldValue }) => {
return { [prop]: fieldValue };
const values = {};
allFields.forEach(({ prop, fieldValue }) => {
values[prop] = fieldValue;
});
return values;
},
validateFields() {
this.validateField(...arguments);
return this.validateField(...arguments);
},
validateField(ns, opt, cb) {
const pending = new Promise((resolve, reject) => {
@ -201,18 +205,18 @@ const Form = {
return !!field.validateFirst;
});
}
let invalidFields = {};
let fieldsErrors = {};
let valid = true;
let count = 0;
fields.forEach(field => {
field.validate('', (message, field) => {
if (message) {
field.validate('', errors => {
if (errors) {
valid = false;
fieldsErrors[field.prop] = errors;
}
// TODO
invalidFields = Object.assign({}, invalidFields, field);
if (typeof callback === 'function' && ++count === fields.length) {
callback(valid, invalidFields);
if (++count === fields.length) {
callback(valid ? null : fieldsErrors, this.getFieldsValue(fields));
}
});
});

View File

@ -152,10 +152,10 @@ export default {
}
const model = {};
model[this.prop] = this.fieldValue;
validator.validate(model, { firstFields: true }, (errors, invalidFields) => {
validator.validate(model, {}, errors => {
this.validateState = errors ? 'error' : 'success';
this.validateMessage = errors ? errors[0].message : '';
callback(this.validateMessage, invalidFields);
callback(errors);
this.FormContext &&
this.FormContext.$emit &&
this.FormContext.$emit('validate', this.prop, !errors, this.validateMessage || null);

View File

@ -59,3 +59,46 @@ export function hasRules(validate) {
}
return false;
}
export function computedStyle(el, prop) {
const getComputedStyle = window.getComputedStyle;
const style =
// If we have getComputedStyle
getComputedStyle
? // Query it
// TODO: From CSS-Query notes, we might need (node, null) for FF
getComputedStyle(el)
: // Otherwise, we are in IE and use currentStyle
el.currentStyle;
if (style) {
return style[
// Switch to camelCase for CSSOM
// DEV: Grabbed from jQuery
// https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194
// https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597
prop.replace(/-(\w)/gi, (word, letter) => {
return letter.toUpperCase();
})
];
}
return undefined;
}
export function getScrollableContainer(n) {
let node = n;
let nodeName;
/* eslint no-cond-assign:0 */
while ((nodeName = node.nodeName.toLowerCase()) !== 'body') {
const overflowY = computedStyle(node, 'overflowY');
// https://stackoverflow.com/a/36900407/3040605
if (
node !== n &&
(overflowY === 'auto' || overflowY === 'scroll') &&
node.scrollHeight > node.clientHeight
) {
return node;
}
node = node.parentNode;
}
return nodeName === 'body' ? node.ownerDocument : node;
}

View File

@ -4,7 +4,7 @@
</div>
</template>
<script>
import demo from '../antdv-demo/docs/cascader/demo/index';
import demo from '../antdv-demo/docs/form-model/demo/custom-validation';
export default {
components: {