About this snippet

Client-side form validation example using JavaScript to check for required fields and valid email format before allowing submission. Provides instant feedback to users.

Size
3.7 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
331
<div class="form-card">
  <h2>Get in Touch</h2>
  <form id="myForm" novalidate>
    <div class="input-field">
      <input type="text" id="name" name="name" required placeholder=" ">
      <label for="name">Name</label>
      <span class="error-hint" id="nameError"></span>
    </div>

    <div class="input-field">
      <input type="email" id="email" name="email" required placeholder=" ">
      <label for="email">Email</label>
      <span class="error-hint" id="emailError"></span>
    </div>

    <button type="submit" id="submitBtn">
      <span>Send Message</span>
      <div class="loader"></div>
    </button>
  </form>
</div>
:root {
  --error: #ef4444;
  --success: #22c55e;
  --primary: #6366f1;
}

* {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  box-sizing: border-box;
}

.form-card {
  max-width: 400px;
  margin: 40px auto;
  padding: 30px;
  background: white;
  border-radius: 20px;
  box-shadow: 0 10px 25px rgba(0,0,0,0.05);
}

.input-field {
  position: relative;
  margin-bottom: 25px;
}

/* Floating Label Logic */
.input-field input {
  width: 100%;
  padding: 12px 0;
  border: none;
  border-bottom: 2px solid #e2e8f0;
  font-size: 1rem;
  outline: none;
  transition: all 0.3s ease;
}

.input-field label {
  position: absolute;
  top: 12px;
  left: 0;
  color: #94a3b8;
  pointer-events: none;
  transition: all 0.3s ease;
}

.input-field input:focus ~ label,
.input-field input:not(:placeholder-shown) ~ label {
  top: -12px;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--primary);
}

.input-field input:focus {
  border-color: var(--primary);
}

/* Validation States */
.input-field.invalid input { border-color: var(--error); }
.input-field.invalid label { color: var(--error); }

.error-hint {
  font-size: 0.75rem;
  color: var(--error);
  position: absolute;
  bottom: -18px;
  left: 0;
  opacity: 0;
  transform: translateY(-5px);
  transition: all 0.2s ease;
}

.input-field.invalid .error-hint {
  opacity: 1;
  transform: translateY(0);
}

button {
  width: 100%;
  padding: 14px;
  border-radius: 12px;
  border: none;
  background: var(--primary);
  color: white;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.2s;
}

button:active { transform: scale(0.98); }
const form = document.getElementById('myForm');
const inputs = form.querySelectorAll('input');

const validateInput = (input) => {
  const container = input.parentElement;
  const errorHint = container.querySelector('.error-hint');
  
  // Use HTML5 validity check
  if (!input.validity.valid) {
    container.classList.add('invalid');
    if (input.validity.valueMissing) {
      errorHint.textContent = `${input.name.charAt(0).toUpperCase() + input.name.slice(1)} is required`;
    } else if (input.validity.typeMismatch) {
      errorHint.textContent = `Please enter a valid email address`;
    }
  } else {
    container.classList.remove('invalid');
    errorHint.textContent = '';
  }
};

// Real-time validation
inputs.forEach(input => {
  input.addEventListener('blur', () => validateInput(input));
  input.addEventListener('input', () => {
    if (input.parentElement.classList.contains('invalid')) {
      validateInput(input);
    }
  });
});

form.addEventListener('submit', (e) => {
  e.preventDefault();
  
  // Validate all inputs before submit
  let isFormValid = true;
  inputs.forEach(input => {
    validateInput(input);
    if (!input.validity.valid) isFormValid = false;
  });

  if (isFormValid) {
    const btn = form.querySelector('button');
    btn.innerText = 'Success! ✓';
    btn.style.backgroundColor = 'var(--success)';
    console.log('FormData:', Object.fromEntries(new FormData(form)));
  }
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save