Giter Site home page Giter Site logo

field-form's Issues

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.

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

嵌套表单校验

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

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时再请求一次, 有什么好的办法吗?

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.

在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 属性的 自定义组件.. 打包后能获取到表单的数据。
在支持其他组件的扩展性上可以 再考虑下?

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

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;
}
});

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

<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.setFieldsValue对InputItem不起作用

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

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

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.

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

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.

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.

[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.

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;
}

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?

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?

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.

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;
}

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.

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.

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?

支持自定义的模板字符串

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

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

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

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.

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>

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.