Form pattern validation with react-hook-form

Viewed 45806

I have been working on a react form and I need to restrict users to put special characters and allow only these ones: [A-Za-z].

I have tried the below code but I am still able to insert inside special characters such as: '♥', '>', '+', etc.

export default Component (props {
  ...
  return (
   <input 
    pattern={props.pattern}
   /> 
  )
}

And I am sending it as a prop to my form:

<Component 
pattern="[A-Za-z]+"
/>

Can you let me know what I am missing and point out what could be the issue? Many thanks.

4 Answers

The pattern attribute on input only works on submit in vanilla HTML forms.

If you're using react-hook-form, it should be in the ref, like this:

<input
    name="email"
    ref={register({
      required: "Required",
      pattern: {
        value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
        message: "invalid email address"
      }
    })}
  />

please have a check on react-hook-form doc. Additionally for simple form use case you can try cksform library.

If you are using react-hook-form v7 then use this:

<input
    placeholder="Email"
    {...register('email', {
        required: 'Email is required',
        pattern: {
            value: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
            message: 'Please enter a valid email',
        },
    })}
    type="email"
    required
    className="input"
/>
{formState.errors.email?.message && (
     <FormError errorMessage={formState.errors.email?.message} />
)}

Assuming your input is name then you can just exclude those special characters, use the every function on pattern, basically check that each pattern is true otherwise throw an error message that you can override as you prefer

 <label htmlFor="name">Name</label>
  <input
    type="text"
    name="name"
    id="name"
    ref={register({
    required: "required",
    maxLength: {
    value: 15,
          message: "must be max 15 chars",
        },
        validate: (value) => {
          return (
            [/[a-z]/, /[A-Z]/, /[0-9]/].every((pattern) =>
              pattern.test(value)
            ) || "cannot special chars, only lower, upper, number"
          );
        },
      })}
    />
    {errors.email ? <div>{errors.email.message}</div> : null}

Or for example if your field is a password and you want that the user include at least a special character, then it would be like this:

<label htmlFor="password">Password</label>
    <input
      type="password"
      name="password"
      id="password"
      ref={register({
        required: "required",
        minLength: {
          value: 8,
          message: "must be 8 chars",
        },
        validate: (value) => {
          return (
            [/[a-z]/, /[A-Z]/, /[0-9]/, /[^a-zA-Z0-9]/].every((pattern) =>
              pattern.test(value)
            ) || "must include lower, upper, number, and special chars"
          );
        },
      })}
    />
    {errors.password ? <div>{errors.password.message}</div> : null}
  </div>
Related