Basic validation

A very basic form validation.

This example uses the default mode - onSubmitUnlessError. The whole form is validated upon submit. If there are errors, the invalid inputs are revalidated based on revalidationStrategy - the default used in this example is onChange. This will only revalidate invalid inputs when they change, never the whole form. As soon as the input is valid, the revalidation will not happen again unless submitted or otherwise requested.

Basic validation

Basic validation with custom validator functions for different fields.

User registration
import React from "react";
import { useBrowserForm, ValidationError, ValidationSchema } from "react-browser-form";

// UI for documentation only
import { Button, Stack } from "react-bootstrap";
import { FormGroup, FormGroupTitle, FormTextInput } from "ui/forms";
import { FormPassword } from "ui/forms/FormPassword";

// FORM SETUP AND VALIDATION
// --------------------------------------------------------------------------------

const defaultValues = {
  name: "",
  email: "",
  newPassword: "",
};
type Form = typeof defaultValues;

const validationSchema: ValidationSchema<Form> = {
  validators: {
    name: name => {
      if (name.length < 5) throw new ValidationError("Name must be at least 5 characters long");
    },

    email: email => {
      if (!email.match(/^\S{2,}@\S{2,}\.\S{2,}$/)) throw new ValidationError("E-mail must match pattern xx@xx.xx");
    },

    newPassword: newPassword => {
      if (!newPassword.match(/[a-z]/))
        throw new ValidationError("Password must contain at least one lowercase letter.");
      if (!newPassword.match(/[A-Z]/))
        throw new ValidationError("Password must contain at least one UPPERCASE letter.");
      if (!newPassword.match(/[0-9]/)) throw new ValidationError("Password must contain at least one number.");
      if (newPassword.length < 8) throw new ValidationError("Password must be at least 8 characters long.");
    },
  },
};

// COMPONENT
// --------------------------------------------------------------------------------

export function ExampleBasicValidation() {
  const [data, setData] = React.useState<Form>();

  const { formProps, names, errorData } = useBrowserForm<Form>({
    name: "example-basic-validation-form",
    defaultValues,
    onSubmit: setData,
    validationSchema,
  });

  const { errors } = errorData;

  return (
    <form {...formProps}>
      <FormGroupTitle>User registration</FormGroupTitle>
      <FormGroup>
        <FormTextInput label="Name" requiredMark name={names.name} error={errors.name} />
        <FormTextInput label="E-mail" requiredMark name={names.email} error={errors.email} />
      </FormGroup>
      <FormPassword label="Password" requiredMark name={names.newPassword} error={errors.newPassword} />

      <Stack direction="horizontal" className="justify-content-end mt-5">
        <Button type="submit" disabled={errorData.count > 0}>
          Submit registration
        </Button>
      </Stack>
    </form>
  );
}
Form meta
Submitted?
No
Has errors?
No
Is dirty?
No
Change reason
Form state

Validation after init

This form is exactly the same as the first one, except for having validateAfterInit set to true.

User registration
import React from "react";
import { useBrowserForm, ValidationError, ValidationSchema } from "react-browser-form";

// UI for documentation only
import { Button, Stack } from "react-bootstrap";
import { FormGroup, FormGroupTitle, FormTextInput } from "ui/forms";
import { FormPassword } from "ui/forms/FormPassword";

// FORM SETUP AND VALIDATION
// --------------------------------------------------------------------------------

const defaultValues = {
  name: "",
  email: "",
  newPassword: "",
};
type Form = typeof defaultValues;

const validationSchema: ValidationSchema<Form> = {
  validators: {
    name: name => {
      if (name.length < 5) throw new ValidationError("Name must be at least 5 characters long");
    },

    email: email => {
      if (!email.match(/^\S{2,}@\S{2,}\.\S{2,}$/)) throw new ValidationError("E-mail must match pattern xx@xx.xx");
    },

    newPassword: newPassword => {
      if (!newPassword.match(/[a-z]/))
        throw new ValidationError("Password must contain at least one lowercase letter.");
      if (!newPassword.match(/[A-Z]/))
        throw new ValidationError("Password must contain at least one UPPERCASE letter.");
      if (!newPassword.match(/[0-9]/)) throw new ValidationError("Password must contain at least one number.");
      if (newPassword.length < 8) throw new ValidationError("Password must be at least 8 characters long.");
    },
  },
};

// COMPONENT
// --------------------------------------------------------------------------------

export function ExampleBasicValidationOnInit() {
  const [data, setData] = React.useState<Form>();

  const { formProps, names, errorData } = useBrowserForm<Form>({
    name: "example-basic-validation-on-init-form",
    defaultValues,
    onSubmit: setData,
    validationSchema,
    validateAfterInit: true,
  });

  const { errors } = errorData;

  return (
    <form {...formProps}>
      <FormGroupTitle>User registration</FormGroupTitle>
      <FormGroup>
        <FormTextInput label="Name" requiredMark name={names.name} error={errors.name} />
        <FormTextInput label="E-mail" requiredMark name={names.email} error={errors.email} />
      </FormGroup>
      <FormPassword label="Password" requiredMark name={names.newPassword} error={errors.newPassword} />

      <Stack direction="horizontal" className="justify-content-end mt-5">
        <Button type="submit" disabled={errorData.count > 0}>
          Submit registration
        </Button>
      </Stack>
    </form>
  );
}
Form meta
Submitted?
No
Has errors?
No
Is dirty?
No
Change reason
Form state