Giter Site home page Giter Site logo

field-form's People

Contributors

afc163 avatar ashonea avatar binyellow avatar capdiem avatar chenshuai2144 avatar crazyair avatar csjkevin avatar dependabot-preview[bot] avatar dependabot[bot] avatar fireairforce avatar geekrainy avatar hengkx avatar hvsy avatar itibbers avatar jueinin avatar kiner-tang avatar li-jia-nan avatar madccc avatar madocto avatar mgcrea avatar minjieliu avatar mushan0x0 avatar pmwmedia avatar rexskz avatar shunyue1320 avatar wanpan11 avatar wxh16144 avatar xrkffgg avatar zombiej avatar ztplz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

field-form's Issues

ValidateErrorEntity Type error

export interface ValidateErrorEntity {
    values: Store;
    errorFields: {
        name: InternalNamePath;
        errors: string[];
    };
    outOfDate: boolean;
}
export interface ValidateErrorEntity {
    values: Store;
    errorFields: Array<{
        name: InternalNamePath;
        errors: string[];
    }>;
    outOfDate: boolean;
}

在material UI中 使用该表单组件,但Button没有submit类型,编译失败。

import React from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';
import TextField from '@material-ui/core/TextField';
import Grid from '@material-ui/core/Grid';
import { makeStyles } from '@material-ui/core/styles';
// import Button from '@material-ui/core/Button';
import Form, { Field } from 'rc-field-form';

const useStyles = makeStyles(theme => ({
gridContainer:{
margin: theme.spacing(2),
display:'flex',
flexWrap:'wrap',
flexDirection:'column',
alignItems:'center'
},
grid:{
margin: theme.spacing(2),
}
}));
export default function Login() {
const classes = useStyles();
return (
<React.Fragment>


<Form
// onFinish={v => {
// console.log(v);
// }}
initialValues={{
user:'hello',
pwd:'hello',
}}
>


<TextField
autoComplete
autoFocus
placeholder="初始帐号:hello"
required
label="帐号"
helperText="初始帐号:hello,该帐号仅提供浏览权限"
// multiline
margin="normal"
variant="outlined"
>





<TextField
autoComplete
autoFocus
placeholder="初始帐号:hello"
required
label="帐号"
helperText="初始帐号:hello,该帐号仅提供浏览权限"
// multiline
margin="normal"
variant="outlined"
>




submit




</React.Fragment>
)
}
目前 button 只能使用 带submit 属性的 自定义组件.. 打包后能获取到表单的数据。
在支持其他组件的扩展性上可以 再考虑下?

resetFields会导致自定义组件销毁并重新加载

我在antd(4.0) form中使用一个自定义组件, 该自定义组件每次加载会异步加载一些数据

const MeetingTab = ({ onChange, value = 0 }) => {
    const [selectTab, setSelectTab] = useState<number>(value)
    const [meetingRooms, setMeetingRooms] = useState<number[]>([])
    const handleMettingTabChange = useCallback(
        value => {
            setSelectTab(value)
            if (onChange) {
                onChange(value)
            }
        },
        [onChange]
    )
    useEffect(() => {
        if (!meetingRooms.length) {
            //异步请求
            request().then(data => {
                setMeetingRooms(data)
            })
        }
    }, [meetingRooms])

    const renderTab = useMemo(() => {
        return meetingRooms.map((value, index) => {
            const isActive = selectTab === value ? "active" : ""
            return (
                <li onClick={() => handleMettingTabChange(value)} key={index} className={isActive}>
                    {value}
                </li>
            )
        })
    }, [handleMettingTabChange, meetingRooms])

    return <div>{renderTab}</div>
}

当使用form.resetFields时, 会导致该组件会重新加载一次, 导致多了一次请求!
当然通过props可以解决这一问题,但是我只想在组件里进行异步请求, 又不想在resetFields时再请求一次, 有什么好的办法吗?

setFieldValue?

I have a situation where I need to manually set the value of a form field, not as part of initialization, but as a result of a server API call. I was looking for something like setFieldValue but I only see setFieldsValue is available. Could you guide me on how to approach this situation? I would really like to avoid knowledge of the entire form state as I'm trying to implement reusable "sub-forms" which are not aware of which form they are part of, but they do need to be able to set/control the value for some of their fields.

Semver and getFieldsValue(bool)

regarding big change to form.getFieldsValue() and form.getFieldValues(true).

semver not respected. antd-rc5 takes a npm dependency using ^ on this in a tagged release and so now we have unpredictable builds and big behaviourable changes with regards to forms.

What is 0.0.0-rc6 meant to represent logically?

#versioning #semver #breaking

Use an object for the hook API?

Not that it is worth anything but I think the hook API would be better if we dropped the array. There is no rule that enforce a hook to return an array and in that case, an object would be better, as it would allow destructuring in a single line:

 const {form, getFieldError} = Form.useForm();

Ideally form would only be a single ref without the extra API to keep things dry.

Use an object for the hook API?

Not that it is worth anything but I think the hook API would be better if we dropped the array. There is no rule that enforce a hook to return an array and in that case, an object would be better, as it would allow destructuring in a single line:

 const {form, getFieldError} = Form.useForm();

Ideally form would only be a single ref without the extra API to keep things dry.

use `lodash/set` instead but not `lodash/fp/set`

setValue in valueUtil use lodash/fp/set to set value, this cause setValue will not work as expect in some case

export function setValue(store: Store, namePath: InternalNamePath, value: StoreValue): Store {
const newStore = setIn(namePath, value, store);
return newStore;
}

consider this situation, a variable named as a, and it's initial value is a boolean

const initialValues = {
  a: true
}

in the form field, a field name path is ['a', 'b'], and field update, but in lodash/fp/set, a will be transformed by Object(value)

nested[key] = clone(index == lastIndex ? value : Object(value));

a -> Boolean{true}

so setValue will not work, a will always be true

Warning: A component is changing an uncontrolled input of type undefined to be controlled.

Warning: A component 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
    in input (at src/index.tsx:8)
    in Input (at src/index.tsx:14)
    in Field (at src/index.tsx:13)
    in form (created by ForwardRef(Form))
    in ForwardRef(Form) (at src/index.tsx:12)
    in App (at src/index.tsx:21)

Step to reproduce

  1. Open CodeSandbox
  2. Expand Codesandbox's console
  3. Type on the input filed

rules多个规则不能校验失败就不继续校验了吗?

因为我一个组件有多个规则,前面几个规则只是判断字符的规则,后面validator有一个异步的校验,是用来验重的,我想有没有办法,让前几个规则校验失败就不进行验重的校验了,目前好像设计是所有都会校验,并且统一返回错误的

react-native support?

Is react-native supported or is it on the roadmap?


EDIT: Looks like it's working just fine. And it's also specified in the README.md!

Guess you might want to add some examples at some point!

    <Form
      component={FormView}
      onFinish={values => {
        console.log('onFinish:', values);
      }}
      onFinishFailed={({values, errorFields, outOfDate}) => {
        console.log('onFinishFailed:', {values, errorFields, outOfDate});
      }}
    >
      <Field
        name="username"
        getValueFromEvent={({nativeEvent}) => {
          return nativeEvent.text;
        }}
        rules={[{required: true}]}
      >
        <Input placeholder="Username" />
      </Field>
    </Form>

No major issues so far, had to tweak my FormView onSubmit call signature to add an event so that the preventDefault calls do not fail.

Returning error when actually it's right

Hi, I started using this library and I found something weird happening to me, when I type just one letter in my input, for some reason, it runs against my rules and does not pass in my required rule, and that's wrong since I have 1 letter in my input. Also, why is it checking my rules every time I type something in my input? I don't need that, I can just validate when I submit the form.

Note: I'm using React Native

My screen component which holds the form:

const Login: FunctionComponent<{
    navigation: StackNavigationProp<{}>
}> = ({ navigation }) => {
    const { login } = useContext(UserContext)

    const [form] = useForm()

    navigation.setOptions({
        title: 'Login'
    })

    const authenticate = () => {
        form.validateFields().then(({ email, password }) => {

        })
    }

    return (
        <Screen>
            <View style={[GlobalStyles.flex, GlobalStyles.alignCenter, GlobalStyles.justifyCenter]}>
                <Image style={styles.image} source={require('../../../assets/black_logo.png')} />
                <Form component={FormView} form={form}>
                    <Field name="email" rules={[{ required: true }]}>
                        <Input placeholder="Email" />
                    </Field>
                    <Field name="Password" rules={[{ required: true }]}>
                        <Input placeholder="Password" secureTextEntry={true} />
                    </Field>
                </Form>
                <Button type="primary" onPress={authenticate}>
                    ENTRAR
                </Button>
            </View>
        </Screen>
    )
}

My Field component:

const Field: FunctionComponent<{

} & FieldProps> = ({ children, ...props }) => {
    return (
        <FormField trigger="onChangeText" getValueFromEvent={text => text} {...props}>
            {
                (control, meta) => {
                    return <View>
                        {
                            React.cloneElement(children as any, { error: meta.errors.length > 0, ...control })
                        }
                        {
                            meta.errors.map((error, index) => (
                                <Error key={index}>
                                    {error}
                                </Error>
                            ))
                        }
                    </View>
                }
            }
        </FormField>
    )
}

And my Input component:

const Input: FunctionComponent<{
    error?: boolean
} & TextInputProps> = ({ error, ...props }) => {
    return (
        <TextInput style={[styles.container, error ? styles.error : {}]} {...props} />
    )
}

This only happens when you type the FIRST LETTER ONLY. When you type the second letter the error goes away, also if you have 2 letters and remove one letting the input value with 1 letter, the error doesn't show as well, so this only happens when the input is empty and you type one letter only.

<Form.List> needs a defaultValue when add items

for example, my data is

[{a:1,b:1},{a,2,b:1}]

when I add another item (using operation.add), the data turns to be

[{a:1,b:1},{a,2,b:1},undefined]

but in fact I need to pass a defaultValue instead of undefined

WHAT'S EXPECTED:

operation.add({a:1})

Form.List add normalize for user-defined field

for example, my data structure is:

{
   a: 1,
   b: 2,
   c: 3,
}

I want to use Form.List but I wouldn't transform structure in initialValues and submit action.

I'd like to suggest that adding normalize in Form.List transform data structure into
user-defined field.

[FR] createForm API

createForm receive an object like interface/type,makes stronger type checking and better field name IntelliSense

interface Param$Login {
  username: string;
  password: string;
}

const { Form, Field, useForm } = createForm<Param$Login>();

For examples,
Screen Shot 2019-12-18 at 10 46 23
Screen Shot 2019-12-18 at 10 46 49

I have created a wrapper for this library with createForm API. It would be great if this feature officially supported.

setErrors after form submission and server-side validation

Is there any way to manually set the validation errors after server-side validation?
I have the case where I submit the data and the API is performing additional business-rules validation and return a list of errors for incorrect fields. atm there is no way to set the errors for fields

Thanks.

Add form.getTouchedFieldsValue helper

A common use case when building large forms is to only patch updated values, eg. the user only changed one or a few fields and you want to easily produce a PATCH http request to apply the update on a backend. Without having to post the whole form payload every time.

Today grabbing these fields seems doable with isFieldTouched but would be a PITA as it would require looping over every field & I haven't found an easy way to grab all current fields namePaths (would need a getFieldNamePaths helper too).

Could gladly work on a PR if needed & it is something that you would consider.

getFieldError usage

I'm trying to setup validation error state/messages and I can't find how to do it:

  • Looks like the <Field /> component does not pass any validation related prop to its children, (only value/onChange).

  • Using form.getFieldError in the parent does not work as it's not properly called upon validation.

  • Haven't found a getFieldProps API to extract validation statuses from the form instance.

Here is a quick code-sandbox: https://codesandbox.io/s/rc-field-form-5jcfm-5jcfm

I know this is alpha software, but it would be great to add some recipe.md file with common use case! Thanks for the great work.

form.setFieldsValue对InputItem不起作用

<Form component={false} form={form}>
	<List>
		<Field name="day">
			<InputItem />
		</Field>
	</List>
</Form>

调用form.setFieldsValue({day: '12'}),并不能成功地给InputItem赋值。
但是如果给Form组件的initialValues={{day: '12'}},又是可以的。

name keeps supporting 'a.b.c' format

now I want to set value of name['children', 1, 'level'] to 'high', so i do like this,

const values = {};
lodash.set(values, ['children', 1, 'level'], 'high')
form.setFieldsValue(values);

but now values is {children: [undefined, {level: 'high'}]}, the children[0] is undefined, so I have no intention, but i changed children[0].

