오늘은 아래와 같은 회원가입 항목에 대해 유효성 검사를 하는 코드를 작성했다.
<회원 가입 유효성 검사 항목>
아이디: 입력 유무
비밀번호: 입력 유무, 영문자와 숫자 각 1개 이상, 8~16자
비밀번호 확인: 비밀번호와 일치 여부
성함: 입력 유무
이메일: 입력 유무, 이메일 형식인지 체크
<form>
<div class="id-form">
<label>아이디</label>
<input type="text" name="id" id="id" placeholder="아이디"/>
<small>Error message</small>
</div>
</form>
유효성 검사에서 사용한 항목들은 form, 각 input 영역을 감싸는 부모태그, input, 그리고 small 태그이다.
const inputList = form.querySelectorAll("input");
inputList.forEach((input) => {
input.addEventListener("keyup", () => {
checkInputs(input);
});
input.addEventListener("blur", () => {
checkInputs(input);
});
...
});
form.addEventListener("submit", (e) => {
e.preventDefault();
checkAllInputs();
});
먼저 form과 각 input을 변수에 할당했다.
그리고 유효성 검사 함수를 돌리기 위해 form을 통해 받은 input 배열에 foreach 매서드를 적용했다.
유효성 검사는 아래 두개의 eventListener를 통해 2번 실행시켰다.
keyup
-> input에서 타자수가 증가했을 때
blur
-> 다른 영역을 클릭하면서 input 에서 포커스가 사라졌을 때
submit
-> form이 제출되었을 때
function checkInputs(input) {
const idValue = id.value.trim();
const passwordValue = password.value.trim();
const password2Value = password2.value.trim();
const nameValue = username.value.trim();
const emailValue = email.value.trim();
const regul1 = /^(?=.*[a-zA-Z])(?=.*\d).{8,16}$/;
const regul2 = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
if (input === id) {
if (idValue === "") {
setErrorFor(id, "아이디를 입력하세요.");
} else {
setSuccessFor(id);
}
} else if (input === password) {
if (passwordValue === "") {
setErrorFor(password, "비밀번호를 입력하세요.");
} else if (!regul1.test(passwordValue)) {
setErrorFor(password, "8~16자 영문, 숫자를 사용하세요.");
} else {
setSuccessFor(password);
}
...
}
const idValue = id.value.trim();
유효성 검사 함수에서 각 input의 value값을 변수에 할당할 때는 공백을 제거하기 위해 trim매서드를 사용해야한다.
const regul1 = /^(?=.*[a-zA-Z])(?=.*\d).{8,16}$/;
⇨ 영대소문자와 숫자 각 1개 이상 포함
함수에서 필요한 정규표현식을 작성해놓았다.
위 정규표현식은 비밀번호 체크에 사용하였다.
함수의 파라미터로 온 input에 따라 필요한 검사를 실행한다.
if (!regul1.test(passwordValue)) {
setErrorFor(password, "8~16자 영문, 숫자를 사용하세요.");
}
비밀번호나 이메일을 검사할 때는 정규표현식을 사용하여 test매서드를 사용했다.
regul1.test(passwordValue)
예를 들어 이 코드는 passwordValue가 regul1이라는 정규표현식의 조건에 일치하는지 여부를 확인하고
true or false를 반환한다.
function setErrorFor(input, message) {
const inputFormDiv = input.parentElement;
const small = inputFormDiv.querySelector("small");
small.innerText = message;
inputFormDiv.classList.remove("success");
inputFormDiv.classList.add("error");
}
setErrorFor 함수에서는 인풋의 부모요소를 가져오고, 부모 요소 안에 있는 small element를 변수에 할당했다.
즉 input의 부모요소 = div
div 안의 small은 input하단에 달리는 메세지 영역이다.
small에 errormessage를 innerText로 넣어준다.
element.classList.remove("클래스명")
-> 해당 클래스가 있다면 지우고 없다면 냅둔다.
element.classList.add("클래스명")
-> 해당 클래스가 있다면 냅두고 없다면 추가한다.
또한 부모태그의 classlist에서 success클래스가 있다면 없애고, error클래스가 있다면 지우면서,
이 클래스를 활용한 css를 조작했다.
function setSuccessFor(input) {
const inputFormDiv = input.parentElement;
inputFormDiv.classList.remove("error");
inputFormDiv.classList.add("success");
}
조건을 통과했을 때는 따로 메세지는 표시하지 않았고,
classList를 이용해 css를 조작했다.
small {
visibility: hidden;
padding: 0px 0px 2px 10px;
}
.error small {
font-size: 14px;
color: #e74c3c;
visibility: visible;
}
point
visibilty: none
우선 visibility를 hidden 으로 설정해놓고 error가 없을 때는 표시하지 않았고,
부모태그에 error클래스가 추가되었을 때 visibilty를 visible로 바꾸어 노출시켰다.
password inpud에 자물쇠 아이콘을 삽입했고 위와 같은 방식으로 적용했다.
끝!