Skip to content

Forms

The useForm hook is heavily inspired by react-hook-form. You create a form object before rendering, then insert its register method into the inputs you want to control. You also get:

  • registerForm — insert into the <form> element to intercept submission
  • registerError — insert into elements where validation errors should appear
  • reset — reset all inputs to their default values
  • handleSubmit — a function that runs the form’s submission pipeline

It accepts the following options:

  • onStart — runs when submission begins
  • onSubmit — runs with the form data
  • onSuccess — runs after onSubmit completes successfully
  • onError — runs when validation fails; receives the errors object
  • onEnd — runs when submission ends, regardless of outcome
  • validate — an async function that can throw to reject the submission
Form with validation
Source
import './examples.css';
import { useForm, useRefProxy, useTextContent } from 'domstatejsx';
import Radio from './Radio.jsx';

export default function App() {
  const refs = useRefProxy();
  const [, setPre] = useTextContent(refs.pre);

  const { registerForm, register, registerError } = useForm({
    onSuccess: async (data) => {
      setPre('Success: ' + JSON.stringify(data, null, 2));
    },
    onError: async (errors) => {
      setPre('Errors: ' + JSON.stringify(errors, null, 2));
    },
    validate: async ({ username, gender }) => {
      if (username === 'Bill' && gender === 'female') {
        throw new Error("Bill is a boy's name");
      }
    },
  });

  return (
    <>
      <form {...registerForm()}>
        <p>
          Username:{' '}
          <input class="dx-input" autoFocus {...register('username', { required: true })} />
        </p>
        <p class="dx-red" style={{ display: 'none' }} {...registerError('username')} />
        <p>
          Gender:{' '}
          <Radio
            options={[
              ['male', 'Male'],
              ['female', 'Female'],
            ]}
            {...register('gender', { required: true })}
          />
        </p>
        <p class="dx-red" style={{ display: 'none' }} {...registerError('gender')} />
        <p class="dx-red" style={{ display: 'none' }} {...registerError()} />
        <p>
          <button class="dx-btn">Submit</button>
        </p>
      </form>
      <p>
        <pre class="dx-pre" ref={refs.pre} />
      </p>
    </>
  );
}