개발노트/JavaScript

[JavaScript] 값 제어하기 - 숫자만 입력받기

dev-mylee 2025. 1. 7. 13:12

오늘 개발하다가 input에서 숫자만 입력받는 부분에서 한참 삽질했다.

평소엔 별거 아닌 것 같은데 보통 이런 게 더 귀찮... 😩

다음에 또 삽질하기 싫어서 정리해둠!

 

1. 기본: 숫자만 입력

처음에는 단순하게 했다:

function onlyNumber(input) {
    input.value = input.value.replace(/[^0-9]/g, '');
}

 

근데 이러면 안 되는 것들:

  • 소수점(.) 입력 불가능
  • 음수(-) 입력 불가능
  • 콤마(,) 입력 불가능
  • maxlength 걸어도 복붙하면 통과됨 😱

 

 

2. 실전에서 쓸만한 버전

function controlNumber(input, options = {}) {
    let value = input.value;
    
    // 1. 옵션 설정
    const config = {
        allowDecimal: options.allowDecimal || false,
        allowNegative: options.allowNegative || false,
        maxLength: options.maxLength || null,
        maxValue: options.maxValue || null
    };
    
    // 2. 입력값 정제
    if(config.allowDecimal && config.allowNegative) {
        // 소수점, 음수 모두 허용
        value = value.replace(/[^-0-9.]/g, '');
    } else if(config.allowDecimal) {
        // 소수점만 허용
        value = value.replace(/[^0-9.]/g, '');
    } else if(config.allowNegative) {
        // 음수만 허용
        value = value.replace(/[^-0-9]/g, '');
    } else {
        // 숫자만 허용
        value = value.replace(/[^0-9]/g, '');
    }
    
    // 3. 소수점 중복 방지
    if(config.allowDecimal) {
        const points = value.match(/\./g);
        if(points && points.length > 1) {
            value = value.substring(0, value.lastIndexOf('.'));
        }
    }
    
    // 4. 음수 부호 위치 보정
    if(config.allowNegative) {
        // - 기호가 중간에 있으면 앞으로 이동
        value = value.replace(/(.+)(-+)(.*)/, '-$1$3');
        // - 기호 중복 제거
        value = value.replace(/--+/, '-');
    }
    
    // 5. maxLength 처리 (복붙할 때도 적용되게)
    if(config.maxLength) {
        value = value.slice(0, config.maxLength);
    }
    
    // 6. maxValue 체크
    if(config.maxValue && Number(value) > config.maxValue) {
        value = String(config.maxValue);
        alert('최대값을 초과했습니다.');  // 이런 alert는 실무에선 toast나 다른걸로 교체
    }
    
    input.value = value;
}

 

 

 

3. 실제 사용법

<!-- 1. 기본 (숫자만) -->
<input type="text" 
       oninput="controlNumber(this)"
       placeholder="숫자만 입력">

<!-- 2. 소수점 허용 -->
<input type="text" 
       oninput="controlNumber(this, {allowDecimal: true})"
       placeholder="소수점 입력 가능">

<!-- 3. 음수 허용 -->
<input type="text" 
       oninput="controlNumber(this, {
           allowNegative: true,
           maxLength: 5
       })"
       placeholder="음수 입력 가능">

<!-- 4. 최대값 제한 -->
<input type="text" 
       oninput="controlNumber(this, {maxValue: 100})"
       placeholder="100까지만 입력 가능">

 

 

 

✅ 메모

  1. 정규식 테스트는 꼭 하자
    • 이거 테스트 안 하고 올렸다가 큰일날 뻔...
    • https://regexr.com/ 여기서 테스트하면 편함
  2. 음수 처리할 때 주의
    • '-'가 중간에 들어갈 수 있음
    • '--' 이렇게 중복으로 들어갈 수도 있음
    • 다 막아야 함
  3. maxLength 속성만으로는 부족
    • 복사/붙여넣기하면 통과됨
    • JavaScript에서 한 번 더 체크해야 안전
  4. 실수했던 것들
    • alert 남발... (사용자 경험 나쁨)
    • 소수점 중복 체크 안 함
    • 음수 부호 위치 제대로 안 잡음
    • maxValue 체크 안 함