Tutorials Logic, IN info@tutorialslogic.com

Validations in JavaScript Form Validation

Validations

It is very important to pre-validate the forms before submission as they can have inappropriate values. JavaScript provides the facility to validate the form on the client-side so data processing will be faster than server-side validation.

Client-side validation should be treated as a user-experience feature, not a security boundary. Users can disable JavaScript, modify requests, or call your API directly, so the server must validate the same rules again before saving data.

Form Validation Examples

The old-style example above returns false to stop form submission. For new projects, prefer addEventListener(), clear error messages near each field, and the HTML5 Constraint Validation API when possible.

Javascript Validations Worked Example

Javascript Validations Worked Example
function validate() {
  const form = document.forms.myForm;
  const name = form.name.value.trim();
  const email = form.email.value.trim();
  const password = form.password.value;

  if (name === "") {
    alert("Please enter your name.");
    form.name.focus();
    return false;
  }

  if (email === "") {
    alert("Please enter your email.");
    form.email.focus();
    return false;
  }

  if (password.length < 8) {
    alert("Please enter a password with at least 8 characters.");
    form.password.focus();
    return false;
  }

  return true;
}

Accessible Form Example

A good validation flow tells users what went wrong, places the message near the input, and exposes the message to screen readers. The example below uses aria-describedby in HTML and writes the error text into matching message elements.

Accessible Validation

Accessible Validation
<form id="signupForm" novalidate>
  <label for="email">Email</label>
  <input id="email" name="email" type="email" aria-describedby="emailError">
  <small id="emailError" class="error" aria-live="polite"></small>

  <label for="password">Password</label>
  <input id="password" name="password" type="password" aria-describedby="passwordError">
  <small id="passwordError" class="error" aria-live="polite"></small>

  <button type="submit">Create account</button>
</form>

Complete Accessible Form Validation

Complete Accessible Form Validation
const form = document.querySelector("#signupForm");
const email = document.querySelector("#email");
const password = document.querySelector("#password");

function showError(input, message) {
  const error = document.querySelector(`#${input.id}Error`);
  input.setAttribute("aria-invalid", "true");
  error.textContent = message;
}

function clearError(input) {
  const error = document.querySelector(`#${input.id}Error`);
  input.removeAttribute("aria-invalid");
  error.textContent = "";
}

form.addEventListener("submit", function (event) {
  let isValid = true;

  clearError(email);
  clearError(password);

  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value.trim())) {
    showError(email, "Enter a valid email address.");
    isValid = false;
  }

  if (password.value.length < 8) {
    showError(password, "Password must be at least 8 characters.");
    isValid = false;
  }

  if (!isValid) {
    event.preventDefault();
  }
});

Pattern Validation

Regular expressions provide powerful pattern matching for validating emails, phone numbers, URLs, and more.

Regex Validation

Regex Validation
// Email validation
function isValidEmail(email) {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return regex.test(email);
}
console.log(isValidEmail('user@example.com')); // true
console.log(isValidEmail('invalid-email'));     // false

// Phone number (10 digits)
function isValidPhone(phone) {
  return /^\d{10}$/.test(phone);
}
console.log(isValidPhone('9876543210')); // true

// Strong password: min 8 chars, uppercase, lowercase, digit, special char
function isStrongPassword(pwd) {
  return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(pwd);
}
console.log(isStrongPassword('Secure@123')); // true
console.log(isStrongPassword('weak'));        // false

// URL validation
function isValidURL(url) {
  try {
    new URL(url);
    return true;
  } catch {
    return false;
  }
}
console.log(isValidURL('https://tutorialslogic.com')); // true

Validation Checklist

  • Validate required fields, length, format, and allowed values.
  • Use trim() for fields where accidental spaces should not count.
  • Show inline messages instead of relying only on alert().
  • Add aria-invalid and aria-describedby for accessible errors.
  • Revalidate on the server before trusting or storing any submitted value.

Constraint Validation API

Modern browsers provide a built-in Constraint Validation API that works alongside HTML5 form attributes like required, minlength, pattern, and type.

Constraint Validation API - JavaScript Example

Constraint Validation API - JavaScript Example
const form = document.getElementById('myForm');
const emailInput = document.getElementById('email');

form.addEventListener('submit', function(e) {
  e.preventDefault();

  // Check validity using built-in API
  if (!emailInput.validity.valid) {
    if (emailInput.validity.valueMissing) {
      emailInput.setCustomValidity('Email is required.');
    } else if (emailInput.validity.typeMismatch) {
      emailInput.setCustomValidity('Please enter a valid email address.');
    }
    emailInput.reportValidity();
    return;
  }

  // Clear custom message and submit
  emailInput.setCustomValidity('');
  console.log('Form is valid, submitting...');
});

// Real-time validation feedback
emailInput.addEventListener('input', function() {
  if (this.validity.valid) {
    this.classList.remove('is-invalid');
    this.classList.add('is-valid');
  } else {
    this.classList.remove('is-valid');
    this.classList.add('is-invalid');
  }
});

Native Form Constraints

Start with semantic HTML controls and attributes such as `required`, `type`, `min`, `max`, `step`, `minlength`, `maxlength`, and `pattern`. The browser can prevent invalid submission, expose input modes, and provide a baseline without custom JavaScript. Use the type that matches the value’s meaning, but remember that an email input checks syntax rather than whether the mailbox exists.

The `validity` property exposes flags including `valueMissing`, `typeMismatch`, `patternMismatch`, range and length failures, `stepMismatch`, `badInput`, and `customError`. `checkValidity()` returns the current result and dispatches invalid events as specified; `reportValidity()` also asks the browser to present the failure. Read the specific flag when custom text must explain the correction.

`setCustomValidity(message)` marks a control invalid while the message is non-empty. Clear it with an empty string as soon as the custom rule passes, or the field remains invalid after the user corrects it. Use custom validity for cross-field or domain rules that belong to the control, not to replace every native message automatically.

The `novalidate` form attribute disables interactive native validation for that form, and `formnovalidate` can affect one submit button. Use them only when the application implements an accessible alternative. Disabling browser presentation without replacing focus, messages, and invalid-state semantics creates a worse form.

  • Express simple constraints in HTML before adding JavaScript.
  • Inspect the exact ValidityState flag for custom guidance.
  • Clear custom validity immediately after the rule passes.
  • Do not disable native behavior without a complete replacement.

Validation Timing and Submission

Validate format after the user has had a reasonable chance to enter it. Showing errors on the first keystroke creates noise, especially for dates, names, and confirmation fields. A common design validates on blur after interaction, updates an existing error on input, and validates every field on submission.

Listen for the `submit` event on the form, not only a button click, because Enter and `requestSubmit()` can submit too. An invalid form may trigger `invalid` events without firing `submit`. Calling `form.submit()` bypasses the submit event and constraint validation; use `requestSubmit()` when script should follow the normal submission path.

Prevent the default action only when JavaScript owns submission. Disable or lock repeated submission while a request is pending, but restore controls after failure and preserve the clicked submitter when different buttons represent different actions. `FormData` includes successful named controls according to form rules; inspect that payload rather than assuming every visible field is present.

Normalize only what the domain permits. Trimming surrounding whitespace may be valid for an email address but not for a password. Parse numbers and dates with an explicit format and reject ambiguous partial conversion. Keep the original user input available when redisplaying a server error so correction does not require retyping unrelated fields.

  • Validate all fields at the final submit boundary.
  • Use requestSubmit for programmatic normal submission.
  • Prevent duplicate requests without trapping the form permanently.
  • Normalize according to field semantics, not one global rule.

Accessible Error Presentation

Associate every control with a visible label and identify required fields in text or semantics, not color alone. Place a concise correction message near the field and connect it with `aria-describedby` when appropriate. Set `aria-invalid` to reflect the current error state only when custom behavior needs it.

After a failed submission, focus the first invalid control or an error summary that links to invalid fields according to the form’s complexity. Do not move focus on every keystroke. Announce newly added summary or status text through a suitable live region, avoiding repeated announcements each time a character changes.

Write messages that state the field and the correction: “End date must be on or after start date” is better than “Invalid value.” Preserve the label, instructions, allowed units, and example format. Do not expose account existence or internal validation details where that creates a privacy or enumeration risk.

Use more than red borders. Icons, text, and valid semantic relationships must survive high contrast, zoom, screen readers, keyboard navigation, and mobile layout. Test native and custom messages in the browsers and assistive technologies the product supports, including the reduced-JavaScript path when relevant.

  • Connect errors to controls programmatically.
  • Focus deliberately only after a submission attempt.
  • State the correction instead of saying only invalid.
  • Test errors with keyboard, zoom, and screen readers.

Domain Rules and Server Trust

Syntactic validation checks shape; semantic validation checks meaning in context. A date can be syntactically valid but outside the booking window. A product ID can match a pattern but not exist or belong to the current tenant. Keep cross-field and domain rules in named functions with stable error codes so client and server behavior can be compared.

Asynchronous checks such as username availability are hints until the server commits the operation. Debounce requests, abort stale checks, identify the value being checked, and show an indeterminate state. A name reported available can be taken by another request before submission, so the server must enforce uniqueness atomically and return a field-level conflict.

Client validation improves feedback but is never a security boundary. Attackers can disable scripts or construct requests directly. Validate every untrusted input on the server before using it, including hidden fields, select values, headers, files, partner feeds, and API payloads. Prefer an allowlist of valid values and ranges over attempts to block a growing list of dangerous strings.

Validation does not replace context-aware output encoding, parameterized database queries, authorization, CSRF protection, safe file handling, or rate limits. Preserve legitimate Unicode and punctuation required by the domain. For uploads, verify size, detected content, permitted type, safe storage name, scanning policy, and authorization instead of trusting extension or client MIME type.

  • Separate syntax, domain meaning, and authorization.
  • Treat asynchronous availability as provisional.
  • Repeat all security-relevant validation on the server.
  • Use validation alongside context-specific security controls.

Validation Tests and Contracts

Create a validation matrix from each field’s accepted type, required state, normalization, minimum, maximum, allowed set, cross-field rule, and server error code. Test one valid representative, every boundary, missing and empty forms, wrong types, malformed Unicode where relevant, and combinations that change domain meaning. Generated random inputs can supplement but not replace known business boundaries.

Keep a single authoritative contract where practical, such as a server schema that can generate client hints or shared language-neutral fixtures. Client and server implementations can still differ because the browser needs presentation while the server needs trust. Run contract tests that submit the same fixtures to both and flag disagreements rather than copying regular expressions manually and assuming they remain synchronized.

Test request tampering outside the UI: remove required keys, add unknown keys, alter hidden values, send duplicate parameters, exceed size limits, change content type, and submit values from another tenant. Confirm the server rejects safely, returns stable field or form codes, avoids echoing unsafe text, and records high-risk tampering without filling logs with sensitive payloads.

  • Build tests from explicit field and domain boundaries.
  • Compare client and server outcomes with shared fixtures.
  • Send tampered requests that the UI cannot produce.
  • Keep stable error codes separate from presentation text.
Before you move on

Validations in JavaScript Form Validation Mastery Check

5 checks
  • It is very important to pre-validate the forms before submission as they can have inappropriate values.
  • JavaScript provides the facility to validate the form on the client-side so data processing will be faster than server-side validation.
  • Client-side validation should be treated as a user-experience feature, not a security boundary.
  • Users can disable JavaScript, modify requests, or call your API directly, so the server must validate the same rules again before saving data.
  • The old-style example above returns false to stop form submission.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.