Skip to content

Latest commit

 

History

History
959 lines (749 loc) · 23.1 KB

API.md

File metadata and controls

959 lines (749 loc) · 23.1 KB

API

import Formsy from 'formsy-react';

class MyForm extends React.Component {
  render() {
    return (
      <Formsy disabled>
        <MyInput name="foo" value="" />
        <MyInput name="bar" value="" />
      </Formsy>
    );
  }
}

Disable the form itself with a prop and use isFormDisabled.

class MyForm extends React.Component {
  mapInputs(inputs) {
    return {
      field1: inputs.foo,
      field2: inputs.bar,
    };
  }
  submit(model) {
    model; // {field1: '', field2: ''}
  }
  render() {
    return (
      <Formsy onSubmit={this.submit} mapping={this.mapInputs}>
        <MyInput name="foo" value="" />
        <MyInput name="bar" value="" />
      </Formsy>
    );
  }
}

Use mapping to change the data structure of your input elements. This structure is passed to the submit hooks.

You can manually pass down errors to your form. In combination with onChange you are able to validate using an external validator.

class Form extends React.Component {
  state = { validationErrors: {} };
  validateForm = (values) => {
    if (!values.foo) {
      this.setState({
        validationErrors: {
          foo: 'Has no value',
        },
      });
    } else {
      this.setState({
        validationErrors: {},
      });
    }
  };
  render() {
    return (
      <Formsy onChange={this.validateForm} validationErrors={this.state.validationErrors}>
        <MyFormElement name="foo" />
      </Formsy>
    );
  }
}
<Formsy onReset={this.handleOnReset}></Formsy>

Takes a function to run when the reset button has been clicked.

<Formsy onSubmit={this.showFormLoader}></Formsy>

Takes a function to run when the submit button has been clicked.

The first argument is the data of the form. The second argument will reset the form. The third argument will invalidate the form by taking an object that maps to inputs. This is useful for server side validation. E.g. {email: "This email is taken"}. Resetting or invalidating the form will cause setState to run on the form element component.

<Formsy onValid={this.enableSubmitButton}></Formsy>

Whenever the form becomes valid the "onValid" handler is called. Use it to change state of buttons or whatever your heart desires.

<Formsy onInvalid={this.disableSubmitButton}></Formsy>

Whenever the form becomes invalid the "onInvalid" handler is called. Use it to for example revert "onValid" state.

<Formsy onValidSubmit={this.sendToServer}></Formsy>

Triggers when form is submitted with a valid state. The arguments are the same as on onSubmit.

<Formsy onInvalidSubmit={this.notifyFormError}></Formsy>

Triggers when form is submitted with an invalid state. The arguments are the same as on onSubmit.

<Formsy onChange={this.saveCurrentValuesToLocalStorage}></Formsy>

"onChange" triggers when setValue is called on your form elements. It is also triggered when dynamic form elements have been added to the form. The "currentValues" is an object where the key is the name of the input and the value is the current value. The second argument states if the forms initial values actually has changed.

class MyForm extends React.Component {
  resetForm = () => {
    this.refs.form.reset();
  };
  render() {
    return <Formsy ref="form">...</Formsy>;
  }
}

Manually reset the form to its pristine state. You can also pass an object that inserts new values into the inputs. Keys are name of input and value is of course the value.

class MyForm extends React.Component {
  getMyData = () => {
    alert(this.refs.form.getModel());
  };
  render() {
    return <Formsy ref="form">...</Formsy>;
  }
}

Manually get values from all registered components. Keys are name of input and value is of course the value.

class MyForm extends React.Component {
  someFunction = () => {
    this.refs.form.updateInputsWithError(
      {
        email: 'This email is taken',
        'field[10]': 'Some error!',
      },
      true,
    );
  };
  render() {
    return <Formsy ref="form">...</Formsy>;
  }
}

Manually set the form fields validation errors by taking an object that maps field name to error message as the first argument and optionally invalidate the form by passing true as the second argument. This is useful for server side validation. This is also passed as the third parameter to the onSubmit, onValidSubmit or onInvalidSubmit.

class MyForm extends React.Component {
  someFunction = () => {
    this.refs.form.updateInputsWithValue({
      email: 'value@example.com',
      'field[10]': 'value!',
    });
  };
  render() {
    return <Formsy ref="form">...</Formsy>;
  }
}

Manually set the form fields values by taking an object that maps field name to value as the first argument and optionally validate the inputs by passing true as the second argument.

class MyForm extends React.Component {
  render() {
    return <Formsy preventDefaultSubmit>...</Formsy>;
  }
}

With the preventDefaultSubmit prop the form will issue full HTTP POST by browser means (and render resulting HTML).

class MyForm extends React.Component {
  onSubmit(model, reset, invalidate) {
    invalidate({
      foo: 'Got some error',
    });
  }
  render() {
    return (
      <Formsy onSubmit={this.onSubmit} preventExternalInvalidation>
        ...
      </Formsy>
    );
  }
}

With the preventExternalInvalidation the input will not be invalidated though it has an error when updateInputsWithError() or an invalidate callback is called.

By default Formsy render the form with the HTML form element. If you want to override this behaviour, you can pass the element to render in the formElement props

  <Formsy formElement="div">
    ...
  </Formsy>

  <Formsy formElement={MyCustomFormElement}>
    ...
  </Formsy>

All Formsy input components must be wrapped in the withFormsy higher-order component, which provides the following properties and methods through props.

import { withFormsy } from 'formsy-react';

class MyInput extends React.Component {
  render() {
    return (
      <div>
        <input value={this.props.value} onChange={(e) => this.props.setValue(e.target.value)} />
      </div>
    );
  }
}
export default withFormsy(MyInput);
<MyInput name="email"/>
<MyInput name="address.street"/>

The name is required to register the form input component in the form. You can also use dot notation. This will result in the "form model" being a nested object. {email: 'value', address: {street: 'value'}}.

Use an innerRef prop to get a reference to your DOM node.

class MyForm extends React.Component {
  componentDidMount() {
    this.searchInput.focus();
  }
  render() {
    return (
      <Formsy>
        <MyInput
          name="search"
          innerRef={(c) => {
            this.searchInput = c;
          }}
        />
      </Formsy>
    );
  }
}
<MyInput name="email" value="My initial value" />

To pass an initial value, use the value attribute. This value will become the "pristine" value and any reset of the form will bring back this value.

<MyInput name="email" validations="isEmail"/>
<MyInput name="number" validations="isNumeric,isLength:5"/>
<MyInput name="number" validations={{
  isNumeric: true,
  isLength: 5
}}/>
<MyInput name="number" validations={{
  myCustomIsFiveValidation: function (values, value) {
    values; // Other current values in form {foo: 'bar', 'number': 5}
    value; // 5
    return 5 === value ? true : 'No five'; // You can return an error
  }
}}/>

A comma separated list with validation rules. Take a look at Validators to see default rules. Use ":" to separate argument passed to the validator. The argument will go through a JSON.parse converting them into correct JavaScript types. Meaning:

<MyInput name='fruit' validations='isIn:["apple", "orange"]'/>
<MyInput name='car' validations='mapsTo:{"bmw": true, "vw": true}'/>

Works just fine.

NOTE: use double quotes to quote the strings in the array/objects argument. JSON.parse() will not parse single quotes.

<MyInput name="email" validations="isEmail" validationError="This is not an email" />

The message that will show when the form input component is invalid. It will be used as a default error.

<MyInput
  name="email"
  validations={{
    isEmail: true,
    maxLength: 50,
  }}
  validationErrors={{
    isEmail: 'You have to type valid email',
    maxLength: 'You can not type in more than 50 characters',
  }}
/>

The message that will show when the form input component is invalid. You can combine this with validationError. Keys not found in validationErrors defaults to the general error message.

<MyInput name="email" validations="isEmail" validationError="This is not an email" required />

A property that tells the form that the form input component value is required. By default it uses isDefaultRequiredValue, but you can define your own definition of what defined a required state.

<MyInput name="email" required="isFalse" />

Would be typical for a checkbox type of form element that must be checked, e.g. agreeing to Terms of Service.

class MyInput extends React.Component {
  render() {
    return <input type="text" onChange={this.changeValue} value={this.props.value} />;
  }
}

Gets the current value of the form input component.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    return <input type="text" onChange={this.changeValue} value={this.props.value} />;
  }
}

Sets the value of your form input component. Notice that it does not have to be a text input. Anything can set a value on the component. Think calendars, checkboxes, autocomplete stuff etc. Running this method will trigger a setState() on the component and do a render.

You can also set the value without forcing an immediate validation by passing a second parameter of false. This is useful in cases where you want to only validate on blur / change / etc.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    return (
      <div>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <button onClick={this.props.resetValue}>Reset</button>
      </div>
    );
  }
}

Resets to empty value. This will run a setState() on the component and do a render.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    return (
      <div>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <span>{this.props.errorMessage}</span>
      </div>
    );
  }
}

Will contain the validation message set if the form input component is invalid. If form input component is valid it will be null.

Will contain the validation messages set if the form input component is invalid. If form input component is valid it will be an empty array.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    var face = this.props.isValid ? ':-)' : ':-(';
    return (
      <div>
        <span>{face}</span>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <span>{this.props.errorMessage}</span>
      </div>
    );
  }
}

The valid state of the form input component.

You can pre-verify a value against the passed validators to the form element.

class MyInput extends React.Component {
  changeValue = (event) => {
    if (this.props.isValidValue(event.target.value)) {
      this.props.setValue(event.target.value);
    }
  }
  render() {
    return <input type="text" onChange={this.changeValue} value={this.props.value}/>;
  }
});

class MyForm extends React.Component {
  render() {
    return (
      <Formsy>
        <MyInput name="foo" validations="isEmail"/>
      </Formsy>
    );
  }
}
class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    return (
      <div>
        <span>
          {this.props.label} {this.props.isRequired ? '*' : null}
        </span>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <span>{this.props.errorMessage}</span>
      </div>
    );
  }
}

True if the required property has been passed.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    var className = this.props.showRequired ? 'required' : '';
    return (
      <div className={className}>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <span>{this.props.errorMessage}</span>
      </div>
    );
  }
}

True if the form input component should indicate if it is a required field. This happens when the form input component value is empty and the required prop has been passed.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    var className = this.props.showRequired ? 'required' : this.props.showError ? 'error' : '';
    return (
      <div className={className}>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <span>{this.props.errorMessage}</span>
      </div>
    );
  }
}

Lets you check if the form input component should indicate if there is an error. This happens if there is a form input component value and it is invalid or if a server error is received.

class MyInput extends React.Component {
  changeValue = (event) => {
    this.props.setValue(event.currentTarget.value);
  };
  render() {
    return (
      <div>
        <input type="text" onChange={this.changeValue} value={this.props.value} />
        <span>{this.props.isPristine ? 'You have not touched this yet' : ''}</span>
      </div>
    );
  }
}

By default all Formsy input elements are pristine, which means they are not "touched". As soon as the setValue method is run it will no longer be pristine.

note! When the form is reset (using reset(...)) the inputs are reset to their pristine state.

class MyInput extends React.Component {
  render() {
    return (
      <div>
        <input type="text" value={this.props.value} disabled={this.props.isFormDisabled} />
      </div>
    );
  }
}

React.render(<Formsy disabled={true} />);

You can disable the form itself with a prop and use isFormDisabled inside form elements to verify this prop.

class MyInput extends React.Component {
  render() {
    var error = this.props.isFormSubmitted ? this.props.errorMessage : null;
    return (
      <div>
        <input type="text" value={this.props.value} />
        {error}
      </div>
    );
  }
}

True if the form has been submitted.

To avoid native validation behavior on inputs, use the React formNoValidate property.

class MyInput extends React.Component {
  render() {
    return (
      <div>
        <input formNoValidate type="number" />
      </div>
    );
  }
}

If you are using React's PropType type checking, you can spread Formsy’s propTypes into your local propTypes to avoid having to repeatedly add withFormsy’s methods to your components.

import PropTypes from 'prop-types';
import { propTypes } from 'formsy-react';

class MyInput extends React.Component {
  static propTypes = {
    firstProp: PropTypes.string,
    secondProp: PropTypes.object,
    ...propTypes,
  };
}

MyInput.propTypes = {
  firstProp: PropTypes.string,
  secondProp: PropTypes.object,
  ...propTypes,
};

import { addValidationRule } from 'formsy-react';

An example:

addValidationRule('isFruit', function (values, value) {
  return ['apple', 'orange', 'pear'].indexOf(value) >= 0;
});
<MyInput name="fruit" validations="isFruit" />

Another example:

addValidationRule('isIn', function (values, value, array) {
  return array.indexOf(value) >= 0;
});
<MyInput name="fruit" validations='isIn:["apple", "orange", "pear"]' />

NOTE: use double quotes to quote the strings in the array argument. JSON.parse() will not parse single quotes.

Cross input validation:

addValidationRule('isMoreThan', function (values, value, otherField) {
  // The this context points to an object containing the values
  // {childAge: "", parentAge: "5"}
  // otherField argument is from the validations rule ("childAge")
  return Number(value) > Number(values[otherField]);
});
<MyInput name="childAge"/>
<MyInput name="parentAge" validations="isMoreThan:childAge"/>

matchRegexp

<MyInput
  name="foo"
  validations={{
    matchRegexp: /foo/,
  }}
/>

Returns true if the value is thruthful

For more complicated regular expressions (emoji, international characters) you can use xregexp. See this comment for an example.

isEmail

<MyInput name="foo" validations="isEmail" />

Return true if it is an email

isUrl

<MyInput name="foo" validations="isUrl" />

Return true if it is an url

isExisty

<MyInput name="foo" validations="isExisty" />

Returns true if the value is not undefined or null

isUndefined

<MyInput name="foo" validations="isUndefined" />

Returns true if the value is undefined

isEmptyString

<MyInput name="foo" validations="isEmptyString" />

Returns true if the value is an empty string

isTrue

<MyInput name="foo" validations="isTrue" />

Returns true if the value is the boolean true

isFalse

<MyInput name="foo" validations="isFalse" />

Returns true if the value is the boolean false

isAlpha

<MyInput name="foo" validations="isAlpha" />

Returns true if string is only letters

isNumeric

<MyInput name="foo" validations="isNumeric" />

Returns true if string only contains numbers. Examples: 42; -3.14

isAlphanumeric

<MyInput name="foo" validations="isAlphanumeric" />

Returns true if string only contains letters or numbers

isInt

<MyInput name="foo" validations="isInt" />

Returns true if string represents integer value. Examples: 42; -12; 0

isFloat

<MyInput name="foo" validations="isFloat" />

Returns true if string represents float value. Examples: 42; -3.14; 1e3

isWords

<MyInput name="foo" validations="isWords" />

Returns true if string is only letters, including spaces and tabs

isSpecialWords

<MyInput name="foo" validations="isSpecialWords" />

Returns true if string is only letters, including special letters (a-z,ú,ø,æ,å)

equals:value

<MyInput name="foo" validations="equals:4" />

Return true if the value from input component matches value passed (==).

equalsField:fieldName

<MyInput name="password"/>
<MyInput name="repeated_password" validations="equalsField:password"/>

Return true if the value from input component matches value of field passed (==).

isLength:length

<MyInput name="foo" validations="isLength:8" />

Returns true if the value length is the equal.

minLength:length

<MyInput name="number" validations="minLength:1" />

Return true if the value is more or equal to argument. Also returns true for an empty value. If you want to get false, then you should use required additionally.

maxLength:length

<MyInput name="number" validations="maxLength:5" />

Return true if the value is less or equal to argument