3.1.0 ā€¢ Published 3 months ago

@roqueform/doubter-plugin v3.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

Doubter plugin for Roqueform

Validates Roqueform fields with Doubter shapes.

šŸ”„ā€‚Try it on CodeSandbox

npm install --save-prod @roqueform/doubter-plugin

Overview

šŸ”Ž API documentation is available here.

This plugin doesn't require any rendering framework. To simplify the usage example, we're going to use the React integration.

import { SyntheticEvent } from 'react';
import { FieldRenderer, useField } from '@roqueform/react';
import { doubterPlugin } from '@roqueform/doubter-plugin';
import * as d from 'doubter';

const planetShape = d.object({
  name: d.string().min(1),
});

export const App = () => {
  const planetField = useField(
    { name: '' },
    doubterPlugin(planetShape)
  );

  const handleSubmit = (event: SyntheticEvent) => {
    event.preventDefault();

    if (planetField.validate()) {
      // If your shapes transform the input, you can safely parse
      // the field value after it was successfully validated.
      const value = planetShape.parse(planetField.value);
      
      doSubmit(value);
    } else {
      // Errors are associated with fields automatically.
    }
  };

  return (
    <form onSubmit={handleSubmit}>

      <FieldRenderer field={planetField.at('name')}>
        {nameField => (
          <>
            <input
              value={nameField.value}
              onChange={event => {
                nameField.setValue(event.target.value);
              }}
              aria-invalid={nameField.isInvalid}
            />

            {nameField.errors[0]?.message}
          </>
        )}
      </FieldRenderer>

      <button type="submit">
        {'Submit'}
      </button>

    </form>
  );
};

Validating fields

Define a field value shape using Doubter.

import * as d from 'doubter';

const planetShape = d.object({
  name: d.string().min(5)
});
// ā®• Shape<{ name: string }>

Create a new field and enhance it with the plugin:

import { useField } from '@roqueform/react';
import { doubterPlugin } from '@roqueform/doubter-plugin';

const planetField = useField(
  { name: 'Mars' },
  doubterPlugin(planetShape)
);

The type of the field value is inferred from the provided shape, so the field value is statically checked.

When you call the validate method, it triggers validation of the field and all of its child fields. So if you call validate on the child field, it won't validate the parent field:

planetField.at('name').validate();
// ā®• false

planetField.at('name').errors;
// ā®• [{ message: 'Must have the minimum length of 5', ā€¦ }]

In this example, planetField.value is not validated, and planetField.at('name').value is validated.

!NOTE\ It's safe to trigger validation of a single text field on every keystroke, since validation doesn't have to process the state of the whole form.

To detect whether the field, or any of its child fields contain a validation error:

planetField.isInvalid;
// ā®• true

Managing errors manually

You can manually associate an error with the field:

planetField.at('name').addError({ message: 'Oh, snap!' });

This may come handy when you want to mix client-side and server-side validation: when you receive errors as a server response, use addError to associate them with form fields.

If a string is provided as an error, then it becomes an error message. The error code in this case is set to "custom":

planetField.addError('Illegal planet');

planetField.errors;
// ā®• [{ code: 'custom', message: 'Illegal planet' }]

Custom error messages

You can customize messages for errors raised by Doubter (the component code is omitted for clarity):

import { useField } from '@roqueform/react';
import { doubterPlugin } from '@roqueform/doubter-plugin';
import * as d from 'doubter';

const valueShape = d.array(d.string(), 'Expected an array').min(3, 'Not enough elements');

const field = useField([], doubterPlugin(valueShape));

field.validate();
// ā®• false

field.errors;
// ā®• [{ message: 'Not enough elements', ā€¦ }]
3.1.0

3 months ago

3.0.0

4 months ago

2.0.1

9 months ago

2.0.0

1 year ago

1.0.0

1 year ago

0.2.2

2 years ago

0.2.1

2 years ago

0.2.0

2 years ago