프론트엔드 개발자가 고민(해야)하는 form(2)

Daniel Woo·2023년 8월 18일
0

이전 글에서는 양식 유효성 검사(form validation)를 왜 하고, 특히 프론트엔드에서는 어떤 점에 신경을 써야하는지 생각해보았다.

이전 글: 프론트엔드 개발자가 고민(해야)하는 form

이전 글을 요약하자면, 프론트엔드 양식 유효성 검사에서는 '초기 검사를 통한 우수한 사용자 경험을 제공하는 것'이 핵심이었다. 또한, 이는 다음과 같은 원리로 실현 가능하다.
1. 데이터 통신 최소화로 성능 향상
2. 상호작용에 따른 피드백을 주어 양식을 제출할 수 있도록 가이드

양식 유효성 검사

이번 글에서는 네이버 회원가입 양식을 모킹한 간단한 프로젝트를 진행하면서 관련된 기능을 자세히 알아볼 것이다. 그리고 JavaScript UI라이브러리의 스탠다드가 된 React에도 이를 적용할 수 있는지 알아보고 React를 사용하면서 얻는 이점을 분석해보려고 한다.


회원가입 양식

우선 양식 유효성 검사를 마음껏 테스트해볼 수 있을만한 템플릿을 만들기 위해 네이버 회원가입 양식을 모킹하여 아래를 만들었다.

모킹 회원가입 양식

모킹한 회원가입 양식은 다음과 같은 특징을 가지고 있다.

  • 다수의 상태(총 8개)
  • 필수, 선택 입력 구분
  • 제출(submit) 및 포커스 해제(blur)시, 유효성 검사
  • 유효성이 충족되지 않았을 경우 UI변화(테두리 및 에러메시지)
  • 모든 유효성이 만족됐을 경우에만, 서버와 통신

기본제공 양식 유효성 검사

프론트엔드 관점에서 바라보는 양식 유효성 검사 이전에 유저 데이터 및 애플리케이션 보호/보안을 신경써야한다. 잘못된 형식의 데이터는 유저뿐 아니라 애플리케이션에 치명적인 오류를 가져올 수 있기 때문이다.
따라서, 패턴에 맞지 않은 데이터 혹은 악의적으로 조작된 데이터가 서버로 제출되는 것을 막아야 한다.
사용자 친화적 관점에서 어떠한 방식으로 작성해야 성공적으로 양식을 제출할 수 있는지 가이드해주는 것은 이것이 만족되었다는 전제 하에 진행한다.

가장 먼저, 아이디 input을 작성해보자. 유효성 검사의 조건은 다음과 같다.

아이디: 5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능(필수)

이러한 유효성 검사를 위해 HTML5에서는 다양한 유효성 양식 검사를 기본적으로 제공한다.

필수, 선택 여부(required)

이메일을 제외한 나머지 input은 모두 필수로 작성해야한다. 이러한 경우에는 required라는 속성을 부여하여 양식 제출을 위해 필수적으로 기입하도록 한다.
필수 기입 오류 메시지

글자 길이 제한(minlength, maxlength)

'5~20자의' 글자제한은 minlengthmaxlength속성으로 조건을 부여할 수 있다. 만약 최소 길이 조건을 충족하지 않는다면 아래와 같은 브라우저 기본 오류 메시지가 발생한다.
최소 길이 조건 불충족 오류 메시지
또, 최대 길이 조건을 만족하지 못한 경우에는 해당 길이 이상으로 글자를 기입할 수 없다.

기입 패턴분석(pattern)

영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능이라는 복잡한 조건이 주어졌을 경우에는 정규식을 사용할 수 있는 pattern 속성을 사용하면 된다. 위 경우에서는 다음과 같은 정규 표현식을 적용했다. [a-z0-9\-_]{5,20}

placeholder

placeholder는 사용자에게 어떠한 주제에 대해 기입해야한지 실마리를 제공해주는 속성이다. 주로 input 이름이나 예시를 기입한다.

아이디에 관한 기본제공 유효성 검사가 적용된 input은 다음과 같다.

 <label for="id">
 	<input
      	id="id"
		name="id"
		type="text"
		placeholder="아이디"
		required
		minlength="5"
		maxlength="20"
		pattern="[a-z0-9\-_]{5,20}"
		title="5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다."
     	/>
</label>

위에서 알아본 속성을 각 input에 적용시키면 HTML5 속성을 이용한 기본제공 유효성 검사만으로도 나름 괜찮은 양식 유효성 검사를 만들어 낼 수 있다. 또, 이후에 진행될 JavaScript 양식 유효성 검사의 validation API를 사용할 수 있게 하는 초석을 만들어 준다.

기본제공 양식 유효성 검사(HTML5 기능)로 얻는 것
1. 클라이언트에서 체크할 수 있는 부분에 한하여 초기검사를 할 수 있다.
2. 사용자가 기입한 값이 조건을 만족하지 않는 경우, 에러메시지를 표시
3. 네트워크 요청이 없어 불필요한 자원낭비를 줄이고, 사용자 경험 향상

JavaScript 양식 유효성 검사

기본제공 유효성 검사만으로 가능한 기능 및 서비스도 있겠지만, 유저와의 다양하고 빠른 상호작용을 중시하는 현대 웹 트랜드에서는 부족함이 있다. 기본제공 유효성 검사만으로는 시각적 에러 표현, 일관된 사용자 경험 등을 챙길 수 없고, 더 높은 커스터마이징을 원할 때는 기능상 구현할 수 없기 때문이다. 이를 보완하기 위해서 JavaScript를 사용한 유효성 양식 검사를 추가적으로 진행할 수 있다.

다음은 pattern 속성에서 정의한 유효성 검사를 통과하지 못했을 때 브라우저에서 발생하는 자체 에러 메시지이다.
크롬
크롬 에러메시지
사파리
사파리 에러메시지
파이어폭스
파이어폭스 에러메시지

모두 시각적으로 다른 형태를 가지고 있으며, 심지어 포맷의 형태 제공하지 않는 브라우저도 있다. 이는 유저의 다음 액션을 제공하지 못해 이탈을 초래할 수 있으며, 일관되지 않은 경험으로 좋지 못한 사용자 경험을 줄 수 있다.

이러한 점을 개선하기 위해서 유저에게 일관되고, 명확한 다음 동작 메시지를 제공하는 것이 바람직하다. 이를 위해 JavaScript validation API를 이용하여 동적인 커스텀 유효성 양식 검사를 작성해보자. 그 전에 우선, 브라우저에서 기본으로 동작하던 양식 유효성 검사를 해제해야한다. form 요소에 novalidate속성을 추가하자.

<form novalidate>
	/* 양식 요소 */
</form>

JavaScript validation API는 아래의 DOM 요소에서 사용 가능하다.

validation API 사용 가능한 DOM Element

  • HTMLButtonElement
  • HTMLFieldSetElement
  • HTMLInputElement
  • HTMLOutputElement
  • HTMLSelectElement
  • HTMLTextAreaElement

properties

validationMessage
유효성 검사에 통과하지 못했을 때 나타나는 메시지를 참조할 수 있는 속성이다. novalidate 속성이 없는 form 제출에서 나타나는 브라우저 기본 오류 메시지에 노출되는 문구와 같다.

브라우저 기본 오류 메시지

validationMessage

validity
ValidityState라는 객체를 반환하는 속성이다. 이 객체를 통해 기본 양식 유효성 검사와 연계하여 어떤 타입의 유효성 검사가 충족되지 못했는지 알 수 있다. 또, 각 에러 상황에서 노출되는 에러 메시지를 설정할 때 유용하다.
validity

validityState 유형에 대한 더 자세한 내용은 MDN - validation_api 참조

willValidate
모든 양식 유효성 검사를 충족하여 form이 제출 가능한 경우에 true를 반환한다.

method

checkValidity()
모든 양식 유효성 검사를 충족하는지 체크하여 boolean 값을 반환한다.

reportValidity()
checkValidity()와 거의 동일한 동작을 한다. 요소가 유효한지 여부만 확인할 때는 checkValidity()를, 유효성 검사 결과를 사용자에게 알려주려면 reportValidity()를 사용하는 것을 추천한다.

setCustomValidity(message)
새로운 validationMessage를 설정할 수 있다.

form styling

위에서 알아본 validation API에서 유효성 양식 검사에 통과하지 못하는 경우, 이에 대한 정보는 CSS에서도 가상 클래스로 참조할 수 있게 된다. 가장 대표적인 가상 클래스를 알아보고, 프로젝트에 적용해보자.
:invalid
유효성 검사에 통과하지 못한 경우, 적용할 수 있는 가상 클래스이다. 이를 통해 일반적인 상황과 스타일을 달리하여, 유저에게 시각적으로 더 명확하게 어떠한 조치를 취해야하는 것을 전달할 수 있다.

:valid
:invalid와 반대로 유효성 검사를 통과한 경우 적용할 수 있는 가상 클래스이다. :invalid상황과 대조하여 다른 스타일을 적용시키고자 할 때 사용할 수 있다.

:placeholder-shown
input에서 placeholder속성을 정의한 경우, placeholder가 노출되었을때 즉, 아무런 타이핑이 일어나지 않았을 때 적용될 수 있는 가상클래스이다. 위에서 본 :invalid와 같이 사용하여 '타이핑이 일어나면서 + 유효성 검사를 충족하지 못한 경우'등 세부적인 경우에 스타일을 먹일 수 있어 나름 유용하게 쓸 수 있다.

에러 스타일 적용


이번 글에서는 크게 기본제공 양식 유효성 검사(HTML5 기능)와 JavaScript를 사용한 양식 유효성 검사(validation API)를 살펴보고, 간단한 회원가입 양식을 구현해보았다.

그 동안 둘 중 하나만 사용하는 방식으로 구현했는데 둘을 조합하여 사용하는 양식 유효성 검사의 유용성을 느꼈고, 특히 validation API는 React에서도 상황에 맞게 제어컴포넌트(controlled component)와 비제어컴포넌트(uncontrolled component)를 구성하여 기능을 구현할 때 유용하게 쓸 수 있는 지식이라고 생각한다.

2015년 부터의 웹 발전의 역사를 보면서 빠르게 변하는 웹 생태계에서는 영원한 라이브러리, 프래임워크는 없다는 것을 느꼈다. 그에 따라 새로운 기술을 빠르게 익히는 능력이 중요하고, 이를 가능하게 하는 것은 그 기술을 이루는 기본이 무엇인지 아는 것이 아닌가 생각하게 되었다.

다시 한번, 클라이언트 양식 유효성 검사에서 중요한 것은 초기 검사를 통한 통신 절약과 사용자 경험 향상이었다. 유저에게 기능을 제공하기 위해 필요한 정보를 얻는 것은 계속해서 일어나는 일이다. 그렇기 때문에, 앞으로도 클라이언트 양식 유효성 검사의 핵심을 염두해두고 form 구현을 해보려고 한다.

profile
모두가행복한세상을만들고싶은사람

0개의 댓글