Skip to content

Commit

Permalink
[#21] Feat: 유효성 검증 진행중
Browse files Browse the repository at this point in the history
- 웹팩 설정 변경
- 구조 정리
- 번들 파일을 3개로(로그인, 회원가입, 메인) 분리. 웹팩 이해 부족으로 제대로 작동하지 않았음
- 유효성 검증 코드 작성 중
  • Loading branch information
sungik-choi committed Mar 25, 2020
1 parent 2978b97 commit fdb8bac
Show file tree
Hide file tree
Showing 16 changed files with 173 additions and 21 deletions.
2 changes: 1 addition & 1 deletion FE/src/home.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import "../scss/home.scss";
import "./scss/home.scss";
45 changes: 45 additions & 0 deletions FE/src/modules/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export const PATTERN = {
userId: "^[a-z0-9-_]{5,20}$",
password: "^(?=.*[A-Za-z])(?=.*d)(?=.*[!@#$%^&*_+~])[A-Za-zd!@#$%^&*_+~]{8,16}$",
email: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$",
phoneNumber: "^(010)(d{7,8})$",
year: "^(0-9)$",
};

export const LIMITED_LENGTH = {
userId: 20,
password: 16,
year: 4,
};

export const FORM_ID = {
userId: "#userId",
password: "#password",
checkPassword: "#check-password",
email: "#email",
phoneNumber: "#phoneNumber",
name: "#name",
year: "#year",
month: "#month",
day: "#day",
gender: "#gender",
interest: "#interest",
};

export const ERROR_MSG_ID = {
userId: "#error-msg-id",
password: "#error-msg-password",
checkPassword: "#error-msg-check-password",
email: "#error-msg-email",
phoneNumber: "#error-msg-phoneNumber",
birthday: "#error-msg-birthday",
interest: "#error-msg-interest",
};

export const TOGGLE_CLASS = {
pass: "pass",
error: "error",
focus: "forus",
hidden: "hidden",
disabled: "disabled",
};
9 changes: 9 additions & 0 deletions FE/src/modules/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const _q = str => {
return document.querySelector(str);
};

export const _qa = str => {
return document.querySelectorAll(str);
};

export const pipe = (...fns) => value => fns.reduce((acc, fn) => fn(acc), value);
100 changes: 100 additions & 0 deletions FE/src/modules/validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { _q, _qa, pipe } from "./util.js";
import { PATTERN, FORM_ID, ERROR_MSG_ID, TOGGLE_CLASS } from "./constants.js";

const isInputTag = elem => {
return !!(elem.tagName === "INPUT" || elem.tagName === "SELECT");
};

const setInputPattern = (target, regExp) => {
if (!isInputTag(target)) return;
target.pattern = regExp;
};

const fields = {
userId: {
isFieldValid() {
const userId = _q(FORM_ID.userId);
const { value } = userId;
const isValid = userId.validity.valid;
return value !== "" && isValid;
},
errorMessage: {
misMatch: "5~20자의 영문 소문자, 숫자와 특수기호(_)(-) 만 사용 가능합니다.",
overlap: "이미 사용중인 아이디입니다.",
},
errorMessageElement: _q(ERROR_MSG_ID.userId),
passMessage: "사용 가능한 아이디입니다.",
},

password: {
isFieldValid() {
const password = _q(FORM_ID.password);
const { value } = password;
return value !== "";
},
errorMessage: {
range: "8자 이상 16자 이하로 입력해주세요.",
upperCase: "영문 대문자를 최소 1자 이상 포함해주세요.",
number: "숫자를 최소 1자 이상 포함해주세요.",
sign: "특수문자를 최소 1자 이상 포함해주세요.",
},
errorMessageElement: _q(ERROR_MSG_ID.password),
passMessage: "안전한 비밀번호입니다.",
},

checkPassword: {
isFieldValid() {
const password = _q(FORM_ID.password).value;
return password !== "";
},
errorMessageElement: _q(ERROR_MSG_ID.checkPassword),
errorMessage: "비밀번호가 일치하지 않습니다.",
passMessage: "비밀번호가 일치합니다.",
},
};

const init = () => {
const userIdInput = _q(FORM_ID.userId);
const passwordInput = _q(FORM_ID.password);
const checkPasswordInput = _q(FORM_ID.checkPassword);
const emailInput = _q(FORM_ID.email);
const phoneNumberInput = _q(FORM_ID.phoneNumber);

setInputPattern(userIdInput, PATTERN.userId);
setInputPattern(passwordInput, PATTERN.password);
setInputPattern(checkPasswordInput, PATTERN.password);
setInputPattern(emailInput, PATTERN.email);
setInputPattern(phoneNumberInput, PATTERN.phoneNumber);
};

init();

_q("form").addEventListener("input", e => {
const tagName = e.target.name;
let message = "";
console.log(fields.userId.isFieldValid());
switch (tagName) {
case "userId":
if (e.target.value === "") {
return;
}
if (!e.target.validity.valid) {
message = "5~20자의 영문 소문자, 숫자와 특수기호(_)(-) 만 사용 가능합니다.";
_q(ERROR_MSG_ID.userId).innerHTML = message;
_q(ERROR_MSG_ID.userId).classList.add(TOGGLE_CLASS.error);
_q(ERROR_MSG_ID.userId).classList.remove(TOGGLE_CLASS.pass);
} else {
message = "사용 가능한 아이디입니다.";
_q(ERROR_MSG_ID.userId).innerHTML = message;
_q(ERROR_MSG_ID.userId).classList.remove(TOGGLE_CLASS.error);
_q(ERROR_MSG_ID.userId).classList.add(TOGGLE_CLASS.pass);
}
break;
default:
break;
}
});

_q(".btn-wrap").addEventListener("click", e => {
e.preventDefault();
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 0 additions & 2 deletions FE/scss/modal.scss → FE/src/scss/modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
top: 0;
left: 0;
z-index: 1;
opacity: 1;
transition: opacity 0.2s ease;
}

.modal {
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 1 addition & 2 deletions FE/scss/toggle-class.scss → FE/src/scss/toggle-class.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
}

.hidden {
visibility: hidden;
opacity: 0;
display: none;
}

.disabled {
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion FE/src/signin.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import "../scss/signin.scss";
import "./scss/signin.scss";
26 changes: 13 additions & 13 deletions FE/src/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@ <h1>회원가입</h1>
<form action="" method="post">
<div class="form-id">
<label for="userId">아이디</label>
<input type="text" name="userId" id="userId" minlength="5" maxlength="20" size="20" aria-errormessage="error-msg-id" aria-required />
<span class="error-msg error" id="error-msg-id" role="alert" aria-role="alert" aria-live="assertive">제대로된 이메일을 입력</span>
<input type="text" name="userId" id="userId" minlength="5" maxlength="20" size="20" aria-errormessage="error-msg-id" required />
<span class="error-msg" id="error-msg-id" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-password">
<label for="password">비밀번호</label>
<input type="password" name="password" id="password" minlength="8" maxlength="16" size="16" aria-errormessage="error-msg-password" aria-required />
<input type="password" name="password" id="password" minlength="8" maxlength="16" size="16" aria-errormessage="error-msg-password" />
<span class="error-msg" id="error-msg-password" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-check-password">
<label for="check-password">비밀번호 재확인</label>
<input type="password" name="check-password" id="check-password" minlength="8" maxlength="16" size="16" aria-errormessage="error-msg-check-password" aria-required />
<input type="password" name="check-password" id="check-password" minlength="8" maxlength="16" size="16" aria-errormessage="error-msg-check-password" />
<span class="error-msg" id="error-msg-check-password" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-name">
<label for="name">이름</label>
<input type="text" name="name" id="name" aria-required />
<input type="text" name="name" id="name" />
</div>
<div class="form-birthday">
<label for="year">생년월일</label>
<div class="birthday-wrap">
<input type="text" name="year" id="year" placeholder="년(4자)" aria-label="년(4자)" aria-errormessage="error-msg-birthday" aria-required />
<input type="text" name="year" id="year" placeholder="년(4자)" aria-label="년(4자)" aria-errormessage="error-msg-birthday" maxlength="4" />
<div class="month-select-wrap">
<select name="month" id="month" aria-label="" aria-errormessage="error-msg-birthday" aria-required>
<select name="month" id="month" aria-label="" aria-errormessage="error-msg-birthday">
<option value="" selected></option>
<option value="1">1</option>
<option value="2">2</option>
Expand All @@ -54,14 +54,14 @@ <h1>회원가입</h1>
</select>
<i class="material-icons md-36 expand-more">expand_more</i>
</div>
<input type="text" name="day" id="day" placeholder="" aria-label="" aria-errormessage="error-msg-birthday" aria-required />
<input type="text" name="day" id="day" placeholder="" aria-label="" aria-errormessage="error-msg-birthday" />
</div>
<span class="error-msg" id="error-msg-birthday" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-gender">
<label for="gender">성별</label>
<div class="gender-select-wrap">
<select name="gender" id="gender" aria-required>
<select name="gender" id="gender">
<option value="" selected>성별</option>
<option value="MALE">남자</option>
<option value="FEMALE">여자</option>
Expand All @@ -71,12 +71,12 @@ <h1>회원가입</h1>
</div>
<div class="form-email">
<label for="email">이메일</label>
<input type="email" name="email" id="email" aria-errormessage="error-msg-email" aria-required />
<input type="email" name="email" id="email" aria-errormessage="error-msg-email" />
<span class="error-msg" id="error-msg-email" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-phone">
<label for="phoneNumber">휴대전화</label>
<input type="tel" name="phoneNumber" id="phoneNumber" placeholder="- 없이 입력해주세요. 예) 0101231234" minlength="10" maxlength="11" aria-errormessage="error-msg-phone" aria-required />
<input type="tel" name="phoneNumber" id="phoneNumber" placeholder="- 없이 입력해주세요. 예) 0101231234" minlength="10" maxlength="11" aria-errormessage="error-msg-phone" />
<span class="error-msg" id="error-msg-phone" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-interest">
Expand Down Expand Up @@ -138,13 +138,13 @@ <h1>회원가입</h1>
<span>개발</span>
<i class="material-icons md-18 close">close</i>
</div>
<input type="text" name="interest" id="interest" aria-errormessage="error-msg-interest" aria-required />
<input type="text" name="interest" id="interest" aria-errormessage="error-msg-interest" />
</div>
<span class="error-msg" id="error-msg-interest" role="alert" aria-role="alert" aria-live="assertive"></span>
</div>
<div class="form-terms">
<label for="terms"><a href="#none">약관에 동의합니다.</a></label>
<input type="checkbox" id="terms" name="terms" readonly aria-required />
<input type="checkbox" id="terms" name="terms" readonly />
</div>
<div class="btn-wrap">
<button class="reset-btn" type="reset">초기화</button>
Expand Down
3 changes: 2 additions & 1 deletion FE/src/signup.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import "../scss/main.scss";
import "./scss/main.scss";
import "./modules/validation";
2 changes: 1 addition & 1 deletion FE/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
entry: { index: "./src/signup.js", signin: "./src/signin.js", home: "./src/home.js" },
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
filename: "dist/[name].bundle.js",
},
plugins: [
new MiniCssExtractPlugin({ filename: "css/[name].css", chunkFilename: "css/[id].css" }),
Expand Down

0 comments on commit fdb8bac

Please sign in to comment.