diff --git a/docs/form/demo/validate-custom-error.md b/docs/form/demo/validate-custom-error.md index a14a04baa0..0f9ab26a86 100644 --- a/docs/form/demo/validate-custom-error.md +++ b/docs/form/demo/validate-custom-error.md @@ -1,4 +1,4 @@ -# 校验 +# 校验(自定义错误) - order: 9 diff --git a/docs/form/demo/validate-label-as-name.md b/docs/form/demo/validate-label-as-name.md new file mode 100644 index 0000000000..16498ff18b --- /dev/null +++ b/docs/form/demo/validate-label-as-name.md @@ -0,0 +1,91 @@ +# label作为校验提示 + +- order: 9 + +使用 label 作为校验提示 + +:::lang=en-us +# Validate + +- order: 9 + +use label as name for validate message +::: + +--- + +````jsx +import { Form, Input, Radio } from '@alifd/next'; + + +const FormItem = Form.Item; +const RadioGroup = Radio.Group; + +const formItemLayout = { + labelCol: { + span: 6 + }, + wrapperCol: { + span: 14 + } +}; + +class Demo extends React.Component { + render() { + return ( +
+ + + + + + + + + + + + + + Male + Female + + + + + + + + + console.log(v, e)} style={{marginRight: 10}}>Submit + Reset + +
+ ); + } +} + +ReactDOM.render(, mountNode); +```` diff --git a/package.json b/package.json index c19ce5958d..a6925261d2 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ }, "dependencies": { "@alifd/field": "~1.3.3", - "@alifd/validate": "~1.1.4", + "@alifd/validate": "~1.2.0", "babel-runtime": "^6.26.0", "classnames": "^2.2.3", "hoist-non-react-statics": "^2.1.0", diff --git a/src/form/enhance.jsx b/src/form/enhance.jsx index 7dc0df708f..1d1e5730b2 100644 --- a/src/form/enhance.jsx +++ b/src/form/enhance.jsx @@ -32,7 +32,7 @@ function getValueName(props, displayName) { return 'value'; } -export function getRules(props) { +export function getRules(props, labelForErrorMessage) { const result = []; // required @@ -99,14 +99,20 @@ export function getRules(props) { }); } + if (labelForErrorMessage) { + result.forEach(r => { + r.aliasName = labelForErrorMessage; + }); + } + return result; } -export function getFieldInitCfg(props, displayName) { +export function getFieldInitCfg(props, displayName, labelForErrorMessage) { return { valueName: getValueName(props, displayName), trigger: props.trigger ? props.trigger : 'onChange', autoValidate: props.autoValidate, - rules: getRules(props), + rules: getRules(props, labelForErrorMessage), }; } diff --git a/src/form/form.jsx b/src/form/form.jsx index 39898d6bf0..cef125c1bb 100644 --- a/src/form/form.jsx +++ b/src/form/form.jsx @@ -112,6 +112,10 @@ export default class Form extends React.Component { * 是否开启预览态 */ isPreview: PropTypes.bool, + /** + * 是否使用 label 替换校验信息的 name 字段 + */ + useLabelForErrorMessage: PropTypes.bool, }; static defaultProps = { @@ -130,6 +134,7 @@ export default class Form extends React.Component { _formSize: PropTypes.string, _formPreview: PropTypes.bool, _formFullWidth: PropTypes.bool, + _formLabelForErrorMessage: PropTypes.bool, }; constructor(props) { @@ -165,6 +170,7 @@ export default class Form extends React.Component { _formSize: this.props.size, _formPreview: this.props.isPreview, _formFullWidth: this.props.fullWidth, + _formLabelForErrorMessage: this.props.useLabelForErrorMessage, }; } diff --git a/src/form/item.jsx b/src/form/item.jsx index 75708866b3..160a91c510 100644 --- a/src/form/item.jsx +++ b/src/form/item.jsx @@ -218,6 +218,10 @@ export default class Item extends React.Component { * @param {any} value 根据包裹的组件的 value 类型而决定 */ renderPreview: PropTypes.func, + /** + * 是否使用 label 替换校验信息的 name 字段 + */ + useLabelForErrorMessage: PropTypes.bool, }; static defaultProps = { @@ -231,6 +235,7 @@ export default class Item extends React.Component { _formSize: PropTypes.oneOf(['large', 'small', 'medium']), _formPreview: PropTypes.bool, _formFullWidth: PropTypes.bool, + _formLabelForErrorMessage: PropTypes.bool, }; static _typeMark = 'form_item'; @@ -299,6 +304,26 @@ export default class Item extends React.Component { : this.props.fullWidth; } + getLabelForErrorMessage() { + let label = this.props.label; + + if (!label || typeof label !== 'string') { + return null; + } + + label = label.replace(':', '').replace(':', ''); + + const labelForErrorMessage = + 'useLabelForErrorMessage' in this.props + ? this.props.useLabelForErrorMessage + : this.context._formLabelForErrorMessage; + if (labelForErrorMessage && label) { + return label; + } + + return null; + } + getItemLabel() { const { id, @@ -403,6 +428,8 @@ export default class Item extends React.Component { childrenNode = children(this.context._formField.getValues()); } + const labelForErrorMessage = this.getLabelForErrorMessage(); + const ele = React.Children.map(childrenNode, child => { if ( child && @@ -421,7 +448,8 @@ export default class Item extends React.Component { { ...getFieldInitCfg( this.props, - child.type.displayName + child.type.displayName, + labelForErrorMessage ), props: { ...child.props, ref: child.ref }, }, diff --git a/test/form/validate-spec.js b/test/form/validate-spec.js index 3904615d40..d0863706a0 100644 --- a/test/form/validate-spec.js +++ b/test/form/validate-spec.js @@ -204,6 +204,26 @@ describe('Submit', () => { .text() === 'first 是必填字段' ); }); + it('validate useLabelForErrorMessage', () => { + const wrapper = mount( +
+ + + +
+ ); + + wrapper + .find('input#first') + .simulate('change', { target: { value: '' } }); + wrapper.update(); + assert( + wrapper + .find('.next-form-item-help') + .first() + .text() === '姓名 是必填字段' + ); + }); }); describe('Reset', () => {