소수점 둘째자리만 입력 가능하도록 제한하기 (IE)

2020. 5. 7. 19:00[개발] 지식/JavaScript

Input 요소의 validation이 제일 골치아프다

보통 크롬을 지원하는 시스템이라면, 좀 더 손쉽게 처리할 수 있지만
IE를 지원해야하는 경우 문제가 생각보다 복잡해진다.
max-length, min-length 등의 속성도 지원되지 않을 뿐만 아니라 key 이벤트 내에서 전달받는 값도 다른 브라우저와 상이하기 때문이다. 여기서 사용하는 방법은 IE를 기준으로 한다. 크롬은 찾아보면 더 좋은 방법이 많이 나올 것이다.

이벤트 발생 순서

일단 key 관련 이벤트 들의 트리거 순서를 알 필요가 있었다.
key를 입력했을때
keydown -> keypress -> input -> keyup
key를 지울때
keydown -> input -> keyup
순서로 발생했다.

input event?

replace 처리를 할때, 입력됐다가 지워지는 모습이 보이는게 싫어서 input event를 활용했다.
keypress 이벤트에서 처리하면 애초에 입력이 되지 않지만, 입력되기 전에 발생하는 이벤트이기 때문에 입력된 전체 문자열을 받을 수 없는 문제점이 있었다.
그렇다고 keyup 이벤트에서 replace 처리를 하자니, 입력됐다가 지워지는 모션이 보기가 싫었다.
input 이벤트는 그 사이에 발생하는 이벤트로써, 글자가 input 요소에 입력되기 전이기 때문에 입력 자체를 막을 수 있었다.
또 한가지 중요한 것은 copy&paste 입력도 감지하여 막을 수 있다는 점이다.
하지만 입력된 keyCode는 이벤트 객체에서 가져올 수 없는 문제도 있었다.

이벤트 하나로는 해결할 수 없다

IE에서 이를 처리하기 위해서 이벤트 하나로 깔끔하게 처리한다는 것은 포기했다.
다만 이벤트를 여러개 사용하고, 기능을 분산시키는 찝찝함이 있었지만 잘 조합한다면 상당히 깔끔한 처리를 할 수 있을거라 생각했다. keyup은 제외하고 input과 keypress를 사용하여 1차적인 입력제한을 구현했으며, blur 이벤트로 예외 케이스들을 처리했다.

구현

먼저 트리거되는 keypress 이벤트에서는 keyCode를 활용해 숫자키와 .(마침표) 입력만 받도록 제한한다.
input 이벤트에서 정규식을 사용해서 '정수.정수2자리' 패턴에 맞지 않는 입력값은 replace를 통해 입력을 취소했다.
정확히말하면 취소한게 아니라 다시 지운셈이다.
마지막으로 blur 이벤트에서 .(마침표)가 맨 앞에 오거나 맨 뒤에 오는 케이스를 제거했다.
이를 blur에서 처리한 이유는 input에서 처리하려고 한다면 .(마침표)을 찍는 순간 마지막에 .이 들어간 셈이므로 validation에 걸려버리기 때문이다. blur에서 마무리하는게 생각보다 깔끔하고 상식적이었다.

SOURCE CODE

// .(마침표)가 양끝에 있는 케이스를 처리, 입력값을 Slider에 적용
$j('#searchPopupWrapper input').off('blur').on('blur',function(e){

    var value = $j(this).val();
    var regExp = /^\.|\.$/;
    if(regExp.test(this.value)){
        $j(this).val(value.replace('.',''));
    }

});

// 소수점 둘째자리까지의 실수만 입력 허용
$j('#searchPopupWrapper input').off('input').on('input',function(e){

    var value = $j(this).val();
    var regExp = /^\d*.?\d{0,2}$/;
    if(!regExp.test(this.value)){
        $j(this).val(value.substring(0,value.length-1));
    }

});

// 숫자와 .(마침표)만 입력 허용
$j('#searchPopupWrapper input').off('keypress').on('keypress',function(e){

    e = e || window.event;
    var charCode = e.which || e.keyCode;
    // var charStr = String.fromCharCode(charCode);
    if (!((charCode >= 48 && charCode <= 57) || charCode === 46)){
        return false;
    }

});

별거 아닌 기능같지만

IE에서 구현하는게 생각보다 까다로웠다.
아직 완벽하게 이벤트의 특성과 종류 그리고 동작방식에 대해 파악한 것은 아니다.
이후에는 key 이벤트를 분석해서 다른 종류의 validation 구현시 도움이 되도록 할 예정이다.

'[개발] 지식 > JavaScript' 카테고리의 다른 글

focusin/focusout, focus/blur의 차이  (0) 2020.05.07
문자열 프로토타입 메서드  (0) 2019.05.06
문자열 생성자 메서드  (0) 2019.05.06
문자열로 이루어진 배열에 join  (0) 2019.05.06
iframe 로딩 확인  (0) 2018.11.22
<