Làm form đăng ký có kiểm tra dữ liệu bằng JavaScript và HTML5

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Form đăng ký là cửa ngõ của hầu hết ứng dụng, và một form kiểm tra dữ liệu tốt vừa giúp người dùng nhập đúng vừa giảm lỗi cho hệ thống. Bài này hướng dẫn bạn kết hợp kiểm tra có sẵn của HTML5 với JavaScript để hiển thị thông báo lỗi rõ ràng, thân thiện.

Bắt đầu từ HTML5

Trình duyệt đã có sẵn nhiều khả năng kiểm tra mà không cần viết dòng JavaScript nào. Các thuộc tính phổ biến gồm required, type="email", minlength, maxlength, pattern, min, max. Hãy tận dụng chúng trước, rồi mới thêm JavaScript cho phần tùy biến thông báo và logic riêng như "mật khẩu nhập lại phải khớp".

<form id="signup" novalidate>
  <div class="field">
    <label for="name">Họ tên</label>
    <input id="name" name="name" type="text" required minlength="2" autocomplete="name">
    <p class="error" id="name-error" aria-live="polite"></p>
  </div>

  <div class="field">
    <label for="email">Email</label>
    <input id="email" name="email" type="email" required autocomplete="email">
    <p class="error" id="email-error" aria-live="polite"></p>
  </div>

  <div class="field">
    <label for="password">Mật khẩu</label>
    <input id="password" name="password" type="password" required minlength="8" autocomplete="new-password">
    <p class="error" id="password-error" aria-live="polite"></p>
  </div>

  <div class="field">
    <label for="confirm">Nhập lại mật khẩu</label>
    <input id="confirm" name="confirm" type="password" required autocomplete="new-password">
    <p class="error" id="confirm-error" aria-live="polite"></p>
  </div>

  <button type="submit">Đăng ký</button>
</form>

Thuộc tính novalidate tắt bong bóng thông báo mặc định của trình duyệt để ta tự hiển thị lỗi theo ý mình, nhưng vẫn dùng được API kiểm tra tích hợp. Thuộc tính autocomplete giúp trình duyệt và trình quản lý mật khẩu điền sẵn đúng thông tin. Mỗi ô nhập có nhãn label gắn bằng for, đây là điều cần thiết cho khả năng truy cập.

Viết JavaScript kiểm tra

Ta dùng đối tượng validity có sẵn của mỗi ô nhập để biết lỗi gì (thiếu, quá ngắn, sai định dạng), rồi dịch ra thông báo tiếng Việt.

const form = document.getElementById('signup');

const messages = {
  name: {
    valueMissing: 'Vui lòng nhập họ tên.',
    tooShort: 'Họ tên cần ít nhất 2 ký tự.',
  },
  email: {
    valueMissing: 'Vui lòng nhập email.',
    typeMismatch: 'Email chưa đúng định dạng, ví dụ ten@example.com.',
  },
  password: {
    valueMissing: 'Vui lòng nhập mật khẩu.',
    tooShort: 'Mật khẩu cần ít nhất 8 ký tự.',
  },
  confirm: {
    valueMissing: 'Vui lòng nhập lại mật khẩu.',
    mismatch: 'Hai mật khẩu chưa khớp.',
  },
};

function showError(input, text) {
  const box = document.getElementById(input.id + '-error');
  box.textContent = text;
  input.setAttribute('aria-invalid', text ? 'true' : 'false');
}

function validateField(input) {
  // Kiểm tra riêng: mật khẩu nhập lại phải khớp
  if (input.id === 'confirm' && input.value &&
      input.value !== form.password.value) {
    showError(input, messages.confirm.mismatch);
    return false;
  }

  if (input.validity.valid) {
    showError(input, '');
    return true;
  }

  const rules = messages[input.id] || {};
  const key = Object.keys(rules).find((k) => input.validity[k]);
  showError(input, rules[key] || 'Giá trị chưa hợp lệ.');
  return false;
}

// Kiểm tra khi người dùng rời khỏi ô nhập
form.querySelectorAll('input').forEach((input) => {
  input.addEventListener('blur', () => validateField(input));
  input.addEventListener('input', () => {
    if (input.getAttribute('aria-invalid') === 'true') validateField(input);
  });
});

form.addEventListener('submit', (e) => {
  e.preventDefault();
  const inputs = [...form.querySelectorAll('input')];
  const results = inputs.map(validateField);
  if (results.every(Boolean)) {
    alert('Đăng ký thành công (demo).');
    form.reset();
  } else {
    inputs.find((i) => i.getAttribute('aria-invalid') === 'true').focus();
  }
});

Nguyên tắc trải nghiệm người dùng

  • Kiểm tra đúng lúc: hiện lỗi khi người dùng rời ô nhập (blur), không báo lỗi khi họ vừa gõ ký tự đầu tiên.
  • Thông báo cụ thể: "Mật khẩu cần ít nhất 8 ký tự" hữu ích hơn "Dữ liệu không hợp lệ".
  • Đưa focus vào ô lỗi đầu tiên khi gửi form thất bại.
  • Đừng dựa vào màu sắc: ngoài viền đỏ, luôn có chữ giải thích.
  • Cho phép dán mật khẩu và hiện mật khẩu để người dùng ít nhập sai.

Quan trọng: kiểm tra phía máy chủ

Kiểm tra phía trình duyệt chỉ để tiện cho người dùng. Bất kỳ ai cũng có thể bỏ qua nó bằng công cụ dành cho nhà phát triển hoặc gửi yêu cầu trực tiếp. Vì vậy mọi dữ liệu vẫn phải được kiểm tra lại ở backend trước khi lưu hoặc xử lý. Hãy xem bước kiểm tra ở frontend là lớp trải nghiệm, còn bước kiểm tra ở backend là lớp bảo vệ.

Kết luận

Kết hợp HTML5 validation, đối tượng validity và thông báo tiếng Việt tùy biến, bạn có một form dễ dùng mà không cần thư viện. Hãy thử thêm thanh đo độ mạnh mật khẩu hoặc kiểm tra email đã tồn tại bằng cách gọi API để nâng cấp thêm.

Nếu muốn nắm vững JavaScript và cách kết nối form với backend, bạn có thể tham khảo các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment