UNPKG

qm-ui

Version:

千米公有云管理端UI基础组件库

197 lines (182 loc) 5.41 kB
/** * @file * @author gcy[of1518] * @date 16/10/11 * * @description Form_Element */ import React, { Component } from 'react' import classNames from 'classnames' import { Row, Col } from 'antd' import { splitObject } from '../_util/ObjectUtil' const noop = () => undefined export default class ElementUI extends Component { static defaultProps = { id: '', index: '', //子元素唯一标识 value: undefined, // rules: {}, //校验规则 extra: undefined, //额外数据缓存,解决复杂表单数据的数据缓存问题 status: '', //校验状态 'success', 'warning', 'error', 'validating' formState: '', //'' || 'view', 默认&&编辑状态,查看审核状态 viewRender: undefined, // msg: '', //提示信息,如不设置,则会根据校验规则自动生成 string help: '', //帮助信息 label: '', //label 标签的文本 labelCol: { span: 3, offset: 12 }, //label 标签布局,通 <Col> 组件,设置 span offset 值 wrapperCol: undefined, //需要为输入控件设置布局样式时,使用该属性 prefixCls: 'ant-form', hasFeedback: false, //是否需要反馈 colon: false, convertValue: undefined, //store:->value formatValue: undefined, //onChange数据装包 默认为Event onValid: noop, onChange: undefined, //外部 } constructor(props) { super(props) } render() { let { prefixCls, style, className, colon, label, value, formState, viewRender } = this.props let children = null switch (formState) { case 'view': if (viewRender && typeof viewRender === 'function') { children = viewRender({ value, formState }) || null break } else if (viewRender && React.isValidElement(viewRender)) { children = React.cloneElement(viewRender, { value, formState }) || null break } default: children = this.renderChildren() break } const babel = this.renderLabel() const itemClassName = classNames({ ['ant-row-label-no']: !label, [`${prefixCls}-item`]: true, [`${prefixCls}-item-with-help`]: !!this.getMsg(), [`${prefixCls}-item-no-colon`]: !colon && !babel, [`${className}`]: !!className, }) let [props] = splitObject(this.props, ['id', 'style']) return ( <Row className={itemClassName} {...props}> {babel} {children} </Row> ) } //render renderChildren() { let { children, index, value, rules, hasFeedback, prefixCls, wrapperCol, status, formatValue, onValid, onChange, convertValue, } = this.props let childrenNode = React.Children.map(children, (child, k) => { let props = { value: typeof convertValue === 'function' ? convertValue(value) : value, onBlur: (data, extra) => { if (child.props.onBlur && typeof child.props.onBlur == 'function') { child.props.onBlur(data, extra) } if (rules && rules['asyncNet']) { onValid({ index }) } }, onChange: (data, extra) => { if (child.props.onChange && typeof child.props.onChange == 'function') { child.props.onChange(data, extra) } let value = data if (typeof formatValue === 'function') { value = formatValue(data) } value = value && value.target ? value.target.value : value return onChange({ index, value, extra }) }, } return React.cloneElement(child, props) }) let classes = classNames({ 'has-feedback': hasFeedback, 'has-success': status === 'success', 'has-warning': status === 'warning', 'has-error': status === 'error', 'is-validating': status === 'validating', }) return ( <Col {...wrapperCol} key="wrapper"> <div className={`${prefixCls}-item-control ${classes}`}> {childrenNode} {this.renderMsg()} {this.renderHelp()} </div> </Col> ) } /** * label渲染 */ renderLabel() { let { id, label, labelCol, prefixCls, rules } = this.props let { required } = rules || {} const className = classNames({ [`${prefixCls}-item-required`]: !!required, }) // remove user input colon if (typeof label === 'string' && label.trim() !== '') { label = label.replace(/[:|:]\s*$/, '') } const child = this.props.children !== undefined ? this.props.children : null return ( <Col {...labelCol} key="label" className={`${prefixCls}-item-label`}> <label htmlFor={id || (child && child.props && child.props['id'])} className={className}> {label} </label> </Col> ) } /** * 提示信息渲染 */ renderMsg() { const { prefixCls } = this.props const msg = this.getMsg() return msg ? ( <div className={`${prefixCls}-explain`} key="msg"> {msg} </div> ) : null } /** * 获取提示文本 */ getMsg() { return this.props.msg || null } /** * 获取额外提示信息 */ renderHelp() { const { help } = this.props return help ? ( typeof help == 'string' ? ( <span className="inline-tips">{help}</span> ) : ( help ) ) : null } }