/form

React High Order Form Component(web & react-native)

Primary LanguageJavaScriptMIT LicenseMIT

rc-form

React High Order Form Component.

NPM version build status Test coverage gemnasium deps node version npm download

Development

npm install
npm start
open http://localhost:8000/examples/

Feature

  • Support react.js and even react-native
  • Validate fields with async-validator

Install

rc-form

Usage

import { createForm } from 'rc-form';

class Form extends React.Component {
  submit = () => {
    this.props.form.validateFields((error, value) => {
      console.log(error, value);
    });
  }

  render() {
    let errors;
    const { getFieldProps, getFieldError } = this.props.form;
    return (
      <div>
        <input {...getFieldProps('normal')}/>
        <input {...getFieldProps('required', {
          onChange(){}, // have to write original onChange here if you need
          rules: [{required: true}],
        })}/>
        {(errors = getFieldError('required')) ? errors.join(',') : null}
        <button onClick={this.submit}>submit</button>
      </div>
    );
  }
}

export createForm()(Form);

Or a quicker version:

import { createForm } from 'rc-form';

class Form extends React.Component {
  componentWillMount() {
    this.requiredDecorator = this.props.form.getFieldDecorator('required', {
      rules: [{required: true}],
    });
  }

  submit = () => {
    this.props.form.validateFields((error, value) => {
      console.log(error, value);
    });
  }

  render() {
    let errors;
    const { getFieldError } = this.props.form;
    return (
      <div>
        {this.requiredDecorator(
          <input onChange={
            // can still write your own onChange
          />
        )}
        {(errors = getFieldError('required')) ? errors.join(',') : null}
        <button onClick={this.submit}>submit</button>
      </div>
    );
  }
}

export createForm()(Form);

createForm(formOption): Function

Option Description Type Default
formOption.validateMessages Preseted messages of async-validator Object {}
formOption.mapProps Get new props transfered to WrappedComponent. (props): Object props => props
formOption.onFieldsChange Called when field changed, you can dispatch fields to redux store. (props, changedFields): void NOOP
formOption.onValuesChange Called when value changed. (props, changedValues): void NOOP
formOption.mapPropsToFields Convert value from props to fields. Used for read fields from redux store. (props): Object NOOP
formOption.withRef(deprecated) Maintain an ref for wrapped component instance, use refs.wrappedComponent to access. boolean false

Note: use wrappedComponentRef instead of withRef after rc-form@1.4.0

class Form extends React.Component { ... }

// deprecated
const EnhancedForm = createForm({ withRef: true })(Form);
<EnhancedForm ref="form" />
this.refs.form.refs.wrappedComponent // => The instance of Form

// Recommended
const EnhancedForm = createForm()(Form);
<EnhancedForm wrappedComponentRef={(inst) => this.formRef = inst} />
this.formRef // => The instance of Form

createForm() will return another function

function(WrappedComponent: React.Component): React.Component

Will pass an object as prop form with the following members to WrappedComponent:

getFieldProps(name, option): Object

Will create props which can be set on a input/InputComponent which support value and onChange interface.

After set, this will create a binding with this input.

<form>
  <input {...getFieldProps('name', { ...options })} />
</form>

name: String

This input's unique name.

option: Object

Option Description Type Default
option.exclusive(deprecated) Whether set value exclusively. Used with radio. boolean false
option.valuePropName Prop name of component's value field, eg: checkbox should be set to checked ... String 'value'
option.getValueProps Get the component props according to field value. (value): Object (value) => ({ value })
option.initialValue Initial value of current component. any -
option.normalize Return normalized value. (value, prevValue, allValues): Object -
option.trigger Event which is listened to collect form data. String 'onChange'
option.validateTrigger Event which is listened to validate. Set to falsy to only validate when call props.validateFields. String String[]
option.rules Validator rules. see: async-validator Object[] -
option.validateFirst Whether stop validate on first rule of error for this field. boolean false
option.fieldNameProp Where to store the name argument of getFieldProps. String -
option.fieldMetaProp Where to store the meta data of getFieldProps. String -
option.validate Object[] -
option.validate[n].trigger Event which is listened to validate. Set to falsy to only validate when call props.validateFields. String String[]
option.validate[n].rules Validator rules. see: async-validator Object[] -
option.getValueFromEvent Specify how to get value from event. (e): any See below
function (e) {
  if (!e || !e.target) {
    return e;
  }
  const { target } = e;
  return target.type === 'checkbox' ? target.checked : target.value;
}
Tips
{
  validateTrigger: 'onBlur',
  rules: [{required: true}],
}
// is the shorthand of
{
  validate: [{
    trigger: 'onBlur',
    rules: [required: true],
  }],
}

getFieldDecorator(name:String, option: Object): (React.Node): React.Node

Similar to getFieldProps, but add some helper warnings and you can write onXX directly inside React.Node props:

<form>
  {getFieldDecorator('name', otherOptions)(<input />)}
</form>

getFieldsValue([fieldNames: String[]])

Get fields value by fieldNames.

getFieldValue(fieldName: String)

Get field value by fieldName.

getFieldInstance(fieldName: String)

Get field react public instance by fieldName.

setFieldsValue(obj: Object)

Set fields value by kv object.

setFieldsInitialValue(obj: Object)

Set fields initialValue by kv object. use for reset and initial display/value.

setFields(obj: Object)

Set fields by kv object. each field can contain errors and value member.

validateFields([fieldNames: String[]], [options: Object], callback: Function(errors, values))

Validate and get fields value by fieldNames.

options is the same as validate method of async-validator. And add force and scroll. scroll is the same as dom-scroll-into-view's function parameter config.

options.force: Boolean

Defaults to false. Whether to validate fields which have been validated(caused by validateTrigger).

getFieldsError(names): Object{ [name]: String[] }

Get inputs' validate errors.

getFieldError(name): String[]

Get input's validate errors.

isFieldValidating(name: String): Bool

Whether this input is validating.

isFieldsValidating(names: String[]): Bool

Whether one of the inputs is validating.

isFieldTouched(name: String): Bool

Whether this input's value had been change.

isFieldsTouched(names: String[]): Bool

Whether one of the inputs' values had been change.

isSubmitting(): Bool

Whether the form is submitting.

submit(callback: Function)

Cause isSubmitting to return true, after callback called, isSubmitting return false.

resetFields([names: String[]])

Reset specified inputs. Defaults to all.

rc-form/lib/createDOMForm(formOption): Function

createDOMForm enhancement, support props.form.validateFieldsAndScroll

props.form.validateFieldsAndScroll([fieldNames: String[]], [options: Object], callback: Function(errors, values))

props.form.validateFields enhancement, support scroll to the first invalid form field

options.container: HTMLElement

Defaults to first scrollable container of form field(until document).

Notes

  • Do not use stateless function component inside Form component: facebook/react#6534

  • you can not set same prop name as the value of validateTrigger/trigger for getFieldProps

<input {...getFieldProps('change',{
  onChange: this.iWantToKnow // you must set onChange here or use getFieldDecorator to write inside <input>
})}>
  • you can not use ref prop for getFieldProps
<input {...getFieldProps('ref')} />

this.props.form.getFieldInstance('ref') // use this to get ref

or

<input {...getFieldProps('ref',{
  ref: this.saveRef // use function here or use getFieldDecorator to write inside <input> (only allow function)
})} />

Test Case

npm test
npm run chrome-test

Coverage

npm run coverage

open coverage/ dir

License

rc-form is released under the MIT license.