ant-design/components/form/FormItem.jsx

208 lines
5.4 KiB
React
Raw Normal View History

2015-10-09 13:53:04 +08:00
import React from 'react';
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 {
_getLayoutClass(colDef) {
if (!colDef) {
return '';
}
2016-01-05 14:42:06 +08:00
const { span, offset } = colDef;
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) {
return (context.form.getFieldError(props.name) || []).join(', ');
}
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();
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-09 13:53:04 +08:00
}
2016-01-21 16:23:35 +08:00
getValidateStatus() {
const { isFieldValidating, getFieldError, getFieldValue } = this.context.form;
const field = this.props.name;
if (isFieldValidating(field)) {
return 'validating';
} else if (!!getFieldError(field)) {
return 'error';
} else if (getFieldValue(field)) {
return 'success';
}
}
2015-11-03 13:50:36 +08:00
renderValidateWrapper(c1, c2) {
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) {
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
}
);
}
return (
2016-01-22 14:56:35 +08:00
<div className={this.props.prefixCls + '-item-control ' + classes}>
{c1}{c2}
</div>
);
2015-10-09 13:53:04 +08:00
}
renderWrapper(children) {
const wrapperCol = this.props.wrapperCol;
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-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;
if (context.form && props.name && props.options) {
children = React.cloneElement(
React.Children.only(children),
context.form.getFieldProps(props.name, props.options)
);
}
2015-10-09 13:53:04 +08:00
return [
this.renderLabel(),
this.renderWrapper(
this.renderValidateWrapper(
2016-01-21 16:23:35 +08:00
children,
2015-11-03 13:50:36 +08:00
this.renderHelp()
2015-10-09 13:53:04 +08:00
)
),
];
}
// 判断是否要 `.ant-form-item-compact` 样式类
_isCompact(children) {
const compactControls = ['checkbox', 'radio', 'radio-group', 'static', 'file'];
let isCompact = false;
const childrenArray = Array.isArray(children) ? children : [children];
childrenArray.map((child) => {
const type = child.props && child.props.type;
let prefixCls = child.props && child.props.prefixCls;
prefixCls = prefixCls ? prefixCls.substring(prefixCls.indexOf('-') + 1) : '';
2016-01-05 14:42:06 +08:00
if ((type && compactControls.indexOf(type) > -1) ||
(prefixCls && compactControls.indexOf(prefixCls) > -1)) {
isCompact = true;
} else if (child.props && typeof child.props.children === 'object') {
isCompact = this._isCompact(child.props.children);
}
});
return isCompact;
}
2015-10-09 13:53:04 +08:00
renderFormItem(children) {
const props = this.props;
const prefixCls = props.prefixCls;
2015-10-09 13:53:04 +08:00
const itemClassName = {
[`${prefixCls}-item`]: true,
2015-11-03 13:50:36 +08:00
[`${prefixCls}-item-compact`]: this._isCompact(props.children),
[`${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 (
<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,
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,
wrapperCol: React.PropTypes.object,
2015-10-09 13:53:04 +08:00
className: React.PropTypes.string,
2016-01-21 16:23:35 +08:00
name: React.PropTypes.string,
options: React.PropTypes.object,
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;