<input
ref={priceRef}
name="price"
type="text"
placeholder="가격(선택사항)"
maxLength="12"
onKeyDown={handlePrice}
onChange={priceModify}
/>
저는 onKeyDown과 onChange를 같이 설정하였습니다.
(스타일링은 아직 안 했습니다...ㅎㅎ)
const handlePrice = (event) => {
if (
(event.keyCode > 47 && event.keyCode < 58 ||
event.keyCode === 8 || //backspace
event.keyCode === 37 ||
event.keyCode === 39 || //방향키 →, ←
event.keyCode === 46 //delete키
) {
return;
} else {
event.preventDefault();
}
};
keyDown: 숫자와 backspace, 방향키, delete키를 제외한 다른 키가 눌리면 이벤트를 처리하지 않습니다. 하지만 여기서 문제점은 영문에서는 키를 눌렀을 때 이벤트가 잘 막아지지만 한글에서는 안 막아진다는 것이었습니다. 그래서 저는 onChange도 같이 설정해 주었습니다.
값이 바뀔 때 input value를 바꿔주면 되겠다는 생각이 들어서 onChange를 사용하였습니다.
keyUp을 사용해볼까 고민도 해보았지만 keyUp을 하면 keyDown에서 막았던 문자들이 같이 들어와서 사용하지 않았습니다.
let data = event.nativeEvent.data; // 어떤 값이 들어왔는지
let value = priceRef.current.value; // 현재 input의 전체값을 받아온다
// 받아온 값이 숫자일 경우 쉼표만 제대로 맞춰주면 된다
if (data >= 0 && data <= 9) {
let onlyNumber = Number(value.replaceAll(',', ''));
const formatValue = onlyNumber.toLocaleString('ko-KR');
priceRef.current.value = formatValue; // input value 변경해주기
} else { // 숫자가 아닌 경우에는 들어온 문자만 지워준다.
let priceExp = /^[,0-9]/g;
if (!priceExp.test(data)) {
const formatValue = value.replaceAll(/[^,0-9]/g, '');
priceRef.current.value = formatValue; // input value 변경해주기
}
쉼표 넣기는 간단하게 이 코드만 하셔도 되지만 문제점이 있습니다.
숫자를 입력했지만 마음이 바뀌어 input을 비어있게 하고 싶어서 backspace 키를 눌렀지만 input이 비지 않고 0으로 남습니다.
data가 null이면 else에 걸려야 하는 것 아닌가?! 싶었는데....
data가 null일 때
data >= 0 && data <= 9
에서 true
가 나왔습니다!!
뭐지 이 점에서는 따로 다뤄봐야겠습니다...ㅠ
data === 0
은 false
로 나오므로
data === '0' || (data > 0 && data <= 9)
로 고치면 될까 싶었는데
흠...
우선 data === 0
이 아닌 data === '0'
을 쓴 이유는 data는 문자입니다. ===은 형식도 확인하기 때문에 형식을 맞춰줘야 true가 나올 수 있죠.
==는 값만 다루기 때문에 data == 0
을 쓴다면 true로 나온답니다!!ㅋㅋ
어쨌든 이 방법은 backSpace도 null로 처리하기 때문에 else문으로 넘어가네요ㅋㅋㅋㅋ
그래서 value가 빈 값일 때 return을 시켜주는 방법을 택했습니다.
if (value === '') {
return;
}
const priceModify = (event) => {
let data = event.nativeEvent.data;
let value = priceRef.current.value;
if (value === '') {
return;
}
if (data >= 0 && data <= 9) {
let onlyNumber = Number(value.replaceAll(',', ''));
const formatValue = onlyNumber.toLocaleString('ko-KR');
priceRef.current.value = formatValue;
} else {
let priceExp = /^[,0-9]/g;
if (!priceExp.test(data)) {
const formatValue = value.replaceAll(/[^,0-9]/g, '');
priceRef.current.value = formatValue;
}
}
};
이렇게만 하시면 화면상으로는 잘 되실 겁니다!
순수js에서도 getElementById 등등 이용해서 바꿀 수 있을 듯 하네요..(예상)
저는 리액트를 사용해서 state값을 업데이트를 해주어야하기 때문에 위 코드에서 set해주는 함수도 추가하하고 이것저것 했네요 ㅎㅎ