3.3.3 • Published 5 months ago

@rn-form/form v3.3.3

Weekly downloads
-
License
UNLICENSED
Repository
github
Last release
5 months ago

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 form

Form.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 removed

FormInstance

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 initialValues
  • setFieldError (name: string, error?: string | false) => void

  • setFieldValue (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 values

Input <TextInputProps>

https://reactnative.dev/docs/textinput

  • error <Boolean>
Preview border error input
  • style <ViewStyle>
Stylesheet wrap view Input
  • styleInput <TextStyle>
Stylesheet Input

Radio


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();
      }}
    />
  )
}
3.1.9

7 months ago

3.1.8

7 months ago

3.2.2

6 months ago

3.2.1

6 months ago

3.2.0

6 months ago

3.2.6

6 months ago

3.0.8

12 months ago

3.2.5

6 months ago

3.0.7

12 months ago

3.2.4

6 months ago

3.2.3

6 months ago

3.2.9

6 months ago

3.2.8

6 months ago

3.2.7

6 months ago

3.0.9

12 months ago

3.3.1

5 months ago

3.1.3

12 months ago

3.3.0

6 months ago

3.1.2

12 months ago

3.1.1

12 months ago

3.1.0

12 months ago

3.1.7

7 months ago

3.1.6

7 months ago

3.3.3

5 months ago

3.1.5

9 months ago

3.3.2

5 months ago

3.1.4

12 months ago

3.0.4

1 year ago

3.0.3

1 year ago

3.0.6

1 year ago

3.0.5

1 year ago

3.0.2

1 year ago

3.0.1

2 years ago

2.3.2

2 years ago

2.3.3

2 years ago

3.0.0

2 years ago

2.3.0

2 years ago

2.3.1

2 years ago

2.2.9

2 years ago

2.2.1

2 years ago

2.2.0

2 years ago

2.2.3

2 years ago

2.2.2

2 years ago

2.2.5

2 years ago

2.2.4

2 years ago

2.2.7

2 years ago

2.2.6

2 years ago

2.2.8

2 years ago

2.1.2

3 years ago

2.0.3

3 years ago

2.1.1

3 years ago

2.0.2

3 years ago

2.1.4

3 years ago

2.0.5

3 years ago

2.1.3

3 years ago

2.1.6

3 years ago

2.0.7

3 years ago

2.1.5

3 years ago

2.0.6

3 years ago

2.1.8

3 years ago

2.0.9

3 years ago

2.1.7

3 years ago

2.0.8

3 years ago

2.1.0

3 years ago

2.1.9

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.1.9

3 years ago

1.1.8

3 years ago

1.1.7

3 years ago

1.1.6

3 years ago

1.1.5

3 years ago

1.1.4

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.1.1

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago