@rn-form/form v3.3.3
Click here to Example
API
Form or Form.ScrollView Support scroll to the first error field
type Form = {
form: FormInstance<T>;
colon?: boolean;
initialValues?: {[key: string]: any}; //default values
labelAlign?: 'left' | 'right'; //The text align of label of all items
name?: string; //Form name. Will be the prefix of Field id
preserve?: boolean; //Keep field value even when field removed
requiredMark?: boolean | string; /
requiredMarkStyle?: StyleProp<TextStyle>;
requiredMarkPosition?: 'before' | 'after';
validateMessages?: ValidateMessages; //Validation prompt template
validateTrigger?: TriggerAction | 'onChange' | 'onBlur'; //Config field validate trigger
onValuesChange?: (values: {[key: string]: any}) => void; //Trigger when value updated
errorStyle?: StyleProp<TextStyle>;
labelStyle?: StyleProp<TextStyle>;
style?: StyleProp<ViewStyle>;
};type Form.ScrollView = Form & ScrollViewProps;- form
<FormInstance>Click to here
Form control instance created by Form.useForm() with Hooks
or Form.create(Component) with Class Component.
Automatically created when not provided- colon
<Boolean>
Configure the default value of colon for Form.Item.
Indicates whether the colon after the label is displayed
(only effective when prop layout is horizontal)- initialValues
{[key: string]: any}
Default Values by form- labelAlign
<'left' | 'right'>
The text align of label of all items- name
<String>
Form name. Will be the prefix of Field id- preserve
<Boolean>
Keep field value even when field removed- requiredMark
<Boolean | String>
Required mark style. Can use required mark or optional mark.
You can not config to single Form.Item since this is a Form level config- requiredMarkStyle
<TextStyle>
Custom mark styleSheet- requiredMarkPosition
<'before' | 'after'>
- Default: before
Config position required mark or optional mark- validateMessages
<ValidateMessages>
Validation prompt template
const validateMessages = {
required: '${name} is required',
whitespace: '${name} cannot be empty',
len: '${name} must be exactly ${len} characters',
min: '${name} must be less than ${min}',
max: '${name} cannot be greater than ${max}',
pattern: '${name} does not match pattern ${pattern}',
enum: '${name} must be one of ${enum}',
};- validateTrigger
<'onChange' | 'onBlur'>
- Default: onChange
Config field validate trigger- onValuesChange
(values: {[key: string]: any}) => void
Trigger when value updated- errorStyle
<TextStyle>
Configure the label message error form- style
<ViewStyle>
Configure the style formForm.Item
! Must be inside the Form
type FormItem = {
name: T;
label?: string; //Label text
initialValue?: any; //Label text
rules?: Rule[];
required?: boolean; //Display required style. It will be generated by the validation rule
validateTrigger?: TriggerAction.onBlur | TriggerAction.onChange <'onChange' | 'onBlur'>;//When to validate the value of children node
preserve?: boolean; //Keep field value even when field removed
style?: StyleProp<ViewStyle>;
getValueProps?: (v: any) => any;
children:
| ((handle: {
onChangeValue: (value: any) => any;
onBlur: () => any;
value?: any;
error?: string;
}) => ReactNode)
| React.ReactNode;
};- name
<String>* Required
Field name- label
<String>
Label text- initialValue
<any>
Config sub default value. Form initialValues get higher priority when conflict- required
<Boolean>
Display required style. It will be generated by the validation rule- validateTrigger
TriggerAction.onBlur | TriggerAction.onChange <'onChange' | 'onBlur'>
Default: onChange
When to validate the value of children node- rules
<Rule[]>
type Rule = {
required?: boolean; //Display required style. It will be generated by the validation rule
enum?: any[]; //Match enum value. You need to set type to enum to enable this
len?: number; //Length of string
max?: number; // max of number
min?: number; // min of number
message?: string; //Error message. Will auto generate by template if not provided
pattern?: RegExp; //Regex pattern
transform?: (value: any) => any; //Transform value to the rule before validation
validateTrigger?: TriggerAction.onBlur | TriggerAction.onChange <'onChange' | 'onBlur'>;
validator?: (
rule: Rule & {name: string},
value: any,
callback: (errorMessage?: string) => void,
) => Promise<void | Error>; //Customize validation rule. Accept Promise as return. See example
whitespace?: boolean; //Failed if only has whitespace
};//Rules for field validation.
import React, {Component} from 'react';
import Form, {Input} from '@form-rn/form';
class App extends Component {
render() {
return (
<Form.ScrollView>
<Form.Item
required={true}
validateTrigger="onBlur"
name="field_name"
label="Example Children type of JSX.Element"
initialValue="initialValue"
rules={[
{required: true, message: 'Field is required'},
{
validator: (rule, value) => {
if (value) {
return Promise.resolve();
}
return Promise.reject('Field is required');
},
validateTrigger: 'onBlur',
},
{
validator: (rule, value, callback) => {
if (value) {
callback();
} else {
callback('Field is required');
}
},
},
]}>
<Input placeholder="2" />
</Form.Item>
</Form.ScrollView>
);
}
}- children
<JSX.Element | ({onChangeValue, value, onBlur, error}) => any>
//children was supported type of functional
//onBlur must be required when rules.trigger or validateTrigger is onBlur
import React, {Component} from 'react';
import Form, {Input} from '@form-rn/form';
class App extends Component {
render() {
return (
<Form.ScrollView>
<Form.Item
name="children"
initialValue="12"
label="Example Children type of function">
{({onChangeValue, value, onBlur, error}) => {
console.log(value, onBlur, error);
return (
<Input
placeholder="2"
onChangeValue={onChangeValue}
value={value}
onBlur={onBlur}
error={error}
/>
);
}}
</Form.Item>
</Form.ScrollView>
);
}
}- colon
<Boolean>
Used with label, whether to display : after label text.- getValueProps
<(value: any) => any>
Additional props with sub component
Convert data onChange- labelAlign
<'left' | 'right'>
The text align of label- style
<ViewStyle | ViewStyle[]>
Stylesheet Field- preserve
<Boolean>
Keep field value even when field removedFormInstance
If you code like below then all the function of FormInstance will return about under an object like {idForm1: values, idForm2: values}
const form1 = useForm<T>()
const form2 = useForm<T>()
<Form form={form}>
<Form.Item name="field_name" label="Example">
<Input placeholder="2" />
</Form.Item>
</Form>
<Form form={form2}>
<Form.Item name="field_name2" label="Example2">
<Input placeholder="2" />
</Form.Item>
</Form>- getFieldError
(name: string) => string | undefined
Get the error messages by the field name- getFieldsError
(names?: string[]) => Promise<{[key: string]: string | undefined}>
Get the error messages by the fields name. Return as an array- getFieldsValue
(names?: string[], filter?: (meta: { touched: boolean, validating: boolean }) => boolean) => Promise<any>
Get values by a set of field names.
Return according to the corresponding structure.
Default return mounted field value, but you can use getFieldsValue() to get all values- getFieldValue
(name: string) => Promise<any>
Get the value by the field name- isFieldsTouched
(names?: string[], allTouched?: boolean) => boolean
Check if fields have been operated.
Check if all fields is touched when allTouched is true- isFieldTouched
(name: string) => boolean
Check if a field has been operated- resetFields
(fields?: string[]) => Promise<void>
Reset fields to initialValuessetFieldError
(name: string, error?: string | false) => voidsetFieldValue
(name: string, value: any) => void
Set fields value(Will directly pass to form store.
If you do not want to modify passed object, please clone first)- setFieldsValue
(values: {[key: string]: any}) => Promise<any>
Set fields value(Will directly pass to form store.
If you do not want to modify passed object, please clone first).- validateFields
(names?: string[]) => Promise<ValueValidateField>
type ValueValidateField = {
values: T;
errors?: {[key: string]: string};
};Validate fields and return errors and valuesInput <TextInputProps>
https://reactnative.dev/docs/textinput
- error
<Boolean>
Preview border error input- style
<ViewStyle>
Stylesheet wrap view Input- styleInput
<TextStyle>
Stylesheet InputRadio
RadioGroup
Example
//Function Componet
import React from 'react';
import Form, {Input} from '@form-rn/form';
import {Button} from 'react-native';
import Text from 'components/Text' // your custom component Text
const App = () => {
const form = useForm<Data>();
return (
<FormProvider Text={Text}>
<Form.ScrollView form={form} initialValues={{example: 'example'}}>
<Form.Item<Data> name="example" initialValue="12" label="Example">
<Input placeholder="2" />
</Form.Item>
<Form.Item<Data> name="radioGroup" label="Login2" required validateFirst>
<RadioGroup>
<Radio value={1} label="radio 1" />
<Radio value={2} label="radio 2" />
<Radio value={3} label="radio 3" />
</RadioGroup>
</Form.Item>
<Form.Item<Data> name="radio" label="Login2" required validateFirst>
<Radio label="radio 1" />
</Form.Item>
<Button
title="Get Value"
onPress={async () => {
const error = await form.getFieldError();
const errors = await form.getFieldsError();
const errorsWithNames = await form.getFieldsError(['example']);
const values = await form.getFieldsValue();
const valuesWithNames = await form.getFieldsValue(['example']);
const valuesWithFilter = await form.getFieldsValue(
undefined,
(touched, validating) => touched && validating,
);
const value = await form.getFieldValue('example');
const isToucheds = await form.isFieldsTouched(undefined, true);
const isTouched = await form.isFieldTouched('example');
const isValidating = await form.isFieldValidating('example');
const data = await form.validateFields();
if (Array.isArray(data)) {
console.log('data is array', data);
} else console.log(data);
}}
/>
<Button
title="Control Value"
onPress={async () => {
form.resetFields();
form.resetFields(['example']);
form.setFields([
{
name: 'example',
value: 'example1',
touched: true,
validating: true,
},
]);
form.setFieldValue('example', 'example1');
form.setFieldsValue({example: 'example1'});
}}
/>
</Form.ScrollView>
</FormProvider>
);
};
export default App;
//Class Component
import React from 'react';
import Form, {Input} from '@form-rn/form';
import {Button} from 'react-native';
class App extends Component<{form: FormInstance<Data>}> {
render() {
const {form} = this.props;
return (
<Form.ScrollView initialValues={{example: 'example'}}>
<Form.Item name="example" initialValue="12" label="Example">
<Input placeholder="2" />
</Form.Item>
<Button
title="Get Value"
onPress={async () => {
const error = await form.getFieldError();
const errors = await form.getFieldsError();
const errorsWithNames = await form.getFieldsError(['example']);
const values = await form.getFieldsValue();
const valuesWithNames = await form.getFieldsValue(['example']);
const valuesWithFilter = await form.getFieldsValue(
undefined,
(touched, validating) => touched && validating,
);
const value = await form.getFieldValue('example');
const isToucheds = await form.isFieldsTouched(undefined, true);
const isTouched = await form.isFieldTouched('example');
const isValidating = await form.isFieldValidating('example');
const data = await form.validateFields();
if (Array.isArray(data)) {
console.log('data is array', data);
} else console.log(data);
}}
/>
<Button
title="Control Value"
onPress={async () => {
form.resetFields();
form.resetFields(['example']);
form.setFields([
{
name: 'example',
value: 'example1',
touched: true,
validating: true,
},
]);
form.setFieldValue('example', 'example1');
form.setFieldsValue({example: 'example1'});
}}
/>
</Form.ScrollView>
);
}
}
export default Form.create(App);
// multiple Form
import React from 'react';
import Form, {Input} from '@form-rn/form';
import {Button} from 'react-native';
const App = () => {
const form1 = Form.useForm()
const form2 = Form.useForm()
return (
<Form form={form1}>
<Form.Item name="example" initialValue="12" label="Example">
<Input placeholder="2" />
</Form.Item>
</Form>
<Form form={form2}>
<Form.Item name="example" initialValue="12" label="Example">
<Input placeholder="2" />
</Form.Item>
</Form>
<Button
title="Control Value"
onPress={async () => {
form1.resetFields();
form2.resetFields();
}}
/>
)
}7 months ago
7 months ago
6 months ago
6 months ago
6 months ago
6 months ago
12 months ago
6 months ago
12 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
12 months ago
5 months ago
12 months ago
6 months ago
12 months ago
12 months ago
12 months ago
7 months ago
7 months ago
5 months ago
9 months ago
5 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago