Git Product home page Git Product logo

react-form-with-constraints's Introduction

react-form-with-constraints

npm version Node.js CI codecov Bundle size Prettier Airbnb Code Style

Simple form validation for React

Check the changelog for breaking changes and fixes between releases.

Introduction: what is HTML5 form validation?

⚠️ Client side validation is cosmetic, you should not rely on it to enforce security

<form>
  <label for="email">Email:</label>
  <input type="email" id="email" required>
  <button type="submit">Submit</button>
</form>

input required input type="email"

The required HTML5 attribute specifies that the user must fill in a value, type="email" checks that the entered text looks like an email address.

Resources:

What react-form-with-constraints brings

  • Minimal API and footprint
  • Unobtrusive: easy to adapt regular React code
  • HTML5 error messages personalization: <FieldFeedback when="valueMissing">My custom error message</FieldFeedback>
  • Custom constraints: <FieldFeedback when={value => ...}>
  • Warnings and infos: <FieldFeedback ... warning>, <FieldFeedback ... info>
  • Async validation
  • No dependency beside React (no Redux, MobX...)
  • Re-render only what's necessary
  • Easily extendable
  • Bootstrap styling with npm package react-form-with-constraints-bootstrap
  • Material-UI integration with npm package react-form-with-constraints-material-ui
  • Support for React Native with npm package react-form-with-constraints-native
  • ...
<input type="password" name="password"
       value={this.state.password} onChange={this.handleChange}
       required pattern=".{5,}" />
<FieldFeedbacks for="password">
  <FieldFeedback when="valueMissing" />
  <FieldFeedback when="patternMismatch">
    Should be at least 5 characters long
  </FieldFeedback>
  <FieldFeedback when={value => !/\d/.test(value)} warning>
    Should contain numbers
  </FieldFeedback>
  <FieldFeedback when={value => !/[a-z]/.test(value)} warning>
    Should contain small letters
  </FieldFeedback>
  <FieldFeedback when={value => !/[A-Z]/.test(value)} warning>
    Should contain capital letters
  </FieldFeedback>
</FieldFeedbacks>

Examples

How it works

The API works the same way as React Router:

<Router>
  <Route exact path="/" component={Home} />
  <Route path="/news" component={NewsFeed} />
</Router>

It is also inspired by AngularJS ngMessages.

If you had to implement validation yourself, you would end up with a global object that tracks errors for each field. react-form-with-constraints works similarly. It uses React context to share the FieldsStore object across FieldFeedbacks and FieldFeedback.

API

The API reads like this: "for field when constraint violation display feedback", example:

<FieldFeedbacks for="password">
  <FieldFeedback when="valueMissing" />
  <FieldFeedback when="patternMismatch">Should be at least 5 characters long</FieldFeedback>
</FieldFeedbacks>
for field "password"
  when constraint violation "valueMissing"    display <the HTML5 error message (*)>
  when constraint violation "patternMismatch" display "Should be at least 5 characters long"

(*) element.validationMessage

Async support works as follow:

<FieldFeedbacks for="username">
  <Async
    promise={checkUsernameAvailability} /* Function that returns a promise */
    then={available => available ?
      <FieldFeedback key="1" info style={{color: 'green'}}>Username available</FieldFeedback> :
      <FieldFeedback key="2">Username already taken, choose another</FieldFeedback>
      // Why key=*? Needed otherwise React gets buggy when the user rapidly changes the field
    }
  />
</FieldFeedbacks>

Trigger validation:

function MyForm() {
  const form = useRef(null);

  async function handleChange({ target }) {
    // Validates only the given fields and returns Promise<Field[]>
    await form.current.validateFields(target);
  }

  async function handleSubmit(e) {
    e.preventDefault();

    // Validates the non-dirty fields and returns Promise<Field[]>
    await form.current.validateForm();

    if (form.current.isValid()) console.log('The form is valid');
    else console.log('The form is invalid');
  }

  return (
    <FormWithConstraints ref={form} onSubmit={handleSubmit} noValidate>
      <input
        name="username"
        onChange={handleChange}
        required minLength={3}
      />
      <FieldFeedbacks for="username">
        <FieldFeedback when="tooShort">Too short</FieldFeedback>
        <Async
          promise={checkUsernameAvailability}
          then={available => available ?
            <FieldFeedback key="1" info style={{color: 'green'}}>Username available</FieldFeedback> :
            <FieldFeedback key="2">Username already taken, choose another</FieldFeedback>
          }
        />
        <FieldFeedback when="*" />
      </FieldFeedbacks>
    </FormWithConstraints>
  );
}

Important note:

If a field (i.e an <input>) does not have a matching FieldFeedbacks, the library won't known about this field (and thus won't perform validation). The field name should match FieldFeedbacks.for:

<input name="MY_FIELD" ...>
<FieldFeedbacks for="MY_FIELD">
  ...
</FieldFeedbacks>


  • FieldFeedbacks

    • for: string => reference to a name attribute (e.g <input name="username">), should be unique to the current form
    • stop?: 'first' | 'first-error' | 'first-warning' | 'first-info' | 'no' => when to stop rendering FieldFeedbacks, by default stops at the first error encountered (FieldFeedbacks order matters)

    Note: you can place FieldFeedbacks anywhere, have as many as you want for the same field, nest them, mix them with FieldFeedback... Example:

    <input name="username" ... />
    
    <FieldFeedbacks for="username" stop="first-warning">
      <FieldFeedbacks>
        <FieldFeedback ... />
        <Async ... />
        <FieldFeedbacks stop="first-info">
          ...
        </FieldFeedbacks>
      </FieldFeedbacks>
    
      <FieldFeedback ... />
      <Async ... />
    </FieldFeedbacks>
    
    <FieldFeedbacks for="username" stop="no">
      ...
    </FieldFeedbacks>
  • FieldFeedback

    • when?:
      • ValidityState as a string => HTML5 constraint violation name
      • '*' => matches any HTML5 constraint violation
      • 'valid' => displays the feedback only if the field is valid
      • (value: string) => boolean => custom constraint
    • error?: boolean => treats the feedback as an error (default)
    • warning?: boolean => treats the feedback as a warning
    • info?: boolean => treats the feedback as an info
    • children => what to display when the constraint matches; if missing, displays the HTML5 error message if any
  • Async<T> => Async version of FieldFeedback (similar API as react-promise)

    • promise: (value: string) => Promise<T> => a promise you want to wait for
    • pending?: React.ReactNode => runs when promise is pending
    • then?: (value: T) => React.ReactNode => runs when promise is resolved
    • catch?: (reason: any) => React.ReactNode => runs when promise is rejected
  • FormWithConstraints

    • validateFields(...inputsOrNames: Array<Input | string>): Promise<Field[]> => Should be called when a field changes, will re-render the proper FieldFeedbacks (and update the internal FieldsStore). Without arguments, all fields ($('[name]')) are validated.

    • validateFieldsWithoutFeedback(...inputsOrNames: Array<Input | string>): Promise<Field[]> => Validates only all non-dirty fields (won't re-validate fields that have been already validated with validateFields()), If you want to force re-validate all fields, use validateFields(). Might be renamed to validateNonDirtyFieldsOnly() or validateFieldsNotDirtyOnly() in the future?

    • validateForm(): Promise<Field[]> => Same as validateFieldsWithoutFeedback() without arguments, typically called before to submit the form. Might be removed in the future?

    • isValid(): boolean => should be called after validateFields(), validateFieldsWithoutFeedback() or validateForm(), indicates if the fields are valid

    • hasFeedbacks(): boolean => indicates if any of the fields have any kind of feedback

    • resetFields(...inputsOrNames: Array<Input | string>): Field[] => Resets the given fields and re-render the proper FieldFeedbacks. Without arguments, all fields ($('[name]')) are reset.

    • Field =>

      {
        name: string;
        validations: { // FieldFeedbackValidation[]
          key: number;
          type: 'error' | 'warning' | 'info' | 'whenValid';
          show: boolean | undefined;
        }[];
        isValid: () => boolean
      }
  • Input

    If you want to style <input>, use <Input> instead: it will add classes is-pending, has-errors, has-warnings, has-infos and/or is-valid on <input> when the field is validated.

    Example: <Input name="username" /> can generate <input name="username" class="has-errors has-warnings">

    FYI react-form-with-constraints-bootstrap and react-form-with-constraints-material-ui already style the fields to match their respective frameworks.

Browser support

react-form-with-constraints needs ValidityState which is supported by all modern browsers and IE 11. It also needs a polyfill such as core-js to support IE 11, see React JavaScript Environment Requirements.

You can use HTML5 attributes like type="email", required, minlength...

<label htmlFor="email">Email</label>
<input type="email" name="email" id="email"
       value={this.state.email} onChange={this.handleChange}
       required />
<FieldFeedbacks for="email">
  <FieldFeedback when="*" />
</FieldFeedbacks>

...and/or rely on when functions:

<label htmlFor="email">Email</label>
<input name="email" id="email"
       value={this.state.email} onChange={this.handleChange} />
<FieldFeedbacks for="email">
  <FieldFeedback when={value => value.length === 0}>Please fill out this field.</FieldFeedback>
  <FieldFeedback when={value => !/\S+@\S+/.test(value)}>Invalid email address.</FieldFeedback>
</FieldFeedbacks>

In the last case you will have to manage translations yourself (see SignUp example).

Notes

react-form-with-constraints's People

Contributors

tkrotoff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-form-with-constraints's Issues

Use HOC instead of inheriting?

See https://facebook.github.io/react/docs/higher-order-components.html
See HOC branch and 354dcba

Example:

import {
  WithConstraints, WithConstraintsProps,
  FieldFeedbacks, FieldFeedback
} from 'react-form-with-constraints';

class Form extends React.Component<WithConstraintsProps> {
  constructor(props: WithConstraintsProps) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(e: React.FormEvent<HTMLInputElement>) {
    this.props.handleChange(e);
  }

  handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    this.props.handleSubmit(e);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit} noValidate>
        <input type="email" name="username" onChange={this.handleChange} required />
        <FieldFeedbacks for="username">
          <FieldFeedback when="*" />
        </FieldFeedbacks>
      </form>
    );
  }
}
const FormWithConstraints = WithConstraints(Form);

ReactDOM.render(<FormWithConstraints />, document.getElementById('app'));

vs

import {
  FormWithConstraints,
  FieldFeedbacks, FieldFeedback
} from 'react-form-with-constraints';

interface Props {}

class Form extends FormWithConstraints<Props> {
  constructor(props: Props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(e: React.FormEvent<HTMLInputElement>) {
    super.handleChange(e);
  }

  handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    super.handleSubmit(e);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit} noValidate>
        <input type="email" name="username" onChange={this.handleChange} required />
        <FieldFeedbacks for="username">
          <FieldFeedback when="*" />
        </FieldFeedbacks>
      </form>
    );
  }
}

ReactDOM.render(<Form />, document.getElementById('app'));

Conclusion: I don't see any advantage to use HOC instead of inheritance in the case of ReactFormWithConstraints

Show something while a field is untouched, when dirty replace by feedbacks

I hate to be a pest with stupid questions.... ;)

I'm looking for a way to show some helper text on an unvalidated field and then swap it out for FieldFeedback error messages when necessary. Is there an easy way to do that?

I thought <FieldFeedback when="valid" might do what I want, but that only seems to display after the form has been validated (which makes sense). I then tried to just apply a <FieldFeedback info/> with my helper text in it, but that also doesn't show up until after a validation (and even then looks just like an error message).

So I'm looking at tracking which fields are unvalidated or validdated-and-valid (either in state or via a bunch of refs) so I can show/hide some typography inside helperText... But that feels extra dirty, so I figured it was worth asking here -- Is there a better way to do what I'm after?

Split in multiple packages

Instead of
import { ... } from 'react-form-with-constraints/lib/Native'
import { ... } from 'react-form-with-constraints/lib/Bootstrap4'

Introduce multiple npm packages:

  • react-form-with-constraints
  • react-form-with-constraints-dom
  • react-form-with-constraints-native
  • react-form-with-constraints-bootstrap4

Will also solve some TypeScript typings:

node_modules/@types/node/index.d.ts(117,13): error TS2300: Duplicate identifier 'require'.
node_modules/@types/react-native/index.d.ts(8584,14): error TS2300: Duplicate identifier 'require'.

See DefinitelyTyped/DefinitelyTyped#16825

