ant-design-vue/components/form/FormItem.jsx

507 lines
15 KiB
Vue
Raw Normal View History

2019-01-12 11:33:27 +08:00
import PropTypes from '../_util/vue-types';
import classNames from 'classnames';
import find from 'lodash/find';
import Row from '../grid/Row';
import Col, { ColProps } from '../grid/Col';
import warning from '../_util/warning';
import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants';
import {
initDefaultProps,
getComponentFromProp,
filterEmpty,
getSlotOptions,
isValidElement,
getAllChildren,
} from '../_util/props-util';
import getTransitionProps from '../_util/getTransitionProps';
import BaseMixin from '../_util/BaseMixin';
import { cloneElement, cloneVNodes } from '../_util/vnode';
import Icon from '../icon';
2019-04-20 14:19:13 +08:00
import { ConfigConsumerProps } from '../config-provider';
2019-01-28 21:09:13 +08:00
function noop() {}
2019-09-11 18:11:48 +08:00
function intersperseSpace(list) {
return list.reduce((current, item) => [...current, ' ', item], []).slice(1);
}
2018-05-05 17:00:51 +08:00
export const FormItemProps = {
id: PropTypes.string,
prefixCls: PropTypes.string,
label: PropTypes.any,
labelCol: PropTypes.shape(ColProps).loose,
wrapperCol: PropTypes.shape(ColProps).loose,
help: PropTypes.any,
extra: PropTypes.any,
validateStatus: PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
hasFeedback: PropTypes.bool,
required: PropTypes.bool,
colon: PropTypes.bool,
2018-06-22 21:35:14 +08:00
fieldDecoratorId: PropTypes.string,
fieldDecoratorOptions: PropTypes.object,
2019-08-30 14:07:32 +08:00
selfUpdate: PropTypes.bool,
2019-01-12 11:33:27 +08:00
};
function comeFromSlot(vnodes = [], itemVnode) {
let isSlot = false;
for (let i = 0, len = vnodes.length; i < len; i++) {
const vnode = vnodes[i];
if (vnode && (vnode === itemVnode || vnode.$vnode === itemVnode)) {
isSlot = true;
} else {
const componentOptions =
vnode.componentOptions || (vnode.$vnode && vnode.$vnode.componentOptions);
const children = componentOptions ? componentOptions.children : vnode.$children;
isSlot = comeFromSlot(children, itemVnode);
}
if (isSlot) {
break;
}
}
return isSlot;
}
2018-05-05 17:00:51 +08:00
export default {
name: 'AFormItem',
__ANT_FORM_ITEM: true,
mixins: [BaseMixin],
props: initDefaultProps(FormItemProps, {
hasFeedback: false,
colon: true,
}),
inject: {
2019-01-28 21:09:13 +08:00
FormProps: { default: () => ({}) },
decoratorFormProps: { default: () => ({}) },
collectFormItemContext: { default: () => noop },
2019-09-11 22:35:25 +08:00
configProvider: { default: () => ConfigConsumerProps },
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
data() {
return { helpShow: false };
2018-05-05 17:00:51 +08:00
},
2019-08-30 14:07:32 +08:00
computed: {
itemSelfUpdate() {
return !!(this.selfUpdate === undefined ? this.FormProps.selfUpdate : this.selfUpdate);
},
},
2019-02-01 17:23:00 +08:00
created() {
this.collectContext();
},
2019-01-30 21:31:36 +08:00
beforeUpdate() {
if (process.env.NODE_ENV !== 'production') {
this.collectContext();
}
},
beforeDestroy() {
this.collectFormItemContext(this.$vnode.context, 'delete');
},
2019-01-12 11:33:27 +08:00
mounted() {
2019-09-11 18:11:48 +08:00
const { help, validateStatus } = this.$props;
2018-05-05 17:00:51 +08:00
warning(
2019-09-11 18:11:48 +08:00
this.getControls(this.slotDefault, true).length <= 1 ||
(help !== undefined || validateStatus !== undefined),
2018-05-05 17:00:51 +08:00
'`Form.Item` cannot generate `validateStatus` and `help` automatically, ' +
2019-01-12 11:33:27 +08:00
'while there are more than one `getFieldDecorator` in it.',
);
warning(
!this.fieldDecoratorId,
2019-01-12 11:33:27 +08:00
'`fieldDecoratorId` is deprecated. please use `v-decorator={id, options}` instead.',
);
2018-05-05 17:00:51 +08:00
},
methods: {
2019-01-30 21:31:36 +08:00
collectContext() {
if (this.FormProps.form && this.FormProps.form.templateContext) {
const { templateContext } = this.FormProps.form;
const vnodes = Object.values(templateContext.$slots || {}).reduce((a, b) => {
return [...a, ...b];
}, []);
const isSlot = comeFromSlot(vnodes, this.$vnode);
warning(!isSlot, 'You can not set FormItem from slot, please use slot-scope instead slot');
let isSlotScope = false;
// 进一步判断是否是通过slot-scope传递
if (!isSlot && this.$vnode.context !== templateContext) {
isSlotScope = comeFromSlot(this.$vnode.context.$children, templateContext.$vnode);
}
if (!isSlotScope && !isSlot) {
this.collectFormItemContext(this.$vnode.context);
}
}
},
2019-01-12 11:33:27 +08:00
getHelpMessage() {
const help = getComponentFromProp(this, 'help');
const onlyControl = this.getOnlyControl();
2018-05-05 17:00:51 +08:00
if (help === undefined && onlyControl) {
2019-01-12 11:33:27 +08:00
const errors = this.getField().errors;
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
if (errors) {
2019-09-11 18:11:48 +08:00
return intersperseSpace(
2019-01-12 11:33:27 +08:00
errors.map((e, index) => {
2019-09-11 18:11:48 +08:00
let node = null;
if (isValidElement(e)) {
node = e;
} else if (isValidElement(e.message)) {
node = e.message;
}
return node ? cloneElement(node, { key: index }) : e.message;
2019-01-12 11:33:27 +08:00
}),
);
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
} else {
2019-01-12 11:33:27 +08:00
return '';
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
}
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
return help;
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getControls(childrenArray = [], recursively) {
let controls = [];
2018-05-05 17:00:51 +08:00
for (let i = 0; i < childrenArray.length; i++) {
if (!recursively && controls.length > 0) {
2019-01-12 11:33:27 +08:00
break;
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
const child = childrenArray[i];
2018-05-05 17:00:51 +08:00
if (!child.tag && child.text.trim() === '') {
2019-01-12 11:33:27 +08:00
continue;
2018-05-05 17:00:51 +08:00
}
if (getSlotOptions(child).__ANT_FORM_ITEM) {
2019-01-12 11:33:27 +08:00
continue;
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
const children = getAllChildren(child);
const attrs = (child.data && child.data.attrs) || {};
if (FIELD_META_PROP in attrs) {
// And means FIELD_DATA_PROP in child.props, too.
controls.push(child);
} else if (children) {
2019-01-12 11:33:27 +08:00
controls = controls.concat(this.getControls(children, recursively));
2018-05-05 17:00:51 +08:00
}
}
2019-01-12 11:33:27 +08:00
return controls;
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getOnlyControl() {
const child = this.getControls(this.slotDefault, false)[0];
return child !== undefined ? child : null;
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getChildAttr(prop) {
const child = this.getOnlyControl();
let data = {};
2018-05-06 18:32:40 +08:00
if (!child) {
2019-01-12 11:33:27 +08:00
return undefined;
2018-05-06 18:32:40 +08:00
}
2018-05-05 17:00:51 +08:00
if (child.data) {
2019-01-12 11:33:27 +08:00
data = child.data;
2018-05-05 17:00:51 +08:00
} else if (child.$vnode && child.$vnode.data) {
2019-01-12 11:33:27 +08:00
data = child.$vnode.data;
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
return data[prop] || data.attrs[prop];
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getId() {
return this.getChildAttr('id');
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getMeta() {
return this.getChildAttr(FIELD_META_PROP);
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getField() {
return this.getChildAttr(FIELD_DATA_PROP);
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
onHelpAnimEnd(_key, helpShow) {
this.helpShow = helpShow;
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
if (!helpShow) {
2019-01-12 11:33:27 +08:00
this.$forceUpdate();
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
}
2018-05-05 17:00:51 +08:00
},
2019-04-20 14:19:13 +08:00
renderHelp(prefixCls) {
2019-01-12 11:33:27 +08:00
const help = this.getHelpMessage();
2018-05-05 17:00:51 +08:00
const children = help ? (
2019-01-12 11:33:27 +08:00
<div class={`${prefixCls}-explain`} key="help">
2018-05-05 17:00:51 +08:00
{help}
</div>
2019-01-12 11:33:27 +08:00
) : null;
2018-05-05 21:38:03 +08:00
if (children) {
2019-01-12 11:33:27 +08:00
this.helpShow = !!children;
2018-05-05 21:38:03 +08:00
}
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
const transitionProps = getTransitionProps('show-help', {
afterEnter: () => this.onHelpAnimEnd('help', true),
afterLeave: () => this.onHelpAnimEnd('help', false),
2019-01-12 11:33:27 +08:00
});
2018-05-05 17:00:51 +08:00
return (
2019-01-12 11:33:27 +08:00
<transition {...transitionProps} key="help">
2018-05-05 17:00:51 +08:00
{children}
</transition>
2019-01-12 11:33:27 +08:00
);
2018-05-05 17:00:51 +08:00
},
2019-04-20 14:19:13 +08:00
renderExtra(prefixCls) {
2019-01-12 11:33:27 +08:00
const extra = getComponentFromProp(this, 'extra');
return extra ? <div class={`${prefixCls}-extra`}>{extra}</div> : null;
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
getValidateStatus() {
const onlyControl = this.getOnlyControl();
2018-05-05 17:00:51 +08:00
if (!onlyControl) {
2019-01-12 11:33:27 +08:00
return '';
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
const field = this.getField();
2018-05-05 17:00:51 +08:00
if (field.validating) {
2019-01-12 11:33:27 +08:00
return 'validating';
2018-05-05 17:00:51 +08:00
}
if (field.errors) {
2019-01-12 11:33:27 +08:00
return 'error';
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
const fieldValue = 'value' in field ? field.value : this.getMeta().initialValue;
2018-05-05 17:00:51 +08:00
if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
2019-01-12 11:33:27 +08:00
return 'success';
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
return '';
2018-05-05 17:00:51 +08:00
},
2019-04-20 14:19:13 +08:00
renderValidateWrapper(prefixCls, c1, c2, c3) {
2019-01-12 11:33:27 +08:00
const props = this.$props;
const onlyControl = this.getOnlyControl;
const validateStatus =
props.validateStatus === undefined && onlyControl
? this.getValidateStatus()
: props.validateStatus;
2018-05-05 17:00:51 +08:00
2019-04-20 14:19:13 +08:00
let classes = `${prefixCls}-item-control`;
2018-05-05 17:00:51 +08:00
if (validateStatus) {
2019-04-20 14:19:13 +08:00
classes = classNames(`${prefixCls}-item-control`, {
2018-05-05 17:00:51 +08:00
'has-feedback': props.hasFeedback || validateStatus === 'validating',
'has-success': validateStatus === 'success',
'has-warning': validateStatus === 'warning',
'has-error': validateStatus === 'error',
'is-validating': validateStatus === 'validating',
2019-01-12 11:33:27 +08:00
});
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
let iconType = '';
switch (validateStatus) {
case 'success':
2019-01-12 11:33:27 +08:00
iconType = 'check-circle';
break;
case 'warning':
2019-01-12 11:33:27 +08:00
iconType = 'exclamation-circle';
break;
case 'error':
2019-01-12 11:33:27 +08:00
iconType = 'close-circle';
break;
case 'validating':
2019-01-12 11:33:27 +08:00
iconType = 'loading';
break;
default:
2019-01-12 11:33:27 +08:00
iconType = '';
break;
}
2019-01-12 11:33:27 +08:00
const icon =
props.hasFeedback && iconType ? (
2019-04-20 14:19:13 +08:00
<span class={`${prefixCls}-item-children-icon`}>
2019-01-12 11:33:27 +08:00
<Icon type={iconType} theme={iconType === 'loading' ? 'outlined' : 'filled'} />
</span>
) : null;
2018-05-05 17:00:51 +08:00
return (
<div class={classes}>
2019-04-20 14:19:13 +08:00
<span class={`${prefixCls}-item-children`}>
2019-01-12 11:33:27 +08:00
{c1}
{icon}
</span>
2019-01-12 11:33:27 +08:00
{c2}
{c3}
2018-05-05 17:00:51 +08:00
</div>
2019-01-12 11:33:27 +08:00
);
2018-05-05 17:00:51 +08:00
},
2019-04-20 14:19:13 +08:00
renderWrapper(prefixCls, children) {
const { wrapperCol = {} } = this;
2019-01-12 11:33:27 +08:00
const { class: cls, style, id, on, ...restProps } = wrapperCol;
const className = classNames(`${prefixCls}-item-control-wrapper`, cls);
2018-05-05 17:00:51 +08:00
const colProps = {
props: restProps,
class: className,
key: 'wrapper',
style,
id,
on,
2019-01-12 11:33:27 +08:00
};
return <Col {...colProps}>{children}</Col>;
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
isRequired() {
const { required } = this;
2018-05-05 17:00:51 +08:00
if (required !== undefined) {
2019-01-12 11:33:27 +08:00
return required;
2018-05-05 17:00:51 +08:00
}
if (this.getOnlyControl()) {
2019-01-12 11:33:27 +08:00
const meta = this.getMeta() || {};
const validate = meta.validate || [];
2018-05-05 17:00:51 +08:00
2019-01-12 11:33:27 +08:00
return validate
.filter(item => !!item.rules)
.some(item => {
return item.rules.some(rule => rule.required);
});
2018-05-05 17:00:51 +08:00
}
2019-01-12 11:33:27 +08:00
return false;
2018-05-05 17:00:51 +08:00
},
// Resolve duplicated ids bug between different forms
// https://github.com/ant-design/ant-design/issues/7351
2019-01-12 11:33:27 +08:00
onLabelClick(e) {
const label = getComponentFromProp(this, 'label');
const id = this.id || this.getId();
2018-05-05 17:00:51 +08:00
if (!id) {
2019-01-12 11:33:27 +08:00
return;
2018-05-05 17:00:51 +08:00
}
2019-09-11 18:11:48 +08:00
const formItemNode = this.$el;
const control = formItemNode.querySelector(`[id="${id}"]`);
if (control) {
2018-05-05 17:00:51 +08:00
// Only prevent in default situation
// Avoid preventing event in `label={<a href="xx">link</a>}``
if (typeof label === 'string') {
2019-01-12 11:33:27 +08:00
e.preventDefault();
2018-05-05 17:00:51 +08:00
}
2019-09-11 18:11:48 +08:00
if (control.focus) {
2019-01-12 11:33:27 +08:00
control.focus();
2018-05-05 17:00:51 +08:00
}
}
},
2019-04-20 14:19:13 +08:00
renderLabel(prefixCls) {
const { labelCol = {}, colon, id } = this;
2019-01-12 11:33:27 +08:00
const label = getComponentFromProp(this, 'label');
const required = this.isRequired();
const {
class: labelColClass,
style: labelColStyle,
id: labelColId,
on,
...restProps
} = labelCol;
const labelColClassName = classNames(`${prefixCls}-item-label`, labelColClass);
2018-05-05 17:00:51 +08:00
const labelClassName = classNames({
[`${prefixCls}-item-required`]: required,
2019-01-12 11:33:27 +08:00
});
2018-05-05 17:00:51 +08:00
2019-01-12 11:33:27 +08:00
let labelChildren = label;
2018-05-05 17:00:51 +08:00
// Keep label is original where there should have no colon
2019-01-12 11:33:27 +08:00
const haveColon = colon && this.FormProps.layout !== 'vertical';
2018-05-05 17:00:51 +08:00
// Remove duplicated user input colon
if (haveColon && typeof label === 'string' && label.trim() !== '') {
2019-01-12 11:33:27 +08:00
labelChildren = label.replace(/[|:]\s*$/, '');
2018-05-05 17:00:51 +08:00
}
const colProps = {
props: restProps,
class: labelColClassName,
key: 'label',
style: labelColStyle,
id: labelColId,
on,
2019-01-12 11:33:27 +08:00
};
2018-05-05 17:00:51 +08:00
return label ? (
2019-01-12 11:33:27 +08:00
<Col {...colProps}>
2018-05-05 17:00:51 +08:00
<label
2018-05-05 21:38:03 +08:00
for={id || this.getId()}
2018-05-05 17:00:51 +08:00
class={labelClassName}
title={typeof label === 'string' ? label : ''}
onClick={this.onLabelClick}
>
{labelChildren}
</label>
</Col>
2019-01-12 11:33:27 +08:00
) : null;
2018-05-05 17:00:51 +08:00
},
2019-04-20 14:19:13 +08:00
renderChildren(prefixCls) {
2018-05-05 17:00:51 +08:00
return [
2019-04-20 14:19:13 +08:00
this.renderLabel(prefixCls),
2018-05-05 17:00:51 +08:00
this.renderWrapper(
2019-04-20 14:19:13 +08:00
prefixCls,
this.renderValidateWrapper(
prefixCls,
this.slotDefault,
this.renderHelp(prefixCls),
2019-05-28 11:37:38 +08:00
this.renderExtra(prefixCls),
2019-04-20 14:19:13 +08:00
),
2018-05-05 17:00:51 +08:00
),
2019-01-12 11:33:27 +08:00
];
2018-05-05 17:00:51 +08:00
},
2019-04-20 14:19:13 +08:00
renderFormItem() {
const { prefixCls: customizePrefixCls, colon } = this.$props;
2019-09-11 22:35:25 +08:00
const getPrefixCls = this.configProvider.getPrefixCls;
2019-04-20 14:19:13 +08:00
const prefixCls = getPrefixCls('form', customizePrefixCls);
const children = this.renderChildren(prefixCls);
2018-05-05 17:00:51 +08:00
const itemClassName = {
[`${prefixCls}-item`]: true,
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
2018-09-05 21:28:54 +08:00
[`${prefixCls}-item-with-help`]: this.helpShow,
2019-04-20 14:19:13 +08:00
[`${prefixCls}-item-no-colon`]: !colon,
2019-01-12 11:33:27 +08:00
};
2018-05-05 17:00:51 +08:00
2019-01-12 11:33:27 +08:00
return <Row class={classNames(itemClassName)}>{children}</Row>;
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
decoratorOption(vnode) {
if (vnode.data && vnode.data.directives) {
2019-01-12 11:33:27 +08:00
const directive = find(vnode.data.directives, ['name', 'decorator']);
warning(
!directive || (directive && Array.isArray(directive.value)),
`Invalid directive: type check failed for directive "decorator". Expected Array, got ${typeof (directive
? directive.value
: directive)}. At ${vnode.tag}.`,
2019-01-12 11:33:27 +08:00
);
return directive ? directive.value : null;
} else {
2019-01-12 11:33:27 +08:00
return null;
}
},
2019-01-12 11:33:27 +08:00
decoratorChildren(vnodes) {
const { FormProps } = this;
const getFieldDecorator = FormProps.form.getFieldDecorator;
for (let i = 0, len = vnodes.length; i < len; i++) {
const vnode = vnodes[i];
if (getSlotOptions(vnode).__ANT_FORM_ITEM) {
break;
}
if (vnode.children) {
2019-01-12 11:33:27 +08:00
vnode.children = this.decoratorChildren(cloneVNodes(vnode.children));
} else if (vnode.componentOptions && vnode.componentOptions.children) {
2019-01-12 11:33:27 +08:00
vnode.componentOptions.children = this.decoratorChildren(
cloneVNodes(vnode.componentOptions.children),
);
}
2019-01-12 11:33:27 +08:00
const option = this.decoratorOption(vnode);
if (option && option[0]) {
2019-08-30 14:07:32 +08:00
vnodes[i] = getFieldDecorator(option[0], option[1], this)(vnode);
}
}
2019-01-12 11:33:27 +08:00
return vnodes;
},
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
render() {
const {
$slots,
decoratorFormProps,
fieldDecoratorId,
fieldDecoratorOptions = {},
FormProps,
} = this;
let child = filterEmpty($slots.default || []);
2018-06-23 17:17:45 +08:00
if (decoratorFormProps.form && fieldDecoratorId && child.length) {
2019-01-12 11:33:27 +08:00
const getFieldDecorator = decoratorFormProps.form.getFieldDecorator;
2019-08-30 14:07:32 +08:00
child[0] = getFieldDecorator(fieldDecoratorId, fieldDecoratorOptions, this)(child[0]);
2018-06-24 21:18:45 +08:00
warning(
!(child.length > 1),
'`autoFormCreate` just `decorator` then first children. but you can use JSX to support multiple children',
2019-01-12 11:33:27 +08:00
);
this.slotDefault = child;
} else if (FormProps.form) {
2019-01-12 11:33:27 +08:00
child = cloneVNodes(child);
this.slotDefault = this.decoratorChildren(child);
} else {
2019-01-12 11:33:27 +08:00
this.slotDefault = child;
2018-06-22 21:35:14 +08:00
}
2019-04-20 14:19:13 +08:00
return this.renderFormItem();
2018-05-05 17:00:51 +08:00
},
2019-01-12 11:33:27 +08:00
};