Frudy
6k
2020-10-11 00:54:51 작성 2020-10-11 11:32:02 수정됨
6
1038

Input 태그 너무 힘드네요이


딱 작년에 jsp로 웹사이트 만들 때, input태그에서 숫자만 입력가능하게 하는것때문에 고생을 해서,

그당시에 꽤 많은 고민을 했지만 해결하지못한적이 있었어요.

(keyDown, onInput, keyUp이었나 3개 이벤트 공부해서 열심히 도전해봤었는데 실패...)



지금은 react로 웹사이트 만드는데 그당시 해결하지못했던걸 지금 동일하게 겪고있어요.

오늘 딱 4시간 고민했으나 해결은못했네요 ㅎㅎ ㅠ


삽질 다시 멈추고,

요구조건부터 다시 명확히 설계하고 하나씩 조건을 맞춰봐야지 했는데 벌써 토요일이 지났네요.


제가 만들려고하는 입력박스 컴포넌트의 조건은 이래요.


1. (권장) 모바일의 경우 입력박스에 포커스 맞춰지면 키보드 올라오죠? 이 때 다른 키보드 말고 숫자키보드가 올라오면 좋겠어요.

2. (필수) 숫자만 입력시킬지, dot(소수점), -(음수기호)도 입력에 포함할지 말지를 선택할 수 있는 기능이 있어야해요.

+ 소수점은 최대 1개, 음수기호는 반드시 맨앞에만 입력이 되야해요.


3. (필수) 최대 입력가능 정수자릿수, 최대 입력가능 소수자릿수를 설정할 수 있는 기능이 있어야해요.


4. (권장) 입력박스에 입력된걸 다 지웠을 때 아무것도 없어야해요. (어떤사이트는 다지우면 0나오던데, 아마 빈문자열을 Number타입으로 바꿔서 0나오게 된거일거에요)


5. (필수) 숫자를 굉장히 크게 입력했을 때 생기는 버그도 조심해야해요.

입력값을 바로바로 Number타입으로 변환해보니 굉장히 큰수를 입력했더니

2.13e+18이었나 이런거 나오더라구요 당연히 이럴 수 밖에 없죠.


6. (필수) 한글을 입력했을 때에도 동일하게 작동되야해요.

input type number로 설정해놓고 입력하다보면 자꾸 영어입력할때는 의도대로 입력이 안되는데

한글로 입력하면 event객체부터가 좀 납득이안되는걸로 전달이 되더라구요. 그래서 버그생겨요.

이건 원인을 모르겠어요. 버그케이스 확보좀 하려구요.


그리고 만들어야하는 함수도 한가지 있어요.

/**
* @param value
* @param meanNumberValue value가 숫자값을 의미하는지 여부
* "0123" 이게 숫자값을 의미하면 "123"으로 바꿔야하는데
* "123.0" 이게 숫자값을 의미하면 "123"으로 바꿔야하는데,
* "01012341234"처럼 숫자로만 이루어진건데 숫자값을 의미하지않으면 바꾸지말아야해요.
*/
declare function change(value: string, meanNumberValue: boolean): string;


처음에는 이걸 입력 할 때 캐치하려고 해봤는대요,

"123" 상태에서 소수입력하려고 "123." (123 dot) 입력해봤더니

"123"에서 "123."으로 안바뀌는거있죠, 123dot을 숫자로 바꾸니 123이 되니까요.


입력할 때 말고 제출할 때 숫자로 바꾸는 방법으로 가려구요.


작성된 주석만큼만 동작하는 함수 만드는건 어렵지않은데,

저기서 또 생각하지못한 부분이 있을지 고민중이에요.


최소한 1개의 교훈은 얻었어요.

입력할때마다 숫자로 바꿔서 input의 value attribute에 넣지는 않을거에요. 제출할때만 숫자로 바꿀거에요

위처럼 고려해야하는 버그와, 안돌아가는 기능이 너무많더라구요.

(자꾸 123dot ==> 123으로 되서 123.1 입력할수가없는)


하지만 1번 조건이 제일 어렵네요.

input type number attribute를 number로 하지않고도

모바일에서 숫자 키패드를 띄우는 방법이 존재할지는 내일 찾아볼거에요.. 


그치만, 당장 다음주 월요일에 실무에 적용을 해야하니,

조건 몇개는 타협해서 적용하고 추후에 수정하는걸로 가야겠어요.

더 중요한거 개발도 해야하고.. 애초에 저렇게 디테일하게 고객이 요구하지도 않았으니..

(사실 저거 다 제 욕심이에요)

0
  • 댓글 6

  • José Antonio Reyes
    484
    2020-10-11 02:44:17

    1,2,3중에 하는 회으를 통해 뺄수있을거 같습니다만..

  • ISA
    3k
    2020-10-11 11:30:51

    그냥 리액트니까 이벤트 헨들링 온체인지 벨류를 정규식으로 dot이랑 넘버만 받도록 걸러주면 되는거 아닌가요? 그걸 세부 조건주는게 다 아닌가 마지막 타입 넘버일때는 잘모르겠네요. 꼼수로 온체인지 일어날때 타입을 바꾸는 방식으로 가능하다면 가능할거 같은데

  • Frudy
    6k
    2020-10-11 11:36:34 작성 2020-10-11 11:37:52 수정됨

    그냥 리액트니까 이벤트 헨들링 온체인지 벨류를 정규식으로 dot이랑 넘버만 받도록 걸러주면 되는거 아닌가요?

    //

    네 그런 방식으로 dot 최대1개, 숫자만, -은 제일 앞에만 오도록 구현 방식으로 생각을 이어나가고있어요.


    꼼수로 온체인지 일어날때 타입을 바꾸는 방식으로 가능하다면 가능할거 같은데

    //

    타입을 바꾸지않고 문자열 그대로 가려고 해요.

    처음에는 입력될때마다 Number()로 문자열 ==> 숫자로 바꿨는데,


    "123"입력하고 dot입력하는순간, "123dot"이 123으로 바뀌기 때문에..

    (123dot은 숫자로 바꾸면 123이 맞긴하죠)

    타입은 안바꾸는 방식으로 가려고 가닥을 잡고있어요.


    자꾸 123dot이 123으로 바뀌면, 123.123 이런값은 절대 입력못하거든요.

    123에서 소수값입력하려고 dot 입력하는거 전부 다시 123으로 바뀌니까요.

  • ISA
    3k
    2020-10-11 11:47:01

    Frudy //

    ParseInt하면 숫자 아닌걸 만나면 거기서 컷해버려요.

    Parsefloat로 소수 될거 같기도 한데..

    그리고 큰수 문제는 bigint라는 자료형이 원래 지원 안해주다가 에크마8인가 에서 생겼어요. 그걸로 해결...? 될듯 아니면 맥시멈을 잡으시는기

    글고 답글 달때는 추천으로 신호좀 보내주세요. 알람기능 고장 났는지 알람이 안뜹니다. 고럼 이만

    화이팅

  • Frudy
    6k
    2020-10-11 11:56:18

    ISA

    //

    Number, parseInt, parseFloat 3개 전부 동일하게,


    123. 까지만 입력하면 123으로 되요.

    사용자 입장에서는 123.123을 입력하고싶은데 123.부터 막혀요 


    그래서 저는 입력할때마다 숫자로 변환하려는 생각 자체를 포기했어요.


    입력할때마다 숫자로 변환하려는 생각을 포기하면,

    1. 큰 수 문제도 안생기고요,

    2. 위처럼 "123dot"같은 문제도 절대 생기지 않고요,

    3. 기타 본문에서 언급한 문제가 거의 생기지않아요.


    그냥 제출할때만 "123."이라고 입력된 상태로 제출하려고 한다면 이거만 123으로 바꾸면되죠오


    그대신 이 방법도 단점이 있어서 ㅋㅋㅋ ㅠㅠ

    좀더 고민해보겠슴니다.

  • DevMiddleStone
    8
    2020-10-11 22:58:38

    Global 오브젝트에 있는 isNaN함수와 Number 오브젝트를 잘 활용해보세요.

    isNaN("123") // false
    isNaN("123.") // false
    isNaN("-123") // false
    isNaN("123.123") // false
    
    isNaN("1-23") // true
    isNaN("1.2.3") // true
    isNaN("1.2a3") // true
  • 로그인을 하시면 댓글 을 등록할 수 있습니다.