logo
Posts예외 처리Input 태그 숫자 입력 제한

Input 태그 숫자 입력 제한

이번 글에서는 input 태그에 숫자만 입력할 수 있도록 제한하는 방법에 대해 알아보겠습니다.

일반적으로 HTML input 태그에 type="number" 속성을 사용하면 숫자만 입력할 수 있을 것 같지만, 이 속성은 사용자가 입력한 값이 숫자인지 확인할 뿐, 입력 제한을 완전히 막지는 않습니다. 또한 다음과 같은 문자들도 입력이 가능합니다.

  • e: 지수 표기법으로 사용 가능
  • .: 소수점 입력 가능
  • +: 양수 표기 가능
  • -: 음수 입력 가능

또한, IME 입력(예: 한글)을 사용하는 경우 조합 문자가 입력될 수 있으며, 이때 입력 도중 화면에 문자가 표시될 수 있습니다.

IME (Input Method Editor): 입력기로 키보드 입력을 받아들여 다른 문자로 변환하는 프로그램을 말합니다. 한글 입력기가 대표적인 예시입니다.

이러한 모든 조건을 충족하여, 정수만 입력하도록 제한하는 코드를 작성해 보겠습니다.

HTML

다음은 예시 input 태그입니다.

index.html
<input type="number" id="numberInput" />

JavaScript

이 input 태그에 숫자만 입력할 수 있도록 제한하려면, 다음과 같이 JavaScript에서 해당 태그에 input 이벤트를 걸어 사용할 수 있습니다.

index.ts
const numberInput = document.getElementById("numberInput");
 
numberInput.addEventListener("input", (e: InputEvent) => {
	const inputElement: HTMLInputElement = e.target;
	const inputValue = e.data;
 
	const regex = /^[1-9]\d*$/g;
	if (!regex.test(inputValue)) {
		inputElement.value = null;
		inputElement.blur();
		inputElement.focus();
		return;
	}
 
	// TODO: 입력된 값이 숫자인 경우 이후 로직 작성
	// ...
});

위 코드에서는 input 태그에 input 이벤트를 등록하여, 입력된 값이 숫자인지 확인하고 숫자가 아닌 경우 입력된 값을 초기화합니다. 이후 blur()focus() 메서드를 순서대로 호출하여 IME 조합 문자를 초기화합니다.

주의사항

input 이벤트는 입력된 값이 변경될 때마다 발생합니다. 정규식을 사용할 때는 전체 값(e.target.value)이 아닌 방금 입력된 문자 하나(e.data) 만 확인하여, 불필요한 입력을 더 효율적으로 필터링할 수 있습니다.

다만, 이후 로직에서는 e.target.value 를 사용하여 전체 값을 확인해야 합니다.

정규식 설명

정규식 /^[1-9]\d*$/g 은 양의 정수만 허용하도록 설정되어 있습니다.

  • ^[1-9]: 1-9로 시작해야 합니다. (0으로 시작하는 값 제외)
  • \d*: 그 뒤에는 0개 이상의 숫자가 올 수 있습니다.
  • ^$는 문자열의 시작과 끝을 지정하여 전체가 정수 형식이어야 함을 명시합니다.

이 설정을 통해 지수 표기법, 소수점, 음수 등의 입력을 모두 제한할 수 있습니다.

Vue.js 사용 시

Vue.js 에서 v-bind를 사용하여 input 태그의 값을 바인딩하고, v-on을 사용해 input 이벤트를 수신할 수 있습니다. 이 방법을 통해 input 의 값과 이벤트를 Vue 컴포넌트 내에서 효과적으로 관리할 수 있습니다.

아래는 Vue.js의 빌트인 디렉티브축약어를 사용한 예시 코드입니다.

index.vue
<template>
	<input
		type="number"
		:value="numberInput"
		@input="onInput"
	/>
</template>
 
<script setup lang="ts">
import { ref } from "vue";
 
const numberInput = ref<number>(0);
 
const onInput = (e: InputEvent) => {
	const inputElement: HTMLInputElement = e.target;
	const inputValue = e.data;
 
	const regex = /^[1-9]\d*$/g;
	if (!regex.test(inputValue)) {
		numberInput.value = null;
		inputElement.value = numberInput.value;
		inputElement.blur();
		inputElement.focus();
		return;
	}
 
	numberInput.value = parseInt(inputElement.value);
 
	// TODO: 입력된 값이 숫자인 경우 이후 로직 작성
	// ...
};
</script>