error TS2415: Class 'FormWithConstraints' incorrectly extends base class 'FormWithConstraints'.
  Types of property 'validateFields' are incompatible.

Required field validation does not work properly with class-based components

Hey there,

Using the react-form-with-constraints-material-ui npm package, I followed the MaterialUI example - which seems to work fine in the codesandbox - to try and get form validation working inside a class-based component.

After a couple of hours working on a simple two TextField login form (both TextFields carry both required and inputProps={{required:true}}), I'm giving up. I see the HTML attributes being applied to the elements inside the form, but FormWithConstraints.isValid() is always true, and Field.isValid() returns true for every field on the form even when both fields are empty and untouched.

I tossed up a CodeSandbox repro here - check the console with the submit button is pressed.

I also ran across a variant sample that is component based, and that wraps the ref assignment up into an arrow function. I tried that approach too, but it doesn't seem to make any difference in what I'm seeing, the form is always valid when it shouldn't be.

Does the library just not work with class-based components or am I doing something wrong?

Thanks.

Possible memory leak with the tests?

Here:

process.on('unhandledRejection', (reason: Error | any, _promise: Promise<any>) => {
console.error('Unhandled promise rejection:', reason);
});

Read Testing with Jest: 15 Awesome Tips and Tricks:

// In Node v7 unhandled promise rejections will terminate the process
if (!process.env.LISTENING_TO_UNHANDLED_REJECTION) {
  process.on('unhandledRejection', reason => {
    throw reason
  })
  // Avoid memory leak by adding too many listeners
  process.env.LISTENING_TO_UNHANDLED_REJECTION = true
}

“Hold up, stipsan; I thought setupFiles run before each test in a sandboxed env, how can a memory leak happen?” good question, you’re right that every test is isolated. But process is a special variable provided by Node that is shared between tests, even when running tests with multiple workers. That is why it’s necessary to add the guard against leaks. If you think about it there’s sense to this. How else would it be possible to $ NODE_ENV=test jest in your terminal and somehow all your tests can access process.env.NODE_ENV and see that it’s value is test just like you expected?

'React' has no exported member 'FormHTMLAttributes'

When I install the package, I get the following error

./node_modules/react-form-with-constraints/lib/FormWithConstraints.d.ts:11:57
TS2694: Namespace 'React' has no exported member 'FormHTMLAttributes'.

Using react 16.1.1

How can I get this to work ?

validateForm() IE11

Just wanted to use this issue to either report a bug or clarify browser support / necessary polyfills.

In testing our relatively simple form I've noticed that IE11 seems to skip through the validation (without throwing any error).

It seems the form.validateForm() method is returning an empty array, I'm still looking into getting some more information so will report back here with what I find. In the meantime here is a simplified forked version (with a Promise polyfill added) of the example on Codepen that recreates the issue.

https://codepen.io/ryanhyslop/pen/BxJQrR

And a couple of screenshots that show the same form being submitted with the same values:

IE11:
ie11 example

Chrome:
chrome example

Returns HTMLElement in Field

Hello @tkrotoff! Thanks for your great job 👍

It would be appreciated if you could return in the Field object, the HTMLElement of the invalid field?
Something like:

{
  name: string;
  validations: { // FieldFeedbackValidation[]
    key: number;
    type: 'error' | 'warning' | 'info' | 'whenValid';
    show: boolean | undefined;
  }[];
  isValid: () => boolean,
  element: HTMLElement
}

Thanks! ;)

Examples should use the npm package

Instead of:
import { ... } from '../../src/index'
use:
import { ... } from 'react-form-with-constraints'
with package.json having:
"react-form-with-constraints": "../.."

Getting TS2605 and TS2607 errors

I'm receiving errors when trying to import and use the package's FieldFeedbacks and FieldFeedback components.

TS2605: JSX element type 'FieldFeedback' is not a constructor function for JSX elements.
     Property 'setState' is missing in type 'FieldFeedback'.

TS2607: JSX element class does not support attributes because it does not have a 'props' property.

We're currently running:

[email protected]
webpack 3.1.0
tsc 2.3.5

I've tried using the following versions of react-form-with-constraints with the same results (thinking it might be because of your react 16 updates in the recent versions):

0.6.3
0.6.2
0.6.1
0.6.0

I'm getting ready to try 0.5.2 before giving up and moving on but I like the simplicity of this lib and I really hope I can get it to work.

Example code:

import * as React from 'react';
// ...
import ( FieldFeedbacks, FieldFeedback } from 'react-form-with-constraints';

export interface FormDetailProps {
    selectedRecord: IRecord
    onChange: (item) => void
}

export class FormDetail extends React.Component<FormDetailProps, {}> {
    constructor(props) {
        super(props)
    }    
    
    render() {
        // ...
        const { onChange, selectedRecord} = this.props
        // ...

        return (
            <Form horizontal >
                <input name="ctrl1" onChange={this.props.onChange} type="text" value={selectedRecord.dummy1} />
                <FieldFeedbacks for="ctrl1" show="all">
                    <FieldFeedback when={x => !x} error>
                        Required
                    </FieldFeedback>
                </FieldFeedbacks>
            </Form>
        )
    }
}

Is the problem because I'm not running react 16? Or something else I'm missing?

Thanks for your time

componentWillMount is deprecated

With React 16.9.0-alpha.0

Warning: componentWillMount is deprecated and will be removed in the next major version. Use componentDidMount instead. As a temporary workaround, you can rename to UNSAFE_componentWillMount.

Please update the following components: Async, FieldFeedback, FieldFeedbackWhenValid, FieldFeedbacks, Input

Example for modifying the style of the input based on validation

Hi, firstly really like the look of this library and seriously considering using it in a project so thanks!

I was curious as to whether you had considered a means to modify the styling of the actual input when its invalid? A common pattern would be to change the colour of the border or background for instance.

I notice (at least as far as v.0.7) the fieldStore keeps a reference to all the fields and theres an error property on them. It wouldn't be too difficult to read from this to check if a field has an error;

ie.form.fieldsStore.fields.fieldName.errors

but was wary of using something thats not an official API for this. Something akin to:
className: (form.fieldStore.isFieldValid('name')) ? 'is-valid' : ' is-not-valid';

Move to new React context API + forwardRef + StrictMode

See also React codemod scripts: https://github.com/reactjs/react-codemod

Validation errors not disappearing

I'm seeing some unexpected behavior when I trigger validation on a button press:

onSave = async (event: React.MouseEvent<HTMLButtonElement>) => {
        event.preventDefault();

        // I need to add this call, otherwise all the validation messages from
        // the previous submission attempt stay, even though the offending
        // input fields are fixed.
        this.form.current.reset();

        await this.form.current.validateForm();
        if (!this.form.current.isValid()) {
            console.log('Form invalid');
            return;
        }

        // Continue processing...
}

The examples don't have this reset() call, so I'm wondering what could cause this type of behavior?
I can't think of anything "special" I did in my form that would cause this.

I'm using version 0.15.0.

"Multiple elements matching 'name' inside the form" error

Hi there,

I'm using the material-ui flavor of react-form-with-constraints on a form that hosts a react filepond component to allow upload of files. There aren't any validation hooks for this component so it doesn't interact directly with your component in any way I can find. My code handles the onSubmit event to manually verify the filepond component has files, if so, it calls FormWithConstraints.validateForm().

This works just fine until there's more than one file in the filepond component, in which case the error "Multiple elements matching '[name="filepond"]' inside the form" is thrown from the forEach callback inside FormWithConstraints.normalizeInputs:

inputs
                .filter(input => input.type !== 'checkbox' && input.type !== 'radio')
                .map(input => input.name)
                .forEach((name, index, self) => {
                if (self.indexOf(name) !== index) {
                    throw new Error(`Multiple elements matching '[name="${name}"]' inside the form`);
                }
            });

Apparently, filepond creates a dynamic hidden element inside the form for each file that's been added to it. We don't actually need those hiddens because at the point the form's being submitted, we've already uploaded them to temporary storage -- and when I'm done here I'm going to bug the maintainers of that project to see if there's a way to disable that or at least force it to generate unique names -- but in the meantime I'm here to see if there's a way to work around this error from normalizeInputs. Is there or can there be a way to tell it "ignore things with this name because you aren't going to validate them"?

Thanks.

Default feedback type shouldn't be error

By default the feedback type is an error: <FieldFeedback when="valueMissing" />
Should it be explicit like for warning and info? <FieldFeedback when="valueMissing" error />

Then what is the type of a feedback without explicit type? info?

Use React.createRef() instead of callback ref

See Introduction to Refs in React 16.3

Prior to React v16.3 the callback ref were the preferred way to create and use refs. [...]
If you use an inline callback function for your ref a new function is created for every re-render. This is the case with any arrow function inside the render method.
The inline callback function will also be called twice during updates. [...] the first call produces a null value before the element is return on the second call.

Crash "Can't perform a React state update on an unmounted component"

react-dom.development.js?61bb:506 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in Async (created by Coordonnees)
    in FieldFeedbacks (created by Coordonnees)
    in div (created by FormSectionGroup)
    in FormSectionGroup (created by Coordonnees)
    in Coordonnees (created by EtapePrincipale)
    in div (created by FormSection)
    in div (created by FormSection)
    in section (created by FormSection)
    in FormSection (created by EtapePrincipale)
    in fieldset (created by EtapePrincipale)
    in form (created by FormWithConstraints)
    in FormWithConstraints (created by EtapePrincipale)
    in div (created by EtapePrincipale)
    in EtapePrincipale (created by component)
    in component (created by Context.Consumer)

Context: the form (with hooks) performs a validation with Async, the validation is not done yet while the form is re-rendered (because the upper state has changed).

Return the input state and form state using hooks

With v0.12, to stylize an input given its state (pending for example), you have to catch the events:

export class Input extends React.Component {
  [...]

  state: InputState = {
    field: undefined
  };

  componentWillMount() {
    this.context.form.addFieldWillValidateEventListener(this.fieldWillValidate);
    this.context.form.addFieldDidValidateEventListener(this.fieldDidValidate);
    this.context.form.addFieldDidResetEventListener(this.fieldDidReset);
  }

  componentWillUnmount() {
    this.context.form.removeFieldWillValidateEventListener(this.fieldWillValidate);
    this.context.form.removeFieldDidValidateEventListener(this.fieldDidValidate);
    this.context.form.removeFieldDidResetEventListener(this.fieldDidReset);
  }

  fieldWillValidate = (fieldName: string) => {
    // Ignore the event if it's not for us
    if (fieldName === this.props.name) {
      this.setState({ field: 'pending' });
    }
  };

  fieldDidValidate = (field: Field) => {
    // Ignore the event if it's not for us
    if (field.name === this.props.name) {
      this.setState({ field });
    }
  };

  fieldDidReset = (field: Field) => {
    // Ignore the event if it's not for us
    if (field.name === this.props.name) {
      this.setState({ field: undefined });
    }
  };

  [...]
}

There is probably a better story here thx to hooks.

const field = useField('fieldName');
return (
  <input className={field.state === 'PENDING' ? 'is-pending' : ''} />
);
enum FieldValidationState {
  Untouched,
  ValidationPending,
  ValidationPerformed
};

See https://www.google.com/search?q=field+validation+status

Work on field lifecycle: untouched => willValidate => didValidate (hasErrors, hasWarnings, hasInfos, isValid) => didReset

Related issues: #40

We should also do the same for the form itself:

const form = useForm(...);
if (form.state === 'VALID') ...
enum FormState {
  Untouched,
  ValidationPending,
  ValidationPerformed
};

Work on form lifecycle: untouched => willValidate => didValidate (hasErrors, hasWarnings, hasInfos, isValid) => didReset

Check for inspiration here: https://github.com/bluebill1049/react-hook-form

react-native

html5 can be integrated to react-native?

i'm using redux-form but don't work well like angular4 reactive-form, i'm looking for to have control about states on the fields

angular4-control-state-transitions-anim

How to reset a specific fields validation state

I want to clear a specific fields validation state but cant see anything in the docs to do this. I've looked at other issues but cant figure it out.

Is it possible?

I've tried this but I get "this.form.fieldsStore.updateField is not a function":

this.form.fieldsStore.updateField('startTime', {
	dirty: false,
	infos: new Set(),
	errors: new Set(),
	warnings: new Set(),
	validationMessage: '',
});

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.