2015-10-09 13:53:04 +08:00
|
|
|
import React from 'react';
|
2015-11-24 20:03:57 +08:00
|
|
|
import classNames from 'classnames';
|
2015-10-09 13:53:04 +08:00
|
|
|
|
|
|
|
function prefixClsFn(prefixCls, ...args) {
|
2016-01-05 14:42:06 +08:00
|
|
|
return args.map((s) => {
|
2015-10-09 13:53:04 +08:00
|
|
|
return prefixCls + '-' + s;
|
|
|
|
}).join(' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
class FormItem extends React.Component {
|
2015-10-29 08:40:51 +08:00
|
|
|
_getLayoutClass(colDef) {
|
|
|
|
if (!colDef) {
|
|
|
|
return '';
|
|
|
|
}
|
2016-01-05 14:42:06 +08:00
|
|
|
const { span, offset } = colDef;
|
2015-10-29 08:40:51 +08:00
|
|
|
const col = span ? 'col-' + span : '';
|
|
|
|
const offsetCol = offset ? ' col-offset-' + offset : '';
|
|
|
|
return col + offsetCol;
|
|
|
|
}
|
|
|
|
|
2016-01-21 16:23:35 +08:00
|
|
|
getHelpMsg() {
|
|
|
|
const context = this.context;
|
|
|
|
const props = this.props;
|
|
|
|
if (props.help === undefined && context.form) {
|
2016-01-22 14:56:33 +08:00
|
|
|
return (context.form.getFieldError(props.id) || []).join(', ');
|
2016-01-21 16:23:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return props.help;
|
|
|
|
}
|
|
|
|
|
2015-10-09 13:53:04 +08:00
|
|
|
renderHelp() {
|
2016-01-21 16:23:35 +08:00
|
|
|
const props = this.props;
|
|
|
|
const prefixCls = props.prefixCls;
|
|
|
|
const help = this.getHelpMsg();
|
2015-10-31 08:43:38 +08:00
|
|
|
return (
|
2016-01-21 16:23:35 +08:00
|
|
|
<div className={!!help ? prefixClsFn(prefixCls, 'explain') : ''}
|
|
|
|
key="help">
|
|
|
|
{ help }
|
2015-10-09 13:53:04 +08:00
|
|
|
</div>
|
2015-10-31 08:43:38 +08:00
|
|
|
);
|
2015-10-09 13:53:04 +08:00
|
|
|
}
|
|
|
|
|
2016-01-21 16:23:35 +08:00
|
|
|
getValidateStatus() {
|
|
|
|
const { isFieldValidating, getFieldError, getFieldValue } = this.context.form;
|
2016-01-22 14:56:33 +08:00
|
|
|
const field = this.props.id;
|
2016-01-21 16:23:35 +08:00
|
|
|
|
|
|
|
if (isFieldValidating(field)) {
|
|
|
|
return 'validating';
|
|
|
|
} else if (!!getFieldError(field)) {
|
|
|
|
return 'error';
|
2016-01-25 15:00:03 +08:00
|
|
|
} else if (getFieldValue(field) !== undefined) {
|
2016-01-21 16:23:35 +08:00
|
|
|
return 'success';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-26 15:40:47 +08:00
|
|
|
renderValidateWrapper(c1, c2, c3) {
|
2015-10-30 11:36:11 +08:00
|
|
|
let classes = '';
|
2016-01-21 16:23:35 +08:00
|
|
|
const form = this.context.form;
|
|
|
|
const props = this.props;
|
|
|
|
const validateStatus = (props.validateStatus === undefined && form) ?
|
|
|
|
this.getValidateStatus() :
|
|
|
|
props.validateStatus;
|
|
|
|
|
|
|
|
if (validateStatus) {
|
2015-11-24 20:03:57 +08:00
|
|
|
classes = classNames(
|
2015-10-09 13:53:04 +08:00
|
|
|
{
|
2016-01-21 16:23:35 +08:00
|
|
|
'has-feedback': props.hasFeedback,
|
|
|
|
'has-success': validateStatus === 'success',
|
|
|
|
'has-warning': validateStatus === 'warning',
|
|
|
|
'has-error': validateStatus === 'error',
|
|
|
|
'is-validating': validateStatus === 'validating',
|
2015-10-09 13:53:04 +08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2015-10-30 11:36:11 +08:00
|
|
|
return (
|
2016-01-22 14:56:35 +08:00
|
|
|
<div className={this.props.prefixCls + '-item-control ' + classes}>
|
2016-01-26 15:38:58 +08:00
|
|
|
{c1}{c2}{c3}
|
2015-10-30 11:36:11 +08:00
|
|
|
</div>
|
|
|
|
);
|
2015-10-09 13:53:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
renderWrapper(children) {
|
2015-10-29 08:40:51 +08:00
|
|
|
const wrapperCol = this.props.wrapperCol;
|
2015-10-31 08:43:38 +08:00
|
|
|
return (
|
2015-11-03 13:50:36 +08:00
|
|
|
<div className={this._getLayoutClass(wrapperCol)} key="wrapper">
|
2015-10-09 13:53:04 +08:00
|
|
|
{children}
|
|
|
|
</div>
|
2015-10-31 08:43:38 +08:00
|
|
|
);
|
2015-10-09 13:53:04 +08:00
|
|
|
}
|
|
|
|
|
2016-01-21 16:23:35 +08:00
|
|
|
isRequired() {
|
|
|
|
const options = this.props.options;
|
|
|
|
if (options === undefined) return false;
|
|
|
|
|
|
|
|
const allRules = (options.validate || []).concat({
|
|
|
|
rules: options.rules || [],
|
|
|
|
});
|
|
|
|
return allRules.some((item) => {
|
|
|
|
return item.rules.some((rule) => rule.required);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-10-09 13:53:04 +08:00
|
|
|
renderLabel() {
|
2016-01-21 16:23:35 +08:00
|
|
|
const props = this.props;
|
|
|
|
const labelCol = props.labelCol;
|
|
|
|
const required = props.required === undefined ?
|
|
|
|
this.isRequired() :
|
|
|
|
props.required;
|
2015-10-09 13:53:04 +08:00
|
|
|
|
2016-01-21 16:23:35 +08:00
|
|
|
return props.label ? (
|
|
|
|
<label htmlFor={props.id} className={this._getLayoutClass(labelCol)}
|
2016-01-05 14:42:06 +08:00
|
|
|
required={required} key="label">
|
2016-01-21 16:23:35 +08:00
|
|
|
{props.label}
|
2015-10-09 13:53:04 +08:00
|
|
|
</label>
|
2015-11-03 13:50:36 +08:00
|
|
|
) : null;
|
2015-10-09 13:53:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
renderChildren() {
|
2016-01-21 16:23:35 +08:00
|
|
|
const context = this.context;
|
|
|
|
const props = this.props;
|
|
|
|
let children = props.children;
|
2016-01-22 14:56:33 +08:00
|
|
|
if (context.form && props.id && props.options) {
|
2016-01-21 16:23:35 +08:00
|
|
|
children = React.cloneElement(
|
|
|
|
React.Children.only(children),
|
2016-01-22 15:00:37 +08:00
|
|
|
{ ...context.form.getFieldProps(props.id, props.options), id: props.id }
|
2016-01-21 16:23:35 +08:00
|
|
|
);
|
|
|
|
}
|
2015-10-09 13:53:04 +08:00
|
|
|
return [
|
|
|
|
this.renderLabel(),
|
|
|
|
this.renderWrapper(
|
|
|
|
this.renderValidateWrapper(
|
2016-01-21 16:23:35 +08:00
|
|
|
children,
|
2016-01-26 15:38:58 +08:00
|
|
|
this.renderHelp(),
|
|
|
|
props.extra
|
2015-10-09 13:53:04 +08:00
|
|
|
)
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
renderFormItem(children) {
|
2015-10-25 11:33:19 +08:00
|
|
|
const props = this.props;
|
|
|
|
const prefixCls = props.prefixCls;
|
2015-10-09 13:53:04 +08:00
|
|
|
const itemClassName = {
|
|
|
|
[`${prefixCls}-item`]: true,
|
2015-12-31 15:57:24 +08:00
|
|
|
[`${prefixCls}-item-with-help`]: !!props.help,
|
2016-01-12 14:24:42 +08:00
|
|
|
[`${props.className}`]: !!props.className,
|
2015-10-09 13:53:04 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2015-11-24 20:03:57 +08:00
|
|
|
<div className={classNames(itemClassName)}>
|
2015-10-09 13:53:04 +08:00
|
|
|
{children}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const children = this.renderChildren();
|
|
|
|
return this.renderFormItem(children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FormItem.propTypes = {
|
|
|
|
prefixCls: React.PropTypes.string,
|
|
|
|
label: React.PropTypes.node,
|
2015-10-29 08:40:51 +08:00
|
|
|
labelCol: React.PropTypes.object,
|
2016-01-12 14:24:42 +08:00
|
|
|
help: React.PropTypes.oneOfType([React.PropTypes.node, React.PropTypes.bool]),
|
2015-10-29 18:59:06 +08:00
|
|
|
validateStatus: React.PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
|
2015-10-09 13:53:04 +08:00
|
|
|
hasFeedback: React.PropTypes.bool,
|
2015-10-29 08:40:51 +08:00
|
|
|
wrapperCol: React.PropTypes.object,
|
2015-10-09 13:53:04 +08:00
|
|
|
className: React.PropTypes.string,
|
2016-01-22 14:56:33 +08:00
|
|
|
id: React.PropTypes.string,
|
2016-01-21 16:23:35 +08:00
|
|
|
options: React.PropTypes.object,
|
2015-10-29 08:40:51 +08:00
|
|
|
children: React.PropTypes.node,
|
2015-10-09 13:53:04 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
FormItem.defaultProps = {
|
|
|
|
hasFeedback: false,
|
|
|
|
prefixCls: 'ant-form',
|
|
|
|
};
|
|
|
|
|
2016-01-21 16:23:35 +08:00
|
|
|
FormItem.contextTypes = {
|
|
|
|
form: React.PropTypes.object,
|
|
|
|
};
|
|
|
|
|
2015-10-09 13:53:04 +08:00
|
|
|
module.exports = FormItem;
|