so i think you should think that name continues to support 'a.b.c' format, thank you.

支持自定义的模板字符串

<Field name="username" label="用户" messageVariables={{ label: '用户名' }} />
  • 可以通过 From来继承 messageVariables
  • 支持 xxx.xxx

No way to provide extra keys for validator template messages

I can currently specify my own ValidatorMessages, but no way to provide extra keys for the message template string.

There is a option(additionalKv) but it is not being used.

const replaceFunc = (template: string, additionalKV?: Record<string, string>) => () =>
replaceMessage(template, { ...kv, ...additionalKV });
/* eslint-disable no-param-reassign */
function fillTemplate(source: ValidateMessages, target: ValidateMessages = {}) {
Object.keys(source).forEach(ruleName => {
const value = source[ruleName];
if (typeof value === 'string') {
target[ruleName] = replaceFunc(value);
} else if (value && typeof value === 'object') {
target[ruleName] = {};
fillTemplate(value, target[ruleName]);
} else {
target[ruleName] = value;
}
});

嵌套表单校验

常用场景需要使用自定义组件, 组件为Form表单, 放在Field组件内使用, 外层表单校验时怎么触发子Form校验

antd-form v3与v4表现不一致

问题1:antd v3使用rc-form时,当因为逻辑分支导致被getFieldDecorator包裹的部分字段未被渲染时,原本保存在这些字段上的值会被清空,再次渲染时会使用initialValue上的值进行初始化;但v4使用rc-field-form时,未被渲染字段的值会持久保存,再次渲染时直接使用之前保存的值。这一行为不一致是刻意的还是bug?
v3版demo:https://codesandbox.io/s/kind-pare-2l760
v4版demo:https://codesandbox.io/s/dark-bush-gzv86
可以看到baz字段在两者间表现的不一致。
问题2:onFieldsChange回调api会在一次交互时触发2次,且第二次的changedFields参数为空数组,感觉是个bug?

The form is not reload after init values using state

		<Form
                    ref={form => { this.form = form }}
                    style={{ overflow: 'auto' }}
                    name='global-feedback'
                    onFinish={this.onFinish}
                    onFinishFailed={this.onFinishFailed}
                    onFieldsChange={this.onFieldsChange}
                    initialValues={{
                      name: userInfo.name || userInfo.username,
                      email: userInfo.email
                    }}
                  >

After API push data to userInfo, the form is still not reload ultil:

componentDidUpdate (prevProps, prevState, snapshot) {
    if (this.form && prevState.userInfo.username !== this.state.userInfo.username) {
      this.form.resetFields()
    }
  }

Any suggestion?

Typescript error in Field.d.ts

onStoreChange: (prevStore: Store, namePathList: InternalNamePath[], info: NotifyInfo) => void;

is not assignable to

onStoreChange: (store: Store, namePathList: InternalNamePath[] | null, info: NotifyInfo) => void;

in Field.d.ts

image

type StoreValue should include Store[] and StoreBaseValue[]

image

when I use ant Upload Component prop fileList: Array<UploadFile> as the initialValues of the form, the initial UploadFile[] cannot be assign to StoreValue, because the only supported array is StoreBaseValue[], not Store[]

So we need to change the typescript interface to:

export declare type StoreValue = StoreBaseValue | Store | StoreBaseValue[] | Store[];
export interface Store {
    [name: string]: StoreValue;
}

List render props add whole list value support

field-form/src/List.tsx

Lines 107 to 124 in bc56d70

return children(
(value as StoreValue[]).map(
(__, index): ListField => {
let key = keyManager.keys[index];
if (key === undefined) {
keyManager.keys[index] = keyManager.id;
key = keyManager.keys[index];
keyManager.id += 1;
}
return {
name: index,
key,
};
},
),
operations,
);

children of List could get all values from render props

<List>
  {(fields, values, operations) => (...)}
</List>

No way to type the form store?

Did not found a documented way to type the store values. Was expecting this API (what's used by react-hook-form):

type FormValues = {
  email: string;
  password: string;
};

const LoginForm: FunctionComponent<Props> = ({history}) => {
  const [form] = Form.useForm<FormValues>();

However useForm does not seem to accept a generic type.

Is there another way to type a form store or do you have another API in mind?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.