react-component / form Goto Github PK
View Code? Open in Web Editor NEWReact High Order Form Component(web & react-native)
Home Page: http://react-component.github.io/form/
License: MIT License
React High Order Form Component(web & react-native)
Home Page: http://react-component.github.io/form/
License: MIT License
虽然,整个代码的逻辑非常清楚,但是,要是代码中能多加点注释,看起来会更方便一些。
checkPass(rule, value, callback) { callback(); }
value的值是怎么获取到的呢?自定义的组件不是input,是一个相册选择
Need some functionality (e.g. callback) which trigger only on validate state change (valid/invalid).
Or is it already possible to do?
Thanks
I am trying to create a form using rc-select and rc-slider components, check my render
render() {
const { getFieldProps, getFieldError } = this.props.form;
const errorEMail = getFieldError('email');
return(
<div style={ regionStyle }>
<div style={style}>
<Slider range allowCross={false} defaultValue={[0, 20]} handle={<CustomHandle />} onChange={log} />
</div>
<div>
<div style={{ width: 300 }}>
<label htmlFor="country">Country</label>
<Select
placeholder="select your country"
defaultActiveFirstOption={false}
showSearch={false}
style={{ width: 500 }}
onChange={onChange}
combobox
>
<OptGroup label="manager">
<Option value="jack">
<b style={{color: 'red'}}>
jack
</b>
</Option>
<Option value="lucy">lucy</Option>
</OptGroup>
<OptGroup label="engineer">
<Option value="yiminghe">yiminghe</Option>
</OptGroup>
</Select>
</div>
</div>
<div>
<label htmlFor="email">E-mail</label>
<input {...getFieldProps('email', {
validateFirst: true,
rules: [
{
required: true,
},
{
type: 'email',
message: 'Invalid E-mail',
}
],
validateTrigger: 'onBlur',
id: 'email'
})}
/>
<div style={errorStyle}>
{(errorEMail) ? errorEMail.join(',') : null}
</div>
</div>
<button onClick={this.submit}>Search</button>
</div>);
},
When I submit the button I only get access to input , bue select and slides values are not availble, this is my submit function
submit(e) {
e.preventDefault();
this.props.form.validateFields((error, values) => {
if (!error) {
console.log('ok', values);
} else {
console.log('error', error, values);
}
});
},
Check the output
How could I access those values?
http://react-component.github.io/form/examples/input-array.html
const inputs = [0,1,2,3].map((k)=> {
return <div key={k}><input {...getFieldProps('peoples[].name',{
indexes: [k]
})}/> <a
onClick={this.remove.bind(this,k)}>delete</a></div>;
});
when use deep rule validation, as following, if onChange get partial value : {name:"hello"}, the validation of form will not be error.
I think the error may be in the code,
https://github.com/react-component/form/blob/master/src/createBaseForm.js#L503
which test the Field.error and Field.subField.error,
nowField.errors = fieldErrors && fieldErrors.errors;
here need to be OR relationship?
the case code :
const proxyRule = {
type: 'object', required: true, message: 'proxy 信息',
fields: {
name: { type: 'string', required: true, message: 'proxy主机名' },
ipv4: { type: 'string', required: true, message: 'proxy Ip' },
}
};
and formItem use it :
<FormItem
{...formItemLayoutWithOutLabel}
inline
hasFeedback
key={id}
>
{
getFieldDecorator(`proxy-${id}`, {
rules: [proxyRule],
initialValue: { name, ipv4 }
})(<ProxyAdd removable={proxyCount !== 1} remove={this.remove(id)} />)
}
</FormItem>
component ProxyAdd:
class ProxyAdd extends Component {
constructor(props) {
super(props);
const { name, ipv4 } = this.props.value || {};
this.state = {
name, ipv4
};
}
updateState = (key) => (e) => {
const state = {};
state[key] = e.target.value;
this.setState(state);
this.props.onChange({ ...this.state, ...state });
}
render() {
const { removable } = this.props;
const { name, ipv4 } = this.state;
return (
<Input.Group>
<Col span="8">
<Input
type="text"
value={name}
placeholder="proxy name"
onChange={this.updateState('name')} />
</Col>
<Col span="6">
<Input
type="text"
placeholder="ipv4"
value={ipv4}
onChange={this.updateState('ipv4')} />
</Col>
</Input.Group>
);
}
}
https://github.com/react-component/form/blob/master/src/createBaseForm.js#L503
I'd like to add custom rules to the async-validator library used. There is a register
method on the AsyncValidator constructor.
It would be nice if rc-form would expose that in some way. Either export the AsyncValidator in a separate file and have baseForm import that file. You could then import AsyncValidator in your own project and register rules before calling createForm?
// base
import AsyncValidator from './AsyncValidator'
// my-lib
import AsyncValidator from 'rc-form/AsyncValidator'
AsyncValidator.register('customRule', () => {})
This is just from the top of my head but I'd really would like to use the proper "register" for rules rather than importing them as methods all over
Checkbox.AgreeItem on onChange?
<div>
<Checkbox.AgreeItem checked={this.state.isAgree}
onChange={()=>{alert('同间协议')}}>我已阅读并同意<a
onClick={(e) => { e.preventDefault(); alert('打开协议'); }}>会员注册协议</a></Checkbox.AgreeItem>
</div>
使用如下的方式给 form 绑定上 onChange 回调后,调用 validateFields 或者validateFieldsAndScroll 时会触发该回调,这样会导致需要验证的域在改变的时候会触发两次该回调。
Form.create({
onFieldsChange(props, changedFields) {
props.onChange(changedFields);
}
})(BaseForm);
https://github.com/react-component/form/blob/master/src/createBaseForm.js#L19
didn't see API about these.
In our case we sometimes use a context to pass objects so it would be nice to provide a way to access it inside of mapPropsToFields.
mapPropsToFields(props, context) => .....
On this sample
http://react-component.github.io/form/examples/data-binding-form.html
Email is on by default, but field for email address isn't
When upgrading React:
Warning: Form: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.
For the life of me I can't seem to figure out how to clear the input boxes after submission.
resetFields doesn't work. setInitialiValues doesn't work. Very frustrating!
In input form
{getFieldDecorator('member[0].name.firstname', {})(<input/>)}
{getFieldDecorator('member[1].name.firstname', {})(<input/>)}
this.props.form.getFieldsValue() 返回数据结构为
members: [{ name: {firstname: "xxx"} }, { name: {firstname: "yyy"} }]
Form is changing an uncontrolled input of type undefined to be controlled. Input elements should not switch from uncontrolled to controlled(or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components
在使用 rc-form 时,我定义了一个剔除头尾空白的逻辑(用户输入过程中可以在尾部输入空白,然后继续输入其他有效内容,即空白可以出现中中间),同时这个逻辑可以避免用户输入全部是空白的无效内容。
rules: [
{required: true, transform: value => String(value).trim() },
],
但是在 form.validateFields(err, value) 中拿到的值确实未经处理的,这个时候需要再做一次同样的处理逻辑(实际校验通过的内容,和提交时拿到的却是通不过校验的原始内容,不一致)。
建议 validateFields 时的结果值应该经过 transform 预处理。
我按照以下两个例子,试图把file input的 formData 放在redux中,但是出现了报错.
实在不知道使用getFieldDecorator正确的写法是怎么样的?
能否更新一下getFieldDecorator的那个例子?
谢谢
http://react-component.github.io/form/examples/redux.html
http://react-component.github.io/form/examples/file-input.html
getValueFromFileEvent({ target }) {
return {target};
}
...
{getFieldDecorator('contentFile', {
getValueFromEvent: this.getValueFromFileEvent.bind(this),
})(<input type="file" />)}
...
export default connect(mapStoreToProps, mapDispatchToProps)(Form.create({
mapPropsToFields(props) {
return {
contentFile: props.formData.contentFile,
};
},
onFieldsChange(props, fields) {
props.setTemplateForm(fields);
},
})(AddTemplate));
报错:
Warning: AddTemplate is changing an uncontrolled input of type file to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components
Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
rc-form 应该不会集成到 antd 里面了,毕竟是纯功能的,而且集成进去可能会导致 antd.Form
变复杂。
但是觉得可以利用 rc-form 简化 FormItem
的用法,如果 getFieldProps
的返回值增加 name
字段,那么 FormItem
的 validateStatus
和 help
都可以自行计算出来,就不需要用户传入了。当然,如果用户传入,就会优先使用用户设置的值。
<FormItem
label="用户名:"
id="name"
labelCol={{span: 7}}
wrapperCol={{span: 12}}
validateStatus={this.getValidateStatus('name')} // 可自动生成
hasFeedback
help={(getFieldError('name') || []).join(', ')} // 可自动生成
required>
<Input {...getFieldProps('name', {
rules: [
{require: true, min: 5, message: '用户名至少为 5 个字符'},
{validator: this.userExists},
],
})} id="name" placeholder="实时校验,输入 JasonWood 看看" />
</FormItem>
当然,如果连 required
都暴露出来的话,FormItem[required]
也可以自动设置,不过这个需要计算,而 name
值则是直接使用 getFieldProps
的第一个参数就行。
在用form
表单时,经常需要封装一些自定义组件,相对应的检验规则希望能在这些组件中动态设置,而不是统一在使用getFieldDecorator
时传入。
@connect({
// redux
})
@form({
mapPropsToFields(props) {
// props.user: {value,error,validating}
return {
user: props.user
};
},
onFieldChange(props,field) {
// field: {name, value, error,validating}
props.dispatch(...)
}
})
class App extends Component {
oSubmit(e) {
this.props.form.validate((error) => {
if(!error){
var values = this.props.form.getFieldsValue();
// ...
}
});
},
render() {
const {
getField, getFieldError, getFieldValue,
setFieldsValue,
isFieldValidating,
getFieldsValue,reset, removeField
} = this.props.form;
let error;
return <div>
<form onSubmit={this.oSubmit}>
<input {...getField({
name: 'user',
rules: [[{required: true, min: 5}, {validator: this.userExists}]],
trigger:'onBlur' // defaults to onChange
})}/>
{error = getFieldError('user') ? error : null}
{isFieldValidating('user') ? 'validating': null}
</div>;
}
}
This option is really helped sometimes and I found it from the sources. No any description of it in readme.
And maybe descibe it in antd's doc too?
form里有个自定义控件,get出来的还是传进去的initialValue
类型的场景还有:想修改Input里输入的值作为value,比如整理一下格式
错误:
Form 由于使用了高阶组件, 先调用了 getFieldProps , 包含初始化 fieldMeta
fieldMeta = fieldsMeta[name] = fieldsMeta[name] || {};
rc-form 重载了 ref
inputProps.ref = this.getCacheBind(name, `${name}__ref`, this.saveRef);
该方法会在 component unmount 时调用
saveRef 清理了 meta state
saveRef(name, _, component) {
if (!component) {
// after destroy, delete data
delete this.fieldsMeta[name];
delete this.fields[name];
delete this.instances[name];
delete this.cachedBind[name];
return;
}
const fieldMeta = this.getFieldMeta(name); // 第二次调用时 由于 fieldMeta 为空, 所以并不会执行 ref(component)
if (fieldMeta) {
const ref = fieldMeta.ref;
if (ref) {
if (typeof ref === 'string') {
throw new Error(`can not set ref string for ${name}`);
}
ref(component);
}
}
this.instances[name] = component;
},
在 react attachRef时, saveRef 会再次被调用, 但此时 fieldMeta 已经在 unmount 时被删除了
所以此时 ref(component) 不会被触发, 导致报错
reset() {
this.props.form.resetFields()
}
render() {
const { getFieldProps } = this.props.form
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 20 },
}
return (
<div>
<a onClick={::this.showModal}>修改</a>
<Modal title="编辑权限"
maskClosable={false}
visible={this.state.modalVisible}
onOk={this.handleSubmit}
onCancel={this.hideModal}
>
<Form horizontal form={this.props.form}>
<FormItem
{...formItemLayout}
label="菜单权限名称"
>
<Input {...getFieldProps('menu_title', {})} />
</FormItem>
<FormItem
{...formItemLayout}
label="url"
>
<Input {...getFieldProps('url', {})} />
</FormItem>
<FormItem
{...formItemLayout}
label="排序编号"
>
<InputNumber {...getFieldProps('sort_num', {})} min={1} defaultValue={0} />
</FormItem>
<Button type="ghost" onClick={::this.reset}>重置</Button>
</Form>
</Modal>
</div>
)
}
Who can give me some advice? thx!
I'm using antd (as you know :), and i can't find how to localize default validators. any ideas?
当我想判断一个 field 的 value
是否为空串时,现在只能这样:
if (!!getFieldsValue(['name']).name) {
// do something
}
想增加一个 getFieldValue
函数,就可以用下面的方式访问:
if (!!getFieldsValue('name')) {
// do something
}
如果增加 getFieldValue
,是否也需增加一个对应的 setFieldValue(fieldName, value)
?
目前将 fields 直接存储到 redux store 中,但是会遇到如下的错误:
VM3378:21 Uncaught TypeError: Converting circular structure to JSON
经排查后发现这是 Redux DevTools 报的错,由 fields 各字段中的 'instance' 引起,在 dispatch 前删掉就可以正常。
现在想问下,这个属性的作用是什么,可以删掉吗?如果删掉没问题最好还是在 onFieldsChange 的参数中就干掉。
Hi guys,
It is possible to disable the form button when all ForItem are not valided ?
Like react-validation does.
Thanks.
I have 2 custom components:
(1) is working - I don't have to provide initialValue
component with valuePropName as string
{getFieldDecorator('background', { valuePropName: 'color'})(
<ColorPicker/>
)}
(2) is NOT working - I HAVE to provide initialValue
component with valuePropName as array
{getFieldDecorator('range', { valuePropName: 'limit', initialValue: get(info, 'range')})(
<RangeInput/>
)}
目前 mapPropsToFields 不能有效的替代 componentWillReceiveProps
因为在 componentWillReceiveProps 里可以通过 this.props 获得当前的props。
而mapPropsToFields 没法获取到 当前的 props
Error info in createBaseForm.js
Uncaught TypeError: Cannot read property 'instance' of undefined
However, [email protected] is OK.
"Warning: Unknown prop `__meta` on <input> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
__meta
在这里是有用的,不太好去掉,看看有没有别的方式来处理。
Relative: ant-design/ant-design#1011 (comment)
增加参数,用以配置 scrollIntoView
的 config。
按照官网的 nested-field 例子,将 setFieldsValue 赋值改变成 mapPropsToFields,nested-field 不能得到初始值,其他 field 能正常赋值。
option.validateTrigger
现在的设计只支持一个 trigger,如果我有一个 input[email][required]
希望:
onBlur
的时候进行校验,以确保用户有输入onChange
的时候进行校验,以确保格式正确现在的 API 好像不行。
Hey!
according to http://recharts.org/#/zh-CN/api/Radar ,it seems no onClick
Properties in Radar
.
Is there any way to deal with it ?
For my use case, if each label can have a specified callback or the callback function can pass which label has been clicked will convenience for me
Thx:)
The problem is that the value of the input field is 1000 it then gets normalized into 1,000 which is all good but on onSubmit the value is 1.000 but I want it to be unformatted.
I tried using normalize and getValueFromEvent together with no success. Maybe this is not possible and has to be done outside the scope of rc-form.
数据结构类似于:
{
title: 'test',
items: [{
id: 1
title: 'xxx'
}, {
id: 2
title: 'xxxx'
}]
}
根据 input-array 这个例子,
先使用
getFieldValue('items').map
但是 map 里的 input 怎么关联到 id 和 title 这样的字段呢
{...getFieldProps('item.title')}
并没有生效
this code work well:
var field = this.getField(name);
var fieldValue = fieldMeta.initialValue;
if (field && 'value' in field) {
fieldValue = field.value;
}
but the new version in my code is work strange:
const field = exclusive ? this.getField(leadingName) : this.getField(name);
let fieldValue = atom;
if (field && 'value' in field) {
fieldValue = field.value;
}
if (fieldValue === atom) {
fieldValue = exclusive ? fieldsMeta[leadingName].initialValue : fieldMeta.initialValue;
}
I want to konw 'atom' what use?
每次输入都会触发整个表单render,当表单项多时,整个表单很卡,有办法可以避免嘛?
Line 62 in 616ddd3
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.