diff --git a/.jules/palette.md b/.jules/palette.md index a1cf208b..dbbaab69 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -74,3 +74,6 @@ ## 2024-07-13 - 일괄 업로드 폼에 프리셋 버튼 및 파일 크기 미리보기 추가 **Learning:** 일괄 파일 업로드 폼에서 대상 바이트(target_bytes) 입력 필드만 제공하면 사용자가 원하는 용량을 바이트 단위로 정확히 계산하기 어려워 사용성이 떨어집니다. 사용자가 여러 파일을 업로드할 때 총 파일 크기를 파악하지 못해 업로드 제한을 초과하거나 잘못된 대상 바이트를 설정할 위험이 큽니다. **Action:** 일괄 파일 업로드 폼에도 단일 파일 업로드 폼과 동일하게 대상 바이트를 쉽게 선택할 수 있는 빠른 프리셋 버튼을 추가하고, `onchange` 이벤트 발생 시 선택된 모든 파일의 크기를 합산하여 사람이 읽기 쉬운 단위(MiB, GiB 등)로 미리보기를 제공하도록 JavaScript 로직을 개선했습니다. +## 2025-02-23 - 숫자 입력 필드 비움 상태에서의 인라인 유효성 검사 UX 개선 +**Learning:** 숫자 입력 필드에 인라인 유효성 검사를 구현할 때, 사용자가 필드를 완전히 비우면 `parseInt`가 `NaN`을 반환하여 네이티브 HTML5 필수(`required`) 검증이 작동하기 전에 커스텀 오류 메시지가 너무 빨리 나타나는 문제가 발생할 수 있습니다. +**Action:** `input` 이벤트 리스너에서 빈 문자열(`this.value === ''`)을 명시적으로 확인하고 커스텀 오류를 지워주어 기본 브라우저 유효성 검사가 먼저 작동할 수 있도록 구현합니다. diff --git a/saas_web.py b/saas_web.py index 3a7b0352..1368a7d2 100644 --- a/saas_web.py +++ b/saas_web.py @@ -255,7 +255,11 @@ async def add_security_headers(request: Request, call_next): ); }); - if (isNaN(val) || val <= 0) { + if (this.value === '') { + preview.innerText = ''; + this.setCustomValidity(''); + this.removeAttribute('aria-invalid'); + } else if (isNaN(val) || val <= 0) { preview.innerText = 'Must be greater than 0.'; preview.style.color = '#dc3545'; this.setCustomValidity('Must be greater than 0.'); @@ -282,7 +286,11 @@ async def add_security_headers(request: Request, call_next): ); }); - if (isNaN(val) || val <= 0) { + if (this.value === '') { + preview.innerText = ''; + this.setCustomValidity(''); + this.removeAttribute('aria-invalid'); + } else if (isNaN(val) || val <= 0) { preview.innerText = 'Must be greater than 0.'; preview.style.color = '#dc3545'; this.setCustomValidity('Must be greater than 0.');