HTML 입력 유효성(input validity) with Javascript

RYU·2022년 11월 19일
4

HTML

목록 보기
3/3

Prologue

우리는 회원 가입과 로그인 같은 어떠한 신청 폼을 작성할 때 필수 입력 사항에 대한 알림 메세지가 표시되는 것을 자주 볼 수 있다. 이러한 화면을 구현하기 위해 내부적으로는 유효성 검사라는 것을 하게 되는데, 이는 사용자가 폼 페이지에서 입력한 데이터 값이 서버로 전송되기 전에 특정 규칙에 맞게 입력되었는지 검증하는 것을 말한다.

이렇게 개발자의 입장에서는 반드시 받아야 할 데이터들의 입력 정보 화면을 구현했지만, 사용자에 의해 맞지 않는 형식으로 입력되었거나 혹은 아예 입력되지 않았을 경우 불필요한 서버로의 데이터 전송에 대비하기 위해 자동으로 필수 입력값들을 입력하도록 요구하는 기능을 사용할 수 있다.

이번 글에서는 별도의 자바스크립트 구현없이도 사용자가 입력한 값이 올바른지 체크하는 방법에 대해서 알아보고, 자바스크립트 기능을 더하여 사용자의 데이터 입력에 문제가 있을 시 해당되는 에러메세지를 다루는 법에 대해서도 알아보자.


Contents


💻 HTML 기능 사용

첫번째로, 별도의 자바스크립트 없이도 html의 input 태그 속성을 추가해주는 것만으로도 간단하게 구현하는 방법이 있다.

아래 코드는 기본적으로 우리가 html 문서에서 <form><input>을 사용하여 로그인시 필요한 이메일과 비밀번호를 입력받는 양식을 만드는 방법이다.

<form action="">
      <div>
        <label for="email">이메일</label>
        <input type="email" name="" id="email"/>
      </div>
      <div>
        <label for="pw">비밀번호</label>
        <input type="password" name="" id="pw"/>
      </div>
      <button type="submit">로그인</button>
    </form>
    <br />

하지만 이렇게 작성할 경우 사용자가 입력칸을 비워둔채로 로그인 버튼을 눌렀을 때, 별도의 필수 입력 사항에 대한 알림 메세지가 화면에 표시되지 않는다.

반드시 받아야 할 데이터라면 필수로 form field를 채워야 하는지에 대한 지시가 필요할 것이다. 이를 해결하기 위해 우리는 <input> 의 required 속성을 추가할 수 있다.


🔎 required 속성

<input type="email" name="" id="email" required/>
<input type="password" name="" id="pw" required/>

required는 값이 입력되지 않았거나 check / select 되지 않은 경우 브라우저에 있는 기본 알림 메세지를 표시하게 된다.

required 속성은 text, search, url, tel, email, password, checkbox, radio, date pickers, number, file 과 같은 입력 유형과 함께 작동할 수 있다.

  • radio 입력 유형

  <body>
    <form action="">
      <div>
        <strong>성별</strong><br/>
        <input type="radio" name="gender" value="female" required />여성
        <input type="radio" name="gender" value="male" required />남성
      </div>
      <button type="submit">저장</button>
    </form>
  </body>

성별을 선택하는 radio 양식 중에 여성과 남성 둘 중 아무것도 선택하지 않았을 때에도 브라우저에서 제공하는 위와 같은 알림 메세지가 표시되게 된다.

  • checkbox 입력 유형

  <body>
    <form action="">
      <div>
        <input type="checkbox" name="" required /> 수량 선택 <br/>
        
        <select name="" required>
          <option value="" selected>선택하세요.</option>
          <option value="">1</option>
        </select>
      </div>
      <button type="submit">저장</button>
    </form>
  </body>

정보를 체크해야 될 항목이 있는 checkbox 양식에서 아무것도 체크하거나 선택하지 않을 때 역시나 기본 브라우저에서 제공하는 위와 같은 알림 메세지가 표시되게 된다.


🔎 추가적인 속성들

HTML5에서는 required 속성 이외에도 데이터의 유효성을 검사하는데 도움이 되는 여러 속성들을 제공한다.

  • type : 데이터 유형을 제한하는 속성으로, 입력 요소가 나타낼 타입을 명시한다. input 요소의 필수 속성은 아니지만 항상 명시하는 것이 좋다.
사진 : <input type="file" name="myfile">
이메일 : <input type="email" name="ccaddress" multiple><br/>
(email type을 명시하면 입력값에 @가 필수로 들어가도록 제한하게 된다.)
  • minlength, maxlength : text 입력값을 받을 때 사용할 수 있고, 데이터의 길이를 제한한다.
비밀번호 : <input type="password" minlength="4" maxlength="12">
(사용자로 하여금 비밀번호를 최소 4자, 최대 12자까지만 입력하게 한다.)
  • min, max : 입력 요소의 최소, 최대값을 명시한다.
    동작할 수 있는 type 속성값은 date, datetime, datetime-local, month, number, range, time, week가 있다. (숫자/날짜)
생년월일 : <input type="date" name="birthday" min="1900-01-01" max="2019-01-01"><br/>  
학년 : <input type="number" name="grade" min="1" max="4">
  • pattern : 데이터 패턴을 지정하는 속성으로, 입력된 양식 데이터가 일치해야 하는 정규식 패턴을 지정한다.
전화번호 : <input type="tel" id="tel" pattern="010-\d{4}-\d{4}$" required/>
(010으로 시작하고 4자리-4자리 숫자로 이루어진 패턴을 충족해야하는 전화번호 정규표현식이다.)

Sample

📱 아래 페이지에서 required 속성 유무에 따른 실제 동작의 차이를 확인해보세요.


💻 Javascript와 함께 사용

위의 내용을 통해 HTML5가 가지고 있는 속성들로 자바스크립트 코드를 구현하지 않고도 훨씬 강력한 기능을 만드는 방법이 있음을 알 수 있었다.
이에 더하여 보다 복잡한 유효성 검사가 필요하거나 자세한 오류 메세지를 제공하려는 경우 자바스크립트의 기능과 함께 사용 가능한 방법에 대해서도 알아보자.

🔎 onsubmit

<form>에서 작동하는 submit은 폼 핸들러로 폼에 입력된 데이터를 전송하는 역할을 한다. 그리고 입력된 데이터가 없거나 잘못 입력되었어도 submit을 누르면 폼 핸들러로 전송하게 된다. 이렇게 상당수 이벤트는 발생 즉시 브라우저에 의해 특정 동작을 자동으로 수행하는데, 폼 전송 버튼을 클릭하면 서버에 폼 데이터가 전송되고 페이지가 리로드 되는 경우도 이에 해당된다.

하지만 이런 브라우저 기본 동작 대신에 직접 동작을 구현하려고 한다면, 브라우저 기본 동작을 취소할 수 있는 방법은 없을까?

이 때, <form>onsubmit를 사용하면 submit 이벤트가 실행되기전에 어떠한 동작이나 기능을 실행시킬 수 있다.

<form action="" onsubmit="login()">

onsubmit는 양식 제출 이벤트가 발생할 때의 동작을 지정한다.
이벤트 발생과 action이 작동되는 그 사이의 시점에 처리할 동작 (일반적으로 자바스크립트 함수를 지정)을 설정할 수 있다.

그리고 이와 함께 추가적으로 preventDefault()를 사용하면 된다.

<script>
  function login() {
    event.preventDefault();
    const email = document.querySelector("#email").value;
    const pw = document.querySelector("#pw").value; 
}
</script>

event.preventDefault()는 이벤트의 기본 동작 기능을 중지한다.
submit의 경우 input 입력값을 전송한 뒤 페이지가 새로고침 되는것이 default 동작이다.

Sample

📱 아래 페이지에서 event.preventDefault() 유무에 따른 실제 동작의 차이를 확인해보세요.

event.preventDefault() 사용 X
데이터를 입력하고 로그인 버튼을 클릭했을 때, 실제 브라우저에서는 페이지가 새로고침 되고 입력했던 데이터도 초기화되어 화면에서 사라진다.

event.preventDefault() 사용 O
데이터를 입력하고 로그인 버튼을 클릭했을 때, 브라우저 기본 동작인 새로고침을 멈추고 입력했던 입력값도 그대로 화면에 유지되는 현상을 볼 수 있다.

이렇게 <form>를 사용하지만 실제 submit은 작동하지 않도록 하면서 불필요한 데이터를 서버로 전송하지 않기 때문에, 보통 폼 데이터 전송 직전에 <form>에 입력된 데이터들의 유효성을 검사하기 위해 사용하게 된다.


🔎 constraint validation API

보다 복잡한 유효성 검사를 원하거나 사용자 경험을 직관적으로 만들어줄 수 있는 자세한 오류 메세지를 제공하려는 경우, <form> 없이도 HTML5의 Constraint Validation API와 같은 내장함수를 활용하여 구현해볼 수 있다.

이 API에서 제공하는 일부 method는 다음과 같다.

  • checkValidity() : required를 만족하는지를 체크한다. 만족하지 않는 경우 invalid event가 발생하여 valid 값을 반환한다.
  • setCustomValidity() : required 알림 메세지를 조건에 맞게 변경할 수 있다.
  • reportValidity() : valid 값을 확인하여 valid가 false인 경우 invalid event가 발생하여 valid 값을 반환한다.
    setCustomValidity로 설정한 메세지를 사용자에게 보여준다. (이는 브라우저의 기본 동작으로 형태나 지속 시간등을 제어할 수는 없다.)

그리고 유용한 property는 다음과 같다.

  • validity : ValidityState를 나타내는 객체를 뜻한다.
  • validationMessage : 브라우저 기본 메세지 (ex. 이 입력란을 작성하세요) 등을 alert창으로 표시한다.
  • willValidate : HTML요소가 검증 후보인지 여부를 체크한다.

실제 코드에서는 어떻게 동작하는지 아래 예시와 함께 적용해보자.

    <script>
      function login3() {
        const email = document.querySelector("#email3");
        const pw = document.querySelector("#pw3");
      
        // 만약 email을 입력하지 않아 false라고 한다면,
        if (!email.checkValidity()) {
          return alert(email.validationMessage);
        // validationMessage을 사용해 브라우저 기본 메세지를 alert창으로 표시할 수 있게 한다.
        }
		// 만약 password를 입력하지 않아 false라고 한다면,
        if (!pw.checkValidity()) {
          return alert(pw.validationMessage);
        // validationMessage을 사용해 브라우저 기본 메세지를 alert창으로 표시할 수 있게 한다.
        }
      }
    </script>

하지만 alert 메세지창으로 메세지를 띄우게되면, 위 사진과 같이 어떤 입력 양식 부분에 대한 안내 메세지인지 구별하기가 어렵다는 문제점이 생긴다. 이를 해결하기 위해 기본적으로 보여지는 alert 창의 메세지를 변경할 필요가 있다.

html로 작성한 input 양식 코드에 oninvalid 속성으로 속성값엔 해당 함수로 setCustomValidity()를 사용하여 변경한 에러메세지를 넣어줄 수 있다.

<div>
	<label for="email">이메일</label>
	<input type="email" name="" id="email3" required />
</div>
<div>
	<label for="pw">비밀번호</label>
  	<input 
    	type="password" 
    	name=""
    	oninvalid="this.setCustomValidity('비밀번호를 입력하세요.')"
    	id="pw3"
    	required/>
</div>
<button onclick="login3();">로그인</button>

메세지 변경이 가능한 내장함수를 이용해서 사용자에게 좀 더 친절하고 직관적인 alert 창을 보여줄 수 있게 되었다.
alert 메세지창의 문제점 이외에도 각 input값 에러의 종류에 따라 브라우저마다 자체적으로 에러 메시지를 다르게 보여주는데, 이 메시지를 변경하고 싶을 때에도 setCustomValidity()로 입력 요소에 내가 원하는 메시지를 지정하면 된다.

Sample

📱아래 페이지에서 형식에 맞지 않는 값을 입력해보고, alert 메세지창의 동작을 확인해보세요.


Epilogue

개발을 공부하고 있는 우리도 수 많은 서비스의 사용자 입장이 될 수 있는만큼, 무언가 잘못 입력되고 있거나 놓치고 있을 때 좋은 사용자 경험을 줄 수 있는 화면을 구현하여 제공하는 것은 중요하다고 생각한다. 다행스럽게도 꽤 훌륭한 유효성 검사 기능이 오늘날의 모든 브라우저에서 내장되어 지원되고 있다. 이번 글을 통해서 학습한 입력 유효성을 위한 기능들을 뼈대로 삼아 어떤 방식으로 커스텀해나가야 사용자에게 더 실용적으로 다가갈 수 있을지에 대해서도 고민해보면 좋을 것 같다.

📚 참고한 사이트들

https://ko.javascript.info/default-browser-action
https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation
https://developer.mozilla.org/en-US/docs/Web/API/Constraint_validation
https://pageclip.co/blog/2018-02-20-you-should-use-html5-form-validation.html
https://www.youtube.com/c/%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98%ED%92%88%EA%B2%A9/featured (개발자의 품격)

profile
Rome wasn't built in a day ✍🏻

0개의 댓글