-
Notifications
You must be signed in to change notification settings - Fork 39
[김성주] sprint4 #135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "Basic-\uAE40\uC131\uC8FC-sprint4"
[김성주] sprint4 #135
Changes from 8 commits
3b36753
6119b39
9e4ec68
d726319
35639a1
a904cd1
0b5b0f1
6f75aca
43d53ec
0934ad9
016847e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { createValidRule, ruleObj, emailInput, passwordInput } from '../modules/validation-rule.mjs'; | ||
| import { initValidation } from '../modules/validate.mjs'; | ||
| import { initPasswordVisibility, visibilityPw } from '../modules/toggle-visibility-pw.mjs'; | ||
|
|
||
| const validRule = createValidRule({ emailInput, passwordInput }, ruleObj); | ||
| initValidation(validRule); | ||
| initPasswordVisibility(visibilityPw); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // #toggle-visibility-pw 관련 변수 | ||
| export const visibilityPw = document.querySelector("#toggle-visibility-pw"); | ||
| const visibilityPwLabel = document.querySelector("label[for='toggle-visibility-pw']"); | ||
| const passwordInput = document.querySelector("#user-password"); | ||
|
|
||
| // #toggle-visibility-pwcheck 관련 변수 | ||
| export const visibilityPwCheck = document.querySelector("#toggle-visibility-pwcheck"); | ||
| const visibilityPwCheckLabel = document.querySelector("label[for='toggle-visibility-pwcheck']"); | ||
| const pwCheckInput = document.querySelector("#user-password-check"); | ||
|
|
||
| function toggleVisibilityPw() { | ||
|
||
| const isShowing = visibilityPw.checked; | ||
| if (isShowing) { | ||
| passwordInput.type = "text"; | ||
| visibilityPwLabel.setAttribute('aria-checked', 'true'); | ||
| } else { | ||
| passwordInput.type = "password"; | ||
| visibilityPwLabel.setAttribute('aria-checked', 'false'); | ||
| } | ||
| } | ||
|
|
||
| function toggleVisibilityPwCheck() { | ||
| const isShowing = visibilityPwCheck.checked; | ||
| if (isShowing) { | ||
| pwCheckInput.type = "text"; | ||
| visibilityPwCheckLabel.setAttribute('aria-checked', 'true'); | ||
| } else { | ||
| pwCheckInput.type = "password"; | ||
| visibilityPwCheckLabel.setAttribute('aria-checked', 'false'); | ||
| } | ||
| } | ||
|
|
||
| export function initPasswordVisibility(visibilityPw, visibilityPwCheck){ | ||
|
||
| visibilityPw.addEventListener("click", toggleVisibilityPw); | ||
| if (visibilityPwCheck) visibilityPwCheck.addEventListener("click", toggleVisibilityPwCheck); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 파일에서도 토글 로직과 UI를 분리해 코드를 더 간결하게 만들었던것처럼 개선할만한 여지가 있는지 한번 더 고민해볼까요? :) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| const userForm = document.querySelector("form"); | ||
| const submitBtn = document.querySelector("button"); | ||
|
|
||
| // 검사 통과 못한 거 있나요? | ||
| function hasInvalidInput(validRule) { | ||
| return Object.values(validRule).some(validator => validator.passed === false); | ||
| } | ||
|
|
||
| //폼 전송 막기 | ||
| function preventInvalidSubmit(e, validRule) { | ||
| //서브밋 누르면 통과 못한 인풋에 경고 보여줘 | ||
| Object.values(validRule).forEach((validator) => { | ||
| updateValidation({ currentTarget: validator.input }, validRule); | ||
| }); | ||
|
|
||
| if (hasInvalidInput(validRule)) { | ||
| e.preventDefault(); | ||
| } | ||
| } | ||
|
|
||
| //검사 실패 시 스타일 추가 | ||
| function updateValidation(e, validRule) { | ||
| const { name } = e.currentTarget; | ||
| const validator = validRule[name]; | ||
|
|
||
| removeMessage(name) | ||
|
|
||
| if (!validator.condition()) { | ||
| appendErr(validator); | ||
| validator.passed = false; | ||
| } else { | ||
| clearErr(validator); | ||
| validator.passed = true; | ||
| } | ||
|
|
||
| updateButton(validRule); | ||
| } | ||
|
|
||
| //존재하는 실패 메세지 삭제 | ||
| function removeMessage(name) { | ||
| const msg = document.querySelector(`#${name}+.error-message`); | ||
| if (msg) msg.remove(); | ||
| } | ||
|
|
||
| // 검사 실패 메세지 추가 | ||
| function appendErr(validator) { | ||
| validator.input.classList.add("error-Line"); | ||
| const err = document.createElement("span"); | ||
| err.classList.add("error-message"); | ||
| err.textContent = validator.createMsg(); | ||
| validator.input.insertAdjacentElement("afterend", err); | ||
| } | ||
|
|
||
| // 검사 실패 스타일 삭제 | ||
| function clearErr(validator) { | ||
| validator.input.classList.remove("error-Line"); | ||
| } | ||
|
|
||
| // 버튼 스타일 추가 | ||
| function updateButton(validRule) { | ||
| submitBtn.classList.toggle("pass-button", !hasInvalidInput(validRule)); | ||
| } | ||
|
|
||
| //리스너 추가 | ||
| export function initValidation(validRule) { | ||
| for (let validator in validRule) { | ||
| validRule[validator].input.addEventListener("focusout", e => updateValidation(e, validRule)); | ||
| } | ||
|
|
||
| userForm.addEventListener("submit", e => preventInvalidSubmit(e, validRule)); | ||
|
|
||
| if (validRule['user-password-check']) { | ||
| validRule['user-password'].input.addEventListener("focusout", () => { | ||
| // 비밀번호 변경되었을 때 비밀번호 확인도 같이 | ||
| updateValidation({ currentTarget: validRule['user-password-check'].input }, validRule); | ||
| }); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| export const emailInput = document.querySelector("#user-email"); | ||
| export const passwordInput = document.querySelector("#user-password"); | ||
| export const nameInput = document.querySelector("#user-name"); | ||
| export const passwordCheckInput = document.querySelector("#user-password-check"); | ||
|
|
||
| // 전체 검사 조건 | ||
| export const ruleObj = { | ||
| 'user-email': { | ||
| input: emailInput, | ||
| isValid() { | ||
| return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.input.value); | ||
| }, | ||
| getErrorMessage() { | ||
| return this.input.value ? "잘못된 이메일입니다." : "이메일을 입력해주세요" | ||
| }, | ||
| }, | ||
| 'user-password': { | ||
| input: passwordInput, | ||
| isValid() { | ||
| return this.input.value.length >= 8; | ||
| }, | ||
| getErrorMessage() { | ||
| return (this.input.value.length == 0) ? "비밀번호를 입력해주세요." : "비밀번호를 8자 이상 입력해주세요." | ||
| }, | ||
| }, | ||
| 'user-name': { | ||
| input: nameInput, | ||
| isValid() { | ||
| return this.input.value; | ||
| }, | ||
| getErrorMessage() { | ||
| return "닉네임을 입력해주세요"; | ||
| }, | ||
| }, | ||
| 'user-password-check': { | ||
| input: passwordCheckInput, | ||
| isValid() { | ||
| return (passwordInput.value === this.input.value) && passwordCheckInput.value.length != 0; | ||
| }, | ||
| getErrorMessage() { | ||
| return "비밀번호가 일치하지 않습니다." | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| // 해당 페이지에 있는 인풋만 규칙 만들기 | ||
| export function createValidRule(inputElement, ruleObj) { | ||
| const validRule = {} | ||
|
|
||
| Object.values(inputElement).forEach((input) => { | ||
| validRule[input.name] = { | ||
| input, | ||
| condition: ruleObj[input.name].isValid, | ||
| createMsg: ruleObj[input.name].getErrorMessage, | ||
| passed: false, | ||
| } | ||
| }); | ||
|
|
||
| return validRule; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { createValidRule, ruleObj, emailInput, passwordInput, nameInput, passwordCheckInput } from '../modules/validation-rule.mjs'; | ||
| import { initValidation } from '../modules/validate.mjs'; | ||
| import { initPasswordVisibility, visibilityPw, visibilityPwCheck } from '../modules/toggle-visibility-pw.mjs'; | ||
|
|
||
| const validRule = createValidRule({ emailInput, passwordInput, nameInput, passwordCheckInput }, ruleObj); | ||
| initValidation(validRule); | ||
| initPasswordVisibility(visibilityPw, visibilityPwCheck); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
함수를 적절한 단위의 작업으로 나누고 모듈화하신 시도 너무 좋습니다! 👍
여기서 더 개선해보자면,
login 파일에 사용된 네이밍과 구조를 아래 예시와 같이 좀 더 페이지&이벤트 기반으로 바꿔보는건 어떨까요?