팀 프로젝트를 하기 앞서 회원가입 폼을 만들어두면 유용하게 쓰일 것 같아서 어느 정도 틀을 잡아 보았다.
class, id, 태그등은 네이버의 회원가입 틀을 보고 참고하였다.
[register.jsp]
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
//주소검색시 사용되는 script
// opener관련 오류가 발생하는 경우 아래 주석을 해지하고, 사용자의 도메인정보를 입력합니다. ("팝업API 호출 소스"도 동일하게 적용시켜야 합니다.)
//document.domain = "http://localhost:8010/register/regitser.jsp";
function goPopup() {
// 호출된 페이지(jusoPopup.jsp)에서 실제 주소검색URL(https://www.juso.go.kr/addrlink/addrLinkUrl.do)를 호출하게 됩니다.
var pop = window.open("jusoPopup.jsp", "pop",
"width=570,height=420, scrollbars=yes, resizable=yes");
// 모바일 웹인 경우, 호출된 페이지(jusoPopup.jsp)에서 실제 주소검색URL(https://www.juso.go.kr/addrlink/addrMobileLinkUrl.do)를 호출하게 됩니다.
//var pop = window.open("/popup/jusoPopup.jsp","pop","scrollbars=yes, resizable=yes");
}
/** API 서비스 제공항목 확대 (2017.02) **/
function jusoCallBack(roadFullAddr, roadAddrPart1, addrDetail,
roadAddrPart2, engAddr, jibunAddr, zipNo, admCd, rnMgtSn, bdMgtSn,
detBdNmList, bdNm, bdKdcd, siNm, sggNm, emdNm, liNm, rn, udrtYn,
buldMnnm, buldSlno, mtYn, lnbrMnnm, lnbrSlno, emdNo) {
// 팝업페이지에서 주소입력한 정보를 받아서, 현 페이지에 정보를 등록합니다.
document.join.roadAddrPart1.value = roadAddrPart1;
document.join.roadAddrPart2.value = roadAddrPart2;
document.join.addrDetail.value = addrDetail;
document.join.zipNo.value = zipNo;
}
</script>
<title>회원가입 폼</title>
<style type="text/css">
#header .h_logo {
width: 300px;
height: 32px;
}
</style>
</head>
<link href="register.css" rel="stylesheet" />
<body>
<div id="wrap">
<div id="header">
<!-- 회원가입 헤더 -->
<a href="#"><h1 class="h_logo"></h1></a>
</div>
<!-- 회원 폼 -->
<form id="join_form" method="post" name="join">
<div id="container">
<!-- 아이디, 비밀번호 -->
<div class="row_group">
<!-- 아이디 -->
<div class="join_row">
<h3 class="join_title">
<label>아이디</label>
</h3>
<span class="box int_id"> <input type="text" id="id"
class="int check" title="ID" maxlength="20">
</span>
<div id="idError" class="error_next_box"></div>
</div>
<!-- 비밀번호 -->
<div class="join_row">
<h3 class="join_title">
<label>비밀번호</label>
</h3>
<span class="box int_id"> <input type="password" id="pw1"
class="int check" title="비밀번호 입력" maxlength="20">
</span>
<div id="pw1Error" class="error_next_box"></div>
<h3 class="join_title">
<label>비밀번호 재확인</label>
</h3>
<span class="box int_id"> <input type="password" id="pw2"
class="int check" title="비밀번호 재확인 입력" maxlength="20">
</span>
<div id="pw2Error" class="error_next_box"></div>
</div>
</div>
<!-- 이름, 생년월일, 성별, 본인확인 이메일 -->
<div class="row_group">
<!-- 이름 -->
<div class="join_row">
<h3 class="join_title">
<label>이름</label>
</h3>
<span class="box int_id"> <input type="text" id="name"
class="int check" title="이름" maxlength="40">
</span>
<div id="nameError" class="error_next_box"></div>
</div>
<!-- 성별 -->
<div class="join_row join_sex">
<h3 class="join_title">
<label>성별</label>
</h3>
<div class="ps_box gender_code">
<select id="gender" name="gender" class="sel check">
<option value="" selected>성별</option>
<option value="M">남자</option>
<option value="F">여자</option>
<option value="U">선택 안함</option>
</select>
</div>
<div id="mfError" class="error_next_box"></div>
</div>
<!-- 이메일 -->
<div class="join_row join_email">
<h3 class="join_title">이메일</h3>
<span class="box" id="emailBox"> <input type="text"
id="email" maxlength="20" class="check"> <span> @
</span> <!-- 이메일 택일 --> <select id="mail_Select">
<option>이메일 선택</option>
<option>naver.com</option>
<option>gmail.com</option>
<option>daum.net</option>
<option>hanmail.net</option>
<option>nate.com</option>
<option>yahoo.co.kr</option>
</select>
</span>
<div id="emailError" class="error_next_box"></div>
</div>
<!-- 전화번호 입력 -->
<div class="join_row">
<h3 class="join_title">전화번호(-제외)</h3>
<span class="box int_id"><input type="text" id="phoneNum"
class="int check" maxlength="11"></span>
<div id="phoneNumError" class="error_next_box"></div>
</div>
</div>
<!-- 도로명주소 -->
<div class="row_group">
<!--우편번호 openapi사용-->
<div class="join_row">
<h3 class="join_title">주소</h3>
<table>
<colgroup>
<col style="width: 20%">
<col>
</colgroup>
<tbody>
<tr>
<th>우편번호</th>
<td><input type="hidden" id="confmKey" name="confmKey"
value=""> <input type="text" id="zipNo" name="zipNo" class="check"
readonly style="width: 100px"> <input type="button"
value="주소검색" onclick="goPopup();"></td>
</tr>
<tr>
<th>도로명주소</th>
<td><input type="text" id="roadAddrPart1"
style="width: 85%" readonly></td>
</tr>
<tr>
<th>상세주소</th>
<td><input type="text" id="addrDetail" style="width: 40%"
value=""> <input type="text" id="roadAddrPart2"
style="width: 40%" value="" readonly></td>
</tr>
</tbody>
</table>
<div id="addNumError" class="error_next_box"></div>
</div>
<div class="btn_area">
<input type="submit" value="가입하기" id="btnJoin"
class="btn_type btn_primary check">
</div>
</div>
</div>
</form>
</div>
<script src="register.js"></script>
</body>
</html>
1. 모든 input태그에 클래스명으로 check를 부여하여 모든 항목을 선택할 수 있도록 한다.
2. 각각의 항목 밑에 id="~Error"를 부여해 유효성 검사를 즉각 반영하여 멘트가 나올 수 있게 하는 공간을 부여하였다.
[register.css]
더보기
body, button, dd, dl, dt, fieldset, form, h1, h2, h3, h3, h5, h6, input,
legend, li, ol, p, select, table, td, textarea, th, ul {
margin: 0;
padding: 0;
}
#wrap {
width: 100%;
min-width: 760px;
}
#container {
margin: 0 auto;
max-width: 460px;
width: auto;
}
#header .h_logo {
display: block;
margin: 0 auto;
width: 240px;
height: 100px;
/*background-image: url(https://static.nid.naver.com/images/ui/join/m_naver_logo_20191126.png);*/
background-image: url('null.png');
background-repeat: no-repeat;
background-position: 0 0;
background-size: 240px auto; /*이미지 사이즈*/
}
.row_group {
overflow: hidden;
width: 100%;
}
.box {
margin: 0px auto;
display: block;
position: relative;
width: 100%;
height: 51px;
border: solid 1px #dadada;
padding: 10px 110px 10px 14px;
padding-top: 10px;
padding-right: 14px;
padding-bottom: 10px;
box-sizing: border-box;
}
#email{
outline: 0;
border: none;
font-size: 16px;
}
#mail_Select{
width: 40%;
font-size: 16px;
border: 1px solid lightgray;
}
.join_title {
display: inline-black;
margin: 19px 0 8px;
width: 60%;
font-size: 18px;
font-weight: 700;
}
.list h3 {
display: inline-black;
}
.gender_code {
display: block;
width: 100%;
padding-right: 7px;
box-sizing: border-box;
}
.ps_box {
display: block;
position: relative;
width: 100%;
height: 51px;
border: solid 1px #dadada;
padding: 10px 110px 10px 14px;
background: #fff;
box-sizing: border-box;
padding-right: 14px;
box-sizing: border-box;
}
.error_next_box {
display: block;
margin: 5px 0 -2px;
font-size: 12px;
line-height: 14px;
color: red;
}
.int {
display: block;
position: relative;
width: 100%;
height: 29px;
padding-right: 25px;
line-height: 29px;
border: none;
background: #fff;
font-size: 18px;
box-sizing: border-box;
z-index: 10;
}
.sel {
width: 100%;
height: 29px;
padding: 7px 8px 6px 7px\9;
font-size: 18px;
line-height: 18px;
color: #000;
border: none;
border-radius: 0;
height: auto;
-webkit-appearance: none;
}
.d_form {
font-size: 15px;
padding: .5em;
border: 1px solid #ccc;
border-color: #dbdbdb #d2d2d2 #d0d0d0 #d2d2d3;
vertical-align: middle;
line-height: 1.25em;
outline: 0;
width: 100%;
height : 50px;
border:none;
padding: 10px 110px 10px 14px;
padding-top: 10px;
padding-right: 110px;
padding-bottom: 10px;
padding-left: 14px;
box-sizing: border-box;
}
.d_form.mini{
width: 20%;
border: solid 1px #dadada;
}
.btn{
cursor: pointer;
}
.btn_area {
margin: 30px 0 9px;
}
.btn_type {
display: block;
width: 100%;
padding: 15px 0 15px;
font-size: 16px;
font-weight: 700;
text-align: center;
cursor: pointer;
box-sizing: border-box;
}
[register.js]
js는 크게 사용자가 입력하는 그대로 유효성 검사를 진행하는 keyup이벤트와,
회원가입 버튼을 누른다면 진행하는 유효성검사로 나뉜다.
-keyup 이벤트 유효성-
더보기
//==============로그인 유효성검사==============
var regId = /^[a-zA-Z0-9-_]{5,15}$/;//id- 5~20자 (a~z, A~Z, 0~9, -, _만 입력가능)
var regPw = /(?=.*\d{1,50})(?=.*[~`!@#$%\^&*()-+=]{1,50})(?=.*[a-zA-Z]{1,50}).{8,50}$/;//숫자, 특수문자, 영문 1개이상 사용하여 8자리 이상
var regName = /^[가-힣]{2,15}$/;
var regEmail = /^[0-9a-zA-Z-_.]{5,15}$/; // 이메일 0~9, a~z, A~Z, -, _, .내에서만 입력가능
var regPhone = /^01([0|1|6|7|8|9])-?([0-9]{3,4})-?([0-9]{4})$/;//전화번호 ->첫숫자는 01+(0,1,6,7,8,9)/-는 무시한다/숫자만 입력가능
var data = document.querySelector("#id");
var input = document.querySelectorAll('.check');
console.log(input);
function idCh() {//id유효성
var err = document.querySelector('#idError');
if (regId.test(input[0].value)) {
console.log('id 잘나옴')
err.innerText = "";
} else {
console.log('id오류')
var data = document.querySelector('#idError');
err.innerText = "5~15자 (a~z, A~Z, 0~9, -, _만 입력가능) ";
}
};
function pw1Ch() {//패스워드 유효성
var err = document.querySelector('#pw1Error');
if (regPw.test(input[1].value)) {
console.log('pw1 잘나옴');
err.innerText = "";
} else {
console.log('pw1오류');
err.innerText = "8자이상 (숫자, 특수문자, 영문 1개이상)";
}
};
function pw2Ch() {//패스워드 확인 유효성
var err = document.querySelector('#pw2Error');
if (input[1].value == input[2].value) {
console.log('pw2 잘나옴');
err.innerText = "";
} else {
console.log('pw2오류');
err.innerText = "비밀번호가 일치하지 않습니다.";
}
};
function nameCh() {//이름유효성
var err = document.querySelector('#nameError');
if (regName.test(input[3].value)) {
console.log('name 잘나옴')
err.innerText = "";
} else {
console.log('name오류')
err.innerText = "한글 2단어 이상 입력해 주세요.";
}
};
function emailCh() {//이메일 유효성
var err = document.querySelector('#emailError');
if (regEmail.test(input[5].value)) {
console.log('email 잘나옴')
err.innerText = "";
} else {
console.log('email오류')
err.innerText = "5~15글자 숫자, 영문자, -, _, .내에서만 입력가능";
input[5].focus();
}
};
function phoneCh() {//핸드폰 유효성
var err = document.querySelector('#phoneNumError');
if (regPhone.test(input[6].value)) {
console.log('phone 잘나옴')
err.innerText = "";
} else {
console.log('phone오류')
err.innerText = "전화번호 형식에 맞지 않습니다.";
input[6].focus();
}
};
input[0].addEventListener('keyup', idCh);
input[1].addEventListener('keyup', pw1Ch);
input[2].addEventListener('keyup', pw2Ch);
input[3].addEventListener('keyup', nameCh);
input[5].addEventListener('keyup', emailCh);
input[6].addEventListener('keyup', phoneCh);
1. 각 항목의 check클래스를 선택자로 저장하여 하나씩 불러 유효성 검사 함수를 만들어둔다.
2. 사용자가 입력할 때마다(keyup) 정규식과 비교하여 에러메시지(err.innerText)를 출력해주고
유효성에 맞으면 ""처리한다.
-회원가입 버튼 유효성-
더보기
window.onload = function() {
document.join.onsubmit=function(){// 회원가입을 누른다면
var errorStr = [ " 아이디를", " 비밀번호를", " 비밀번호 확인을", " 성함을","성별", "이메일을","전화번호", "주소를" ];
var error=document.querySelectorAll('.error_next_box');
console.log(input);
for (var i = 0; i < input.length-1; i++) { // -1 == submit제외
if (!input[i].value) {
error[i].innerHTML = errorStr[i]+ " 입력해 주세요.";
input[i].focus(); // 포커스 이동
return false; // 종료 (포커스 이동유지를 위해 false 종료)
}
error[i].innerHTML = "";
}
if (!regId.test(input[0].value)){//
var err = document.querySelector('#idError');
err.innerText = "5~15자 (a~z, A~Z, 0~9, -, _만 입력가능) ";
input[0].focus();
return false;
}
if (!regPw.test(input[1].value)) {
var err = document.querySelector('#pw1Error');
err.innerText = "8자이상 (숫자, 특수문자, 영문 1개이상)";
input[1].focus();
return false;
}
if (input[1].value !== input[2].value) {
var err = document.querySelector('#pw2Error');
err.innerText = "비밀번호가 일치하지 않습니다.";
input[2].focus();
return false;
}
if (!regName.test(input[3].value)) {
var err = document.querySelector('#nameError');
err.innerText = "한글 2단어 이상 입력해 주세요.";
input[3].focus();
return false;
}
if (!regEmail.test(input[5].value)) {
var err = document.querySelector('#emailError');
err.innerText = "5글자이상 숫자, 영문자, -, _, .내에서만 입력가능";
input[5].focus();
return false;
}
if (!regPhone.test(input[6].value)) {
var err = document.querySelector('#phoneNumError');
err.innerText = "전화번호 형식에 맞지 않습니다.";
input[6].focus();
return false;
}
alert("회원가입이 완료되었습니다. this+조의 멤버가 되신 것을 환영합니다!! :D");
}
}
1. required 대신 직접 텍스트를 입력하기 위해 텍스트를 배열에 넣고, 모든 input에 대해 비어있다면 텍스트 출력
2.. 정규식에 대한 유효성이 맞지 않는다면 해당 input에 focus가 가도록 하고, 해당 유효성 텍스트 출력
*소감: 회원가입 요소가 추가되는 등에 대한 유지보수가 많이 어려운 코드 같다. 시간이 날 때 변수명을 통일하고, 동의 항목 등을 추가하여 디벨롭해봐야겠다.
'HTML CSS JS' 카테고리의 다른 글
JavaScript) 이모지 필터링 정규식 (0) | 2023.04.11 |
---|---|
jQuery) .find() - 어떤 요소의 하위 요소 중 특정 요소를 찾는 메서드 (0) | 2022.08.11 |
day40) [JavaScript] Json사용하기 (0) | 2022.02.24 |
day35) [JavaScript] 회원가입 폼 유효성 검사 예제 (0) | 2022.02.17 |
day34) [JavaScript] addEventListener (0) | 2022.02.17 |
댓글