Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Range Overflow và Range Underflow trong JavaScript (Validation API)

HTML5 Constraint Validation API cung cấp ValidityState object với 2 thuộc tính quan trọng cho input type=number:

  • rangeOverflow: true nếu value > max
  • rangeUnderflow: true nếu value < min

Các thuộc tính khác của validity: valueMissing, typeMismatch, patternMismatch, tooLong, tooShort, stepMismatch, badInput, valid.

Ví dụ minh họa

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Range Overflow/Underflow</title>
  <style>
    body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
    .result { font-size: 20px; font-weight: 500; margin: 10px 0; color: green; }
    input { padding: 8px; font-size: 16px; width: 100px; }
    button { padding: 8px 16px; cursor: pointer; font-size: 16px; }
    .error { color: red; }
    .success { color: green; }
    .warning { color: orange; }
  </style>
</head>
<body>
  <h1>Range Overflow & Underflow Validation</h1>
  Nhập số 0-20: <input type="number" id="numInput" min="0" max="20" step="1" />
  <button id="checkBtn">KIỂM TRA</button>
  <h3> Nhấn nút để kiểm tra số có trong khoảng 0-20 không </h3>
  <div class="result" id="result"></div>
  <script>
    const resEle = document.querySelector("#result");
    const numEle = document.querySelector("#numInput");
    
    document.querySelector("#checkBtn").addEventListener("click", () => {
      const validity = numEle.validity;
      resEle.className = "result"; // Reset class
      
      if (validity.rangeOverflow) {
        resEle.innerHTML = '❌ Số vượt quá tối đa (max=20)';
        resEle.classList.add('error');
      } else if (validity.rangeUnderflow) {
        resEle.innerHTML = '❌ Số nhỏ hơn tối thiểu (min=0)';
        resEle.classList.add('error');
      } else if (validity.stepMismatch) {
        resEle.innerHTML = '⚠️ Số không khớp step (step=1)';
        resEle.classList.add('warning');
      } else if (validity.badInput) {
        resEle.innerHTML = '❌ Dữ liệu không phải số hợp lệ';
        resEle.classList.add('error');
      } else if (validity.valid) {
        resEle.innerHTML = '✅ Số nằm trong khoảng cho phép';
        resEle.classList.add('success');
      } else {
        resEle.innerHTML = 'Trạng thái khác: ' + JSON.stringify(validity);
      }
      
      // Debug: hiển thị tất cả validity flags
      console.log('ValidityState:', validity);
    });
    
    // Real-time validation
    numEle.addEventListener('input', () => {
      numEle.setCustomValidity(''); // Clear custom error
      if (numEle.validity.rangeOverflow) {
        numEle.setCustomValidity('Số không được lớn hơn 20');
      } else if (numEle.validity.rangeUnderflow) {
        numEle.setCustomValidity('Số không được nhỏ hơn 0');
      }
      numEle.reportValidity(); // Show browser native UI
    });
  </script>
</body>
</html>

Kết quả

  • Nhập 25 → ❌ Số vượt quá tối đa (max=20)
  • Nhập -5 → ❌ Số nhỏ hơn tối thiểu (min=0)
  • Nhập 10 → ✅ Số nằm trong khoảng cho phép
  • Nhập 10.5 (step=1) → ⚠️ Số không khớp step

Validation API Methods:

// Kiểm tra form/input hợp lệ
form.checkValidity();     // true/false, không hiển thị UI
form.reportValidity();    // true/false, HIỂN THỊ browser native UI

// Input level
input.checkValidity();
input.reportValidity();
input.setCustomValidity("Custom error message"); // Set custom error
input.validationMessage; // Lấy message hiện tại

CSS Pseudo-classes cho validation:

input:valid { border-color: green; }
input:invalid { border-color: red; }
input:required { /* required fields */ }
input:in-range { /* trong min-max */ }
input:out-of-range { /* ngoài min-max */ }
input:read-only / :read-write { /* readonly state */ }

Tắt validation mặc định browser:

<form novalidate> ... </form>
// Hoặc
input.addEventListener('invalid', e => e.preventDefault());

Lưu ý: Validation API chỉ hoạt động trên <form> và các <input>, <select>, <textarea> có ràng buộc (required, min, max, pattern